William Tran-Viet
1c51886920
[libc++] Implement P3168R2: Give optional range support ( #149441 )
...
Resolves #105430
- Implement all required pieces of P3168R2
- Leverage existing `wrap_iter` and `bounded_iter` classes to implement
the `optional` regular and hardened iterator type, respectively
- Update documentation to match
2025-08-18 18:04:45 +03:00
Nikolas Klauser
d9bc548fac
[libc++] Optimize __tree::find and __tree::__erase_unique ( #152370 )
...
This patch changes `__tree::find` to return when it has found any equal
element instead of the lower bound of the equal elements. For `map` and
`set` there is no observable difference, since the keys are unique.
However for their `multi` versions this can mean a change in behaviour
since it's not longer guaranteed that `find` will return the first
element.
```
------------------------------------------------------------------------------------------
Benchmark old new
------------------------------------------------------------------------------------------
std::map<int, int>::erase(key) (existent)/0 24.4 ns 24.9 ns
std::map<int, int>::erase(key) (existent)/32 39.8 ns 32.1 ns
std::map<int, int>::erase(key) (existent)/1024 83.8 ns 52.5 ns
std::map<int, int>::erase(key) (existent)/8192 91.4 ns 66.4 ns
std::map<int, int>::erase(key) (non-existent)/0 0.511 ns 0.328 ns
std::map<int, int>::erase(key) (non-existent)/32 9.12 ns 5.62 ns
std::map<int, int>::erase(key) (non-existent)/1024 26.6 ns 11.3 ns
std::map<int, int>::erase(key) (non-existent)/8192 37.0 ns 16.9 ns
std::map<int, int>::find(key) (existent)/0 0.007 ns 0.007 ns
std::map<int, int>::find(key) (existent)/32 6.02 ns 4.32 ns
std::map<int, int>::find(key) (existent)/1024 13.6 ns 8.35 ns
std::map<int, int>::find(key) (existent)/8192 30.3 ns 12.8 ns
std::map<int, int>::find(key) (non-existent)/0 0.299 ns 0.545 ns
std::map<int, int>::find(key) (non-existent)/32 8.78 ns 4.60 ns
std::map<int, int>::find(key) (non-existent)/1024 26.1 ns 21.8 ns
std::map<int, int>::find(key) (non-existent)/8192 36.2 ns 27.9 ns
std::map<std::string, int>::erase(key) (existent)/0 74.1 ns 76.7 ns
std::map<std::string, int>::erase(key) (existent)/32 161 ns 114 ns
std::map<std::string, int>::erase(key) (existent)/1024 196 ns 126 ns
std::map<std::string, int>::erase(key) (existent)/8192 207 ns 160 ns
std::map<std::string, int>::erase(key) (non-existent)/0 0.754 ns 0.328 ns
std::map<std::string, int>::erase(key) (non-existent)/32 47.3 ns 40.7 ns
std::map<std::string, int>::erase(key) (non-existent)/1024 122 ns 96.1 ns
std::map<std::string, int>::erase(key) (non-existent)/8192 168 ns 123 ns
std::map<std::string, int>::find(key) (existent)/0 0.059 ns 0.058 ns
std::map<std::string, int>::find(key) (existent)/32 54.3 ns 34.6 ns
std::map<std::string, int>::find(key) (existent)/1024 125 ns 64.5 ns
std::map<std::string, int>::find(key) (existent)/8192 159 ns 79.2 ns
std::map<std::string, int>::find(key) (non-existent)/0 0.311 ns 0.299 ns
std::map<std::string, int>::find(key) (non-existent)/32 44.0 ns 42.7 ns
std::map<std::string, int>::find(key) (non-existent)/1024 120 ns 92.6 ns
std::map<std::string, int>::find(key) (non-existent)/8192 189 ns 124 ns
std::set<int>::erase(key) (existent)/0 25.1 ns 25.1 ns
std::set<int>::erase(key) (existent)/32 42.1 ns 33.1 ns
std::set<int>::erase(key) (existent)/1024 73.8 ns 55.5 ns
std::set<int>::erase(key) (existent)/8192 101 ns 68.8 ns
std::set<int>::erase(key) (non-existent)/0 0.511 ns 0.328 ns
std::set<int>::erase(key) (non-existent)/32 9.60 ns 4.67 ns
std::set<int>::erase(key) (non-existent)/1024 26.5 ns 11.2 ns
std::set<int>::erase(key) (non-existent)/8192 46.2 ns 16.8 ns
std::set<int>::find(key) (existent)/0 0.008 ns 0.007 ns
std::set<int>::find(key) (existent)/32 5.87 ns 4.51 ns
std::set<int>::find(key) (existent)/1024 14.3 ns 8.69 ns
std::set<int>::find(key) (existent)/8192 30.2 ns 12.8 ns
std::set<int>::find(key) (non-existent)/0 0.531 ns 0.530 ns
std::set<int>::find(key) (non-existent)/32 8.77 ns 4.64 ns
std::set<int>::find(key) (non-existent)/1024 26.1 ns 21.7 ns
std::set<int>::find(key) (non-existent)/8192 36.3 ns 27.8 ns
std::set<std::string>::erase(key) (existent)/0 93.2 ns 70.2 ns
std::set<std::string>::erase(key) (existent)/32 164 ns 116 ns
std::set<std::string>::erase(key) (existent)/1024 161 ns 136 ns
std::set<std::string>::erase(key) (existent)/8192 231 ns 140 ns
std::set<std::string>::erase(key) (non-existent)/0 0.532 ns 0.326 ns
std::set<std::string>::erase(key) (non-existent)/32 43.4 ns 40.1 ns
std::set<std::string>::erase(key) (non-existent)/1024 122 ns 99.5 ns
std::set<std::string>::erase(key) (non-existent)/8192 168 ns 125 ns
std::set<std::string>::find(key) (existent)/0 0.059 ns 0.059 ns
std::set<std::string>::find(key) (existent)/32 53.1 ns 35.5 ns
std::set<std::string>::find(key) (existent)/1024 124 ns 61.2 ns
std::set<std::string>::find(key) (existent)/8192 154 ns 73.9 ns
std::set<std::string>::find(key) (non-existent)/0 0.532 ns 0.301 ns
std::set<std::string>::find(key) (non-existent)/32 44.4 ns 39.5 ns
std::set<std::string>::find(key) (non-existent)/1024 120 ns 95.5 ns
std::set<std::string>::find(key) (non-existent)/8192 193 ns 119 ns
std::multimap<int, int>::erase(key) (existent)/0 26.5 ns 26.6 ns
std::multimap<int, int>::erase(key) (existent)/32 33.5 ns 32.9 ns
std::multimap<int, int>::erase(key) (existent)/1024 55.5 ns 58.0 ns
std::multimap<int, int>::erase(key) (existent)/8192 67.4 ns 70.0 ns
std::multimap<int, int>::erase(key) (non-existent)/0 0.523 ns 0.532 ns
std::multimap<int, int>::erase(key) (non-existent)/32 5.08 ns 5.09 ns
std::multimap<int, int>::erase(key) (non-existent)/1024 13.0 ns 12.9 ns
std::multimap<int, int>::erase(key) (non-existent)/8192 19.6 ns 19.8 ns
std::multimap<int, int>::find(key) (existent)/0 0.015 ns 0.037 ns
std::multimap<int, int>::find(key) (existent)/32 7.07 ns 3.85 ns
std::multimap<int, int>::find(key) (existent)/1024 22.0 ns 7.44 ns
std::multimap<int, int>::find(key) (existent)/8192 37.6 ns 12.0 ns
std::multimap<int, int>::find(key) (non-existent)/0 0.297 ns 0.305 ns
std::multimap<int, int>::find(key) (non-existent)/32 8.79 ns 4.59 ns
std::multimap<int, int>::find(key) (non-existent)/1024 26.0 ns 11.2 ns
std::multimap<int, int>::find(key) (non-existent)/8192 36.4 ns 16.8 ns
std::multimap<std::string, int>::erase(key) (existent)/0 93.4 ns 84.5 ns
std::multimap<std::string, int>::erase(key) (existent)/32 101 ns 101 ns
std::multimap<std::string, int>::erase(key) (existent)/1024 118 ns 126 ns
std::multimap<std::string, int>::erase(key) (existent)/8192 108 ns 124 ns
std::multimap<std::string, int>::erase(key) (non-existent)/0 2.39 ns 2.43 ns
std::multimap<std::string, int>::erase(key) (non-existent)/32 44.4 ns 49.7 ns
std::multimap<std::string, int>::erase(key) (non-existent)/1024 108 ns 103 ns
std::multimap<std::string, int>::erase(key) (non-existent)/8192 140 ns 125 ns
std::multimap<std::string, int>::find(key) (existent)/0 0.059 ns 0.058 ns
std::multimap<std::string, int>::find(key) (existent)/32 52.3 ns 32.6 ns
std::multimap<std::string, int>::find(key) (existent)/1024 122 ns 58.9 ns
std::multimap<std::string, int>::find(key) (existent)/8192 160 ns 72.7 ns
std::multimap<std::string, int>::find(key) (non-existent)/0 0.524 ns 0.494 ns
std::multimap<std::string, int>::find(key) (non-existent)/32 43.8 ns 38.9 ns
std::multimap<std::string, int>::find(key) (non-existent)/1024 123 ns 90.8 ns
std::multimap<std::string, int>::find(key) (non-existent)/8192 190 ns 126 ns
std::multiset<int>::erase(key) (existent)/0 27.1 ns 26.8 ns
std::multiset<int>::erase(key) (existent)/32 33.3 ns 34.1 ns
std::multiset<int>::erase(key) (existent)/1024 58.5 ns 58.8 ns
std::multiset<int>::erase(key) (existent)/8192 66.7 ns 64.1 ns
std::multiset<int>::erase(key) (non-existent)/0 0.318 ns 0.325 ns
std::multiset<int>::erase(key) (non-existent)/32 5.15 ns 5.25 ns
std::multiset<int>::erase(key) (non-existent)/1024 12.9 ns 12.7 ns
std::multiset<int>::erase(key) (non-existent)/8192 20.3 ns 20.3 ns
std::multiset<int>::find(key) (existent)/0 0.043 ns 0.015 ns
std::multiset<int>::find(key) (existent)/32 6.94 ns 4.22 ns
std::multiset<int>::find(key) (existent)/1024 21.4 ns 8.23 ns
std::multiset<int>::find(key) (existent)/8192 37.4 ns 12.6 ns
std::multiset<int>::find(key) (non-existent)/0 0.515 ns 0.300 ns
std::multiset<int>::find(key) (non-existent)/32 8.52 ns 4.62 ns
std::multiset<int>::find(key) (non-existent)/1024 25.5 ns 11.3 ns
std::multiset<int>::find(key) (non-existent)/8192 36.5 ns 27.0 ns
std::multiset<std::string>::erase(key) (existent)/0 81.9 ns 77.5 ns
std::multiset<std::string>::erase(key) (existent)/32 113 ns 129 ns
std::multiset<std::string>::erase(key) (existent)/1024 132 ns 148 ns
std::multiset<std::string>::erase(key) (existent)/8192 114 ns 165 ns
std::multiset<std::string>::erase(key) (non-existent)/0 2.33 ns 2.32 ns
std::multiset<std::string>::erase(key) (non-existent)/32 44.4 ns 42.0 ns
std::multiset<std::string>::erase(key) (non-existent)/1024 97.3 ns 95.1 ns
std::multiset<std::string>::erase(key) (non-existent)/8192 132 ns 123 ns
std::multiset<std::string>::find(key) (existent)/0 0.058 ns 0.059 ns
std::multiset<std::string>::find(key) (existent)/32 48.3 ns 34.4 ns
std::multiset<std::string>::find(key) (existent)/1024 121 ns 61.9 ns
std::multiset<std::string>::find(key) (existent)/8192 155 ns 77.7 ns
std::multiset<std::string>::find(key) (non-existent)/0 0.524 ns 0.306 ns
std::multiset<std::string>::find(key) (non-existent)/32 44.1 ns 40.4 ns
std::multiset<std::string>::find(key) (non-existent)/1024 121 ns 96.3 ns
std::multiset<std::string>::find(key) (non-existent)/8192 193 ns 121 ns
```
2025-08-15 08:59:39 +02:00
Nikolas Klauser
cbbf303ff5
[libc++] Optimize __hash_table copy constructors and assignment ( #151951 )
...
```
----------------------------------------------------------------------------------------------------------------------
Benchmark old new
----------------------------------------------------------------------------------------------------------------------
std::unordered_set<int>::ctor(const&)/0 15.4 ns 14.6 ns
std::unordered_set<int>::ctor(const&)/32 686 ns 322 ns
std::unordered_set<int>::ctor(const&)/1024 35839 ns 21490 ns
std::unordered_set<int>::ctor(const&)/8192 385790 ns 280270 ns
std::unordered_set<int>::operator=(const&) (into cleared Container)/0 15.1 ns 15.9 ns
std::unordered_set<int>::operator=(const&) (into cleared Container)/32 1077 ns 333 ns
std::unordered_set<int>::operator=(const&) (into cleared Container)/1024 31296 ns 9984 ns
std::unordered_set<int>::operator=(const&) (into cleared Container)/8192 266776 ns 109418 ns
std::unordered_set<int>::operator=(const&) (into partially populated Container)/0 15.1 ns 16.3 ns
std::unordered_set<int>::operator=(const&) (into partially populated Container)/32 962 ns 320 ns
std::unordered_set<int>::operator=(const&) (into partially populated Container)/1024 31713 ns 10128 ns
std::unordered_set<int>::operator=(const&) (into partially populated Container)/8192 266113 ns 108525 ns
std::unordered_set<int>::operator=(const&) (into populated Container)/0 0.990 ns 2.03 ns
std::unordered_set<int>::operator=(const&) (into populated Container)/32 963 ns 263 ns
std::unordered_set<int>::operator=(const&) (into populated Container)/1024 27600 ns 7793 ns
std::unordered_set<int>::operator=(const&) (into populated Container)/8192 235295 ns 66248 ns
std::unordered_set<std::string>::ctor(const&)/0 16.0 ns 15.0 ns
std::unordered_set<std::string>::ctor(const&)/32 2950 ns 1277 ns
std::unordered_set<std::string>::ctor(const&)/1024 246935 ns 73762 ns
std::unordered_set<std::string>::ctor(const&)/8192 3310895 ns 2468608 ns
std::unordered_set<std::string>::operator=(const&) (into cleared Container)/0 16.1 ns 15.8 ns
std::unordered_set<std::string>::operator=(const&) (into cleared Container)/32 5856 ns 1039 ns
std::unordered_set<std::string>::operator=(const&) (into cleared Container)/1024 170436 ns 74836 ns
std::unordered_set<std::string>::operator=(const&) (into cleared Container)/8192 1574235 ns 1096891 ns
std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/0 16.0 ns 16.3 ns
std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/32 5571 ns 1064 ns
std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/1024 199220 ns 75462 ns
std::unordered_set<std::string>::operator=(const&) (into partially populated Container)/8192 1552465 ns 1116094 ns
std::unordered_set<std::string>::operator=(const&) (into populated Container)/0 1.70 ns 2.14 ns
std::unordered_set<std::string>::operator=(const&) (into populated Container)/32 2562 ns 645 ns
std::unordered_set<std::string>::operator=(const&) (into populated Container)/1024 228608 ns 39100 ns
std::unordered_set<std::string>::operator=(const&) (into populated Container)/8192 2013723 ns 390401 ns
```
Fixes #77657
2025-08-15 08:57:33 +02:00
Nikolas Klauser
1cac2be874
[libc++] Optimize copy construction and assignment of __tree ( #151304 )
...
```
----------------------------------------------------------------------------------------------------------
Benchmark old new
----------------------------------------------------------------------------------------------------------
std::map<int, int>::ctor(const&)/0 15.5 ns 14.9 ns
std::map<int, int>::ctor(const&)/32 474 ns 321 ns
std::map<int, int>::ctor(const&)/1024 24591 ns 11101 ns
std::map<int, int>::ctor(const&)/8192 236153 ns 98868 ns
std::map<std::string, int>::ctor(const&)/0 15.2 ns 14.9 ns
std::map<std::string, int>::ctor(const&)/32 2673 ns 2340 ns
std::map<std::string, int>::ctor(const&)/1024 115354 ns 86088 ns
std::map<std::string, int>::ctor(const&)/8192 1298510 ns 626876 ns
std::map<int, int>::operator=(const&) (into cleared Container)/0 16.5 ns 16.1 ns
std::map<int, int>::operator=(const&) (into cleared Container)/32 548 ns 323 ns
std::map<int, int>::operator=(const&) (into cleared Container)/1024 28418 ns 11026 ns
std::map<int, int>::operator=(const&) (into cleared Container)/8192 281827 ns 97113 ns
std::map<int, int>::operator=(const&) (into populated Container)/0 2.42 ns 1.85 ns
std::map<int, int>::operator=(const&) (into populated Container)/32 369 ns 73.0 ns
std::map<int, int>::operator=(const&) (into populated Container)/1024 24078 ns 2322 ns
std::map<int, int>::operator=(const&) (into populated Container)/8192 266537 ns 22963 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/0 16.6 ns 16.2 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/32 2614 ns 1622 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/1024 116826 ns 63281 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/8192 1316655 ns 649177 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/0 2.42 ns 1.89 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/32 1264 ns 581 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/1024 238826 ns 39943 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/8192 2412327 ns 379456 ns
```
Fixes #77658
Fixes #62571
2025-08-05 09:49:40 +02:00
A. Jiang
4a509f853f
[libc++] Implement comparison operators for tuple
added in C++23 ( #148799 )
...
And constrain the new `operator==` since C++26.
This patch implements parts of P2165R4, P2944R3, and a possibly improved
resolution of LWG3882. Currently, libstdc++ and MSVC STL constrain the
new overloads in the same way.
Also set feature-test macro `__cpp_lib_constrained_equality` and add
related release note, as P2944R3 will completed with this patch.
Fixes #136765
Fixes #136770
Fixes #105424
2025-08-01 11:53:33 -04:00
Konstantin Varlamov
3eee9fc2c4
[libc++][hardening] Introduce assertion semantics. ( #149459 )
...
Assertion semantics closely mimic C++26 Contracts evaluation semantics.
This brings our implementation closer in line with C++26 Library Hardening
(one particular benefit is that using the `observe` semantic makes adopting
hardening easier for projects).
2025-07-29 00:19:15 -07:00
Hui
d344c383e2
[libc++][ranges] implement std::ranges::zip_transform_view
( #79605 )
...
Fixes #104977
Fixes #105035
---------
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Co-authored-by: A. Jiang <de34@live.cn>
2025-07-20 09:13:59 +01:00
Louis Dionne
167c695cec
[libc++] Add and empty skeleton for LLVM 22 release notes ( #149535 )
2025-07-19 14:32:54 +01:00
Louis Dionne
d737fe2c91
[libc++][NFC] Fix typos in the libc++ 21 release notes ( #149536 )
2025-07-18 11:54:27 -04:00
Nikolas Klauser
339a1f2e8f
Revert "[libc++][hardening] Introduce assertion semantics" ( #148822 )
...
Reverts llvm/llvm-project#148268
It looks like this was based on #148266 , which I reverted in #148787 .
2025-07-15 12:43:37 +02:00
Konstantin Varlamov
7345508c6f
[libc++][hardening] Introduce assertion semantics ( #148268 )
...
Assertion semantics closely mimic C++26 Contracts evaluation semantics.
This brings our implementation closer in line with C++26 Library
Hardening (one particular benefit is that using the `observe` semantic
makes adopting hardening easier for projects).
2025-07-15 02:14:30 -07:00
A. Jiang
4177bfdb46
[libc++][docs] Confirm that P2372R3 has been implemented ( #148573 )
...
In #125921 , the changes requested by P2372R3 were completed and tested
together with corresponding `chrono` types. But that PR didn't mention
P2372R3. The `__cpp_lib_format` FTM was even bumped by an earlier PR
#98275 .
This PR confirms that P2372R3 was completed in LLVM 21 (together with P1361R2).
Closes #100043
2025-07-14 10:23:27 -04:00
Kazu Hirata
ef48b7fae5
[libcxx] Fix a typo in documentation ( #148557 )
2025-07-13 22:20:03 -07:00
A. Jiang
8b171a08db
[libc++] Remove the packaged_task::result_type
extension ( #147671 )
...
No escape hatch added, as there doesn't seem anyone critically relying
on this.
2025-07-10 15:04:49 +08:00
Nikolas Klauser
44d37695a5
[libc++] Optimize ctype::to{lower,upper} ( #145344 )
...
```
----------------------------------------------
Benchmark old new
--------------------------- ------------------
BM_tolower_char<char> 1.64 ns 1.41 ns
BM_tolower_char<wchar_t> 1.64 ns 1.41 ns
BM_tolower_string<char> 32.4 ns 12.8 ns
BM_tolower_string<wchar_t> 32.9 ns 15.1 ns
BM_toupper_char<char> 1.63 ns 1.64 ns
BM_toupper_char<wchar_t> 1.63 ns 1.41 ns
BM_toupper_string<char> 32.2 ns 12.7 ns
BM_toupper_string<wchar_t> 33.0 ns 15.1 ns
```
2025-07-09 16:32:01 +02:00
Hui
0d1e5ab2fd
[libc++] P2655R3 common_reference_t of reference_wrapper Should Be a Reference Type ( #141408 )
...
Fixes #105260
This patch applies the change as a DR to C++20. The rationale is that
the paper is more like a bug fix. It does not introduce new features, it
simply changes an existing behaviour (as a bug fix). MSVC STL DRed this
paper to C++20 as well.
2025-07-06 17:32:59 +01:00
Hui
5f44b5a305
[libc++][doc][NFC] update release notes on P3372R3 ( #147161 )
2025-07-06 10:51:35 +01:00
Hui
34b2e934ea
[libc++] Introduce __product_iterator_traits
and optimise flat_map::insert
( #139454 )
...
Fixes #108624
This allows `flat_map::insert(Iter, Iter)` to directly forward to
underlying containers' `insert(Iter, Iter)`, instead of inserting one
element at a time, when input models "product iterator". atm,
`flat_map::iterator` and `zip_view::iterator` are "product iterator"s.
This gives about almost 10x speed up in my benchmark with -03 (for both
before and after)
```cpp
Benchmark Time CPU Time Old Time New CPU Old CPU New
-----------------------------------------------------------------------------------------------------------------------------------------------
flat_map::insert_product_iterator_flat_map/32 -0.5028 -0.5320 149 74 149 70
flat_map::insert_product_iterator_flat_map/1024 -0.8617 -0.8618 3113 430 3112 430
flat_map::insert_product_iterator_flat_map/8192 -0.8877 -0.8877 26682 2995 26679 2995
flat_map::insert_product_iterator_flat_map/65536 -0.8769 -0.8769 226235 27844 226221 27841
flat_map::insert_product_iterator_zip/32 -0.5844 -0.5844 162 67 162 67
flat_map::insert_product_iterator_zip/1024 -0.8754 -0.8754 3427 427 3427 427
flat_map::insert_product_iterator_zip/8192 -0.8934 -0.8934 28134 3000 28132 3000
flat_map::insert_product_iterator_zip/65536 -0.8783 -0.8783 229783 27960 229767 27958
OVERALL_GEOMEAN -0.8319 -0.8332 0 0 0 0
```
---------
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-06-28 13:42:50 +01:00
Hui
831fcb5e91
[libc++] constexpr flat_map ( #137453 )
...
Fixes #128673
2025-06-21 13:41:32 +01:00
Jakub Mazurkiewicz
1bb2328fd3
[libc++] Implement views::join_with
( #65536 )
...
* Implement "P2441R2 `views::join_with`" (https://wg21.link/P2441R2 ),
closes #105185
* Implement LWG4074 (https://wg21.link/LWG4074 ), closes #105346
* Complete implementation of "P2711R1 Making multi-param constructors of
views explicit" (https://wg21.link/P2711R1 ), closes #105252
* Complete implementation of "P2770R0 Stashing stashing iterators for
proper flattening" (https://wg21.link/P2770R0 ), closes #105250
2025-06-21 10:54:50 +01:00
Peng Liu
9827440f1e
[libc++] Optimize ranges::{for_each, for_each_n} for segmented iterators ( #132896 )
...
Previously, the segmented iterator optimization was limited to `std::{for_each, for_each_n}`. This patch
extends the optimization to `std::ranges::for_each` and `std::ranges::for_each_n`, ensuring consistent
optimizations across these algorithms. This patch first generalizes the `std` algorithms by introducing
a `Projection` parameter, which is set to `__identity` for the `std` algorithms. Then we let the `ranges`
algorithms to directly call their `std` counterparts with a general `__proj` argument. Benchmarks
demonstrate performance improvements of up to 21.4x for ``std::deque::iterator`` and 22.3x for
``join_view`` of ``vector<vector<char>>``.
Addresses a subtask of #102817 .
2025-06-18 12:22:47 -04:00
Nikolas Klauser
b979311842
[libc++] Remove allocator support from std::function ( #140395 )
...
The allocator support was removed in P0302R1, since it was impossible to
implement. We're currently providing the API for this, but ignore the
allocator in all cases but one (which is almost certainly an oversight).
That case is the `function(allocator_arg_t, const Alloc&, Func)`
constuctor. IMO we should remove the API entirely at a later date, but
this only removes most of the code for now, leaving only the public
functions. This not only simplifies the code quite a bit, but also
results in the constructor being instantiated ~8x faster.
Fixes #133901
2025-06-12 14:21:29 +02:00
A. Jiang
fdb11c1be6
[libc++] Disallow specializing common_reference
( #141465 )
...
`common_reference` isn't an exception for [meta.rqmts]/4, so it's better
to disallow users to specialize it.
`indirectly_readable.compile.pass.cpp` was a bit problematic. It
attempted to opt-out common reference type in some wrong ways. Also, the
standard effectively forbids opting-out common reference type for `T&`
and `T&&`. This patch removes and adjusts some problematic cases.
---------
Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
2025-06-04 20:41:58 +08:00
Peng Liu
81b81354f8
[libc++] Optimize bitset::to_string ( #128832 )
...
This patch optimizes `bitset::to_string` by replacing the existing bit-by-bit processing with a more efficient
bit traversal strategy. Instead of checking each bit sequentially, we leverage `std::__countr_zero` to efficiently
locate the next set bit, skipping over consecutive zero bits. This greatly accelerates the conversion process,
especially for sparse `bitset`s where zero bits dominate. To ensure similar improvements for dense `bitset`s, we
exploit symmetry by inverting the bit pattern, allowing us to apply the same optimized traversal technique. Even
for uniformly distributed `bitset`s, the proposed approach offers measurable performance gains over the existing
implementation.
Benchmarks demonstrate substantial improvements, achieving up to 13.5x speedup for sparse `bitset`s with
`Pr(true bit) = 0.1`, 16.1x for dense `bitset`s with `Pr(true bit) = 0.9`, and 8.3x for uniformly distributed
`bitset`s with `Pr(true bit) = 0.5)`.
2025-05-21 12:16:40 -04:00
Peng Liu
09c266b75d
[libc++] Optimize std::for_each_n for segmented iterators ( #135468 )
...
This patch enhances the performance of `std::for_each_n` when used with
segmented iterators, leading to significant performance improvements,
summarized in the tables below. This addresses a subtask of
https://github.com/llvm/llvm-project/issues/102817 .
2025-05-21 12:10:50 -04:00
Nikolas Klauser
3a86e0bd29
[libc++] Optimize std::getline ( #121346 )
...
```
-----------------------------------------------
Benchmark old new
-----------------------------------------------
BM_getline_string 318 ns 32.4 ns
```
2025-05-19 10:59:36 +02:00
A. Jiang
e9ce752769
[libc++] Remove the constexpr hash<vector<bool>>
extension ( #132617 )
...
libc++ makes the `hash<vector<bool, A>>::operator()` `constexpr` since
C++20, which is a conforming extension, but it was unintended.
This patch removes the extension, with an escape hatch macro for it, and
the escape hatch will be removed in the future. Test cases for
`constexpr` along with the assumption of hash values are moved to the
`libcxx/test/libcxx/` subdirectory.
---------
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-05-14 07:20:27 +08:00
Louis Dionne
91074a1b50
[libc++] Reword release note section about future releases ( #138544 )
...
For several releases, we had a section in the release notes that was
called "Upcoming Deprecations and Removals". That section was used to
advertize breaking changes in future releases as opposed to ones in the
current release.
However, the way this section was worded and organized made it unclear
what release these announcements related to. This patch rewords that
section of the release notes to make it less ambiguous and moves items
that aren't done yet (but relate to the ongoing release) to a different
section with a TODO.
2025-05-07 13:01:40 -04:00
Louis Dionne
25fc52e655
[libc++] Re-introduce _LIBCPP_DISABLE_AVAILABILITY ( #134158 )
...
The `_LIBCPP_DISABLE_AVAILABILITY` macro was removed in afae1a5f32bb as an
intended no-op. It turns out that some projects are making use of that
macro to work around a Clang bug with availability annotations that
still exists: https://github.com/llvm/llvm-project/issues/134151 .
Since that Clang bug still hasn't been fixed, I feel that we must sill
honor that unfortunate macro until we've figured out how to get rid of
it without breaking code.
2025-05-05 14:19:13 -07:00
Peng Liu
e9280a1d39
[libc++] Backport segmented iterator optimization for std::for_each to C++11 ( #134960 )
...
Previously, the segmented iterator optimization for `std::for_each` was restricted to C++23 and later due to its dependency on `__movable_box`, which is not available in earlier standards. This patch eliminates that restriction, enabling consistent optimizations starting from C++11.
By backporting this enhancement, we improve performance across older standards and create opportunities to extend similar optimizations to other algorithms by forwarding their calls to `std::for_each`.
2025-04-19 07:12:43 -04:00
Дмитрий Изволов
51b8c66b08
[libc++] Extend the scope of radix sorting inside std::stable_sort to floating-point types ( #129452 )
...
These changes speed up `std::stable_sort` in the case of sorting
floating-point types.
This applies only to IEEE 754 floats.
The speedup is similar to that achieved for integers in PR #104683 (see
benchmarks below).
Why does this worth doing?
Previously, `std::stable_sort` had almost no chance of beating
`std::sort`.
Now there are cases when `std::stable_sort` is preferrable, and the
difference is significant.
```
---------------------------------------------------------------------------
Benchmark | std::stable_sort | std::sort | std::stable_sort
| without radix_sort | | with radix_sort
---------------------------------------------------------------------------
float_Random_1 | 1.62 ns | 2.15 ns | 1.61 ns
float_Random_4 | 18.0 ns | 2.71 ns | 16.3 ns
float_Random_16 | 118 ns | 113 ns | 112 ns
float_Random_64 | 751 ns | 647 ns | 730 ns
float_Random_256 | 4715 ns | 2937 ns | 4669 ns
float_Random_1024 | 25713 ns | 13172 ns | 5959 ns <--
float_Random_4096 | 131307 ns | 56870 ns | 19294 ns <--
float_Random_16384 | 624996 ns | 242953 ns | 64264 ns <--
float_Random_65536 | 2895661 ns | 1027279 ns | 288553 ns <--
float_Random_262144 | 13285372 ns | 4342593 ns | 3022377 ns <--
float_Random_1048576 | 60595871 ns | 19087591 ns | 18690457 ns <--
float_Random_2097152 | 131336117 ns | 38800396 ns | 52325016 ns
float_Random_4194304 | 270043042 ns | 79978019 ns | 102907726 ns
double_Random_1 | 1.60 ns | 2.15 ns | 1.61 ns
double_Random_4 | 15.2 ns | 2.70 ns | 16.9 ns
double_Random_16 | 104 ns | 112 ns | 119 ns
double_Random_64 | 712 ns | 614 ns | 755 ns
double_Random_256 | 4496 ns | 2966 ns | 4820 ns
double_Random_1024 | 24722 ns | 12679 ns | 6189 ns <--
double_Random_4096 | 126075 ns | 54484 ns | 20999 ns <--
double_Random_16384 | 613782 ns | 232557 ns | 110276 ns <--
double_Random_65536 | 2894972 ns | 988531 ns | 774302 ns <--
double_Random_262144 | 13460273 ns | 4278059 ns | 5115123 ns
double_Random_1048576 | 61119996 ns | 18408462 ns | 27166574 ns
double_Random_2097152 | 132511525 ns | 37986158 ns | 54423869 ns
double_Random_4194304 | 272949862 ns | 77912616 ns | 147670834 ns
```
Comparison for only `std::stable_sort`:
```
Benchmark Time Time Old Time New
--------------------------------------------------------------------------------------------------
BM_StableSort_float_Random_1024 -0.7997 25438 5096
BM_StableSort_float_Random_4096 -0.8731 128157 16260
BM_StableSort_float_Random_16384 -0.9024 621271 60623
BM_StableSort_float_Random_65536 -0.9081 2922413 268619
BM_StableSort_float_Random_262144 -0.7766 13386345 2990408
BM_StableSort_float_Random_1048576 -0.6954 60673010 18481751
BM_StableSort_float_Random_2097152 -0.6026 130977358 52052182
BM_StableSort_float_Random_4194304 -0.6252 271556583 101770500
BM_StableSort_float_Ascending_1024 -0.6430 6711 2396
BM_StableSort_float_Ascending_4096 -0.7979 38460 7773
BM_StableSort_float_Ascending_16384 -0.8471 191069 29222
BM_StableSort_float_Ascending_65536 -0.8683 882321 116194
BM_StableSort_float_Ascending_262144 -0.8346 3868552 639937
BM_StableSort_float_Ascending_1048576 -0.7460 16521233 4195953
BM_StableSort_float_Ascending_2097152 -0.5439 21757532 9922776
BM_StableSort_float_Ascending_4194304 -0.7525 67847496 16791582
BM_StableSort_float_Descending_1024 -0.6359 15038 5475
BM_StableSort_float_Descending_4096 -0.7090 62810 18278
BM_StableSort_float_Descending_16384 -0.7763 311844 69750
BM_StableSort_float_Descending_65536 -0.7228 1270513 352202
BM_StableSort_float_Descending_262144 -0.6785 5484173 1763045
BM_StableSort_float_Descending_1048576 -0.5084 20223149 9941852
BM_StableSort_float_Descending_2097152 -0.7646 60523254 14247014
BM_StableSort_float_Descending_4194304 -0.5638 95706839 41748858
BM_StableSort_float_SingleElement_1024 +0.3715 1732 2375
BM_StableSort_float_SingleElement_4096 -0.1685 9357 7781
BM_StableSort_float_SingleElement_16384 -0.3793 47307 29362
BM_StableSort_float_SingleElement_65536 -0.4925 227666 115536
BM_StableSort_float_SingleElement_262144 -0.4271 1075853 616387
BM_StableSort_float_SingleElement_1048576 -0.3736 5097599 3193279
BM_StableSort_float_SingleElement_2097152 -0.2470 9854161 7420158
BM_StableSort_float_SingleElement_4194304 -0.3384 22175964 14670720
BM_StableSort_float_PipeOrgan_1024 -0.4885 10664 5455
BM_StableSort_float_PipeOrgan_4096 -0.6340 50095 18337
BM_StableSort_float_PipeOrgan_16384 -0.7078 238700 69739
BM_StableSort_float_PipeOrgan_65536 -0.6740 1102419 359378
BM_StableSort_float_PipeOrgan_262144 -0.7460 4698739 1193511
BM_StableSort_float_PipeOrgan_1048576 -0.5657 18493972 8032392
BM_StableSort_float_PipeOrgan_2097152 -0.7116 41089206 11850349
BM_StableSort_float_PipeOrgan_4194304 -0.6650 83445011 27955737
BM_StableSort_float_QuickSortAdversary_1024 -0.6863 17402 5460
BM_StableSort_float_QuickSortAdversary_4096 -0.7715 79864 18247
BM_StableSort_float_QuickSortAdversary_16384 -0.7800 317480 69839
BM_StableSort_float_QuickSortAdversary_65536 -0.7400 1357601 352967
BM_StableSort_float_QuickSortAdversary_262144 -0.6450 5662094 2009769
BM_StableSort_float_QuickSortAdversary_1048576 -0.5092 21173627 10392107
BM_StableSort_float_QuickSortAdversary_2097152 -0.7333 61748178 16469993
BM_StableSort_float_QuickSortAdversary_4194304 -0.5607 98459863 43250182
BM_StableSort_double_Random_1024 -0.7657 24769 5802
BM_StableSort_double_Random_4096 -0.8441 126449 19717
BM_StableSort_double_Random_16384 -0.8269 614910 106447
BM_StableSort_double_Random_65536 -0.7413 2905000 751427
BM_StableSort_double_Random_262144 -0.6287 13449514 4994348
BM_StableSort_double_Random_1048576 -0.5635 60863246 26568349
BM_StableSort_double_Random_2097152 -0.5959 130293892 52654532
BM_StableSort_double_Random_4194304 -0.4772 272616445 142526267
BM_StableSort_double_Ascending_1024 -0.4870 6757 3466
BM_StableSort_double_Ascending_4096 -0.7360 37592 9923
BM_StableSort_double_Ascending_16384 -0.7971 183967 37324
BM_StableSort_double_Ascending_65536 -0.7465 897116 227398
BM_StableSort_double_Ascending_262144 -0.6764 4020980 1301033
BM_StableSort_double_Ascending_1048576 -0.6407 16421799 5900751
BM_StableSort_double_Ascending_2097152 -0.6380 29347139 10622419
BM_StableSort_double_Ascending_4194304 -0.5934 70439925 28644185
BM_StableSort_double_Descending_1024 -0.5988 15216 6105
BM_StableSort_double_Descending_4096 -0.6857 65069 20449
BM_StableSort_double_Descending_16384 -0.6922 329321 101381
BM_StableSort_double_Descending_65536 -0.7038 1367970 405242
BM_StableSort_double_Descending_262144 -0.6472 5361644 1891429
BM_StableSort_double_Descending_1048576 -0.6656 22031404 7366459
BM_StableSort_double_Descending_2097152 -0.7593 68922467 16591242
BM_StableSort_double_Descending_4194304 -0.6392 96283643 34743223
BM_StableSort_double_SingleElement_1024 +0.9128 1895 3625
BM_StableSort_double_SingleElement_4096 +0.1475 10013 11490
BM_StableSort_double_SingleElement_16384 -0.1901 52382 42424
BM_StableSort_double_SingleElement_65536 -0.2096 254698 201313
BM_StableSort_double_SingleElement_262144 -0.1833 1248478 1019648
BM_StableSort_double_SingleElement_1048576 -0.1741 5703397 4710603
BM_StableSort_double_SingleElement_2097152 -0.1751 10922197 9009835
BM_StableSort_double_SingleElement_4194304 -0.1538 26571923 22485137
BM_StableSort_double_PipeOrgan_1024 -0.4406 10752 6014
BM_StableSort_double_PipeOrgan_4096 -0.5917 49456 20195
BM_StableSort_double_PipeOrgan_16384 -0.6258 270515 101221
BM_StableSort_double_PipeOrgan_65536 -0.7098 1159462 336457
BM_StableSort_double_PipeOrgan_262144 -0.6591 4735711 1614433
BM_StableSort_double_PipeOrgan_1048576 -0.6620 19353110 6541172
BM_StableSort_double_PipeOrgan_2097152 -0.7288 49131812 13323391
BM_StableSort_double_PipeOrgan_4194304 -0.5988 81958974 32878171
BM_StableSort_double_QuickSortAdversary_1024 -0.6516 17948 6254
BM_StableSort_double_QuickSortAdversary_4096 -0.7527 82359 20363
BM_StableSort_double_QuickSortAdversary_16384 -0.7009 340410 101811
BM_StableSort_double_QuickSortAdversary_65536 -0.6854 1487480 467928
BM_StableSort_double_QuickSortAdversary_262144 -0.6386 5648460 2041377
BM_StableSort_double_QuickSortAdversary_1048576 -0.6127 22859142 8852587
BM_StableSort_double_QuickSortAdversary_2097152 -0.7161 68693975 19499381
BM_StableSort_double_QuickSortAdversary_4194304 -0.5909 95532179 39077491
OVERALL_GEOMEAN -0.6472 0 0
```
2025-04-16 17:34:11 +08:00
Damien L-G
557e931d95
[libc++] Implement P2897R7 aligned_accessor: An mdspan accessor expressing pointer over-alignment ( #122603 )
...
Closes #118372
2025-04-14 17:33:57 -04:00
Mark de Wever
1175f5b988
[libc++] Removes the _LIBCPP_VERBOSE_ABORT_NOT_NOEXCEPT macro. ( #135494 )
...
This makes __libcpp_verbose_abort unconditionally noexcept. This was
planned for the upcomming release.
2025-04-14 18:55:01 +02:00
Mark de Wever
d39d24cec1
[libc++][doc] Updates the release notes.
...
Copies the not-yet-implemented items planned for removal from the
LLVM-20 to the LLVM-21 release notes. This allows to better keep track
of the status of the next release.
2025-04-12 15:26:48 +02:00
Nikolas Klauser
8fc2538f33
Reapply "[libc++] Optimize num_put integral functions" ( #131613 ) ( #133572 )
...
This reverts commit d1156fcb56891fb1a426c3e8331a51d47f98a1b8.
This patch fixes the reported incorrect formatting changes and adds
tests for them. The performance should be unaffected, since there are no
significant changes required to fix the bugs.
Specifically, a `>` was changed to a `>=` to also add a `+` in the zero
case, and we're checking for zero now before printing the octal and
hexadecimal prefixes.
Closes #131710
2025-04-11 15:35:58 +02:00
Mark de Wever
01a2922f0d
[libc++][doc] Removes LLVM 19 Release Notes. ( #134894 )
...
There will be no more LLVM-19 releases so we will not backport patches
for this release. This makes these Release Notes obsolete.
2025-04-10 18:04:49 +02:00
A. Jiang
ab95005a05
[libc++] P3247R2: Deprecate is_trivial(_v)
( #130573 )
...
Requirements on character-like types are updated unconditionally,
because `basic_string` does requires the default-constructibility. It
might be possible to make `basic_string_view` support classes with
non-public trivial default constructor, but this doesn't seem sensible.
libcxxabi's `ItaniumDemangle.h` is also updated to avoid deprecated
features.
2025-04-09 07:40:01 +08:00
Hui
7013b51548
[libc++] Implement std::flat_multiset
( #128363 )
...
fixes https://github.com/llvm/llvm-project/issues/105193
2025-04-06 10:50:55 +01:00
Louis Dionne
2cd8edd1ff
[libc++] Add missing release note for LLVM 20 about zip_view ( #134144 )
...
We should have had a release note in LLVM 20 about implementing P2165R4
since that is technically an ABI and API break for zip_view. We don't
expect anyone to actually hit the ABI issue, but we've come across some
(fairly small) breakage due to the API change, so this should at least
be mentioned in the release notes.
2025-04-03 18:34:49 -04:00
Nikolas Klauser
c59d3a2684
[libc++] Add visibility annotations to the std namespace with GCC ( #133233 )
...
This allows us to remove the need for `_LIBCPP_TEMPLATE_VIS` and fixes a
bunch of missing annotations for RTTI when used across dylib boundaries.
`_LIBCPP_TEMPLATE_VIS` itself will be removed in a separate patch, since
it touches a lot of code.
This patch is a no-op for Clang. Only GCC is affected.
2025-04-02 22:12:59 +02:00
Amr Hesham
357306572d
[libcxx] Put std::monostate
in <utility>
( #128373 )
...
Fixes : #127874
2025-03-25 18:31:57 +01:00
Hui
2f1416bbcd
[libc++] implement std::flat_set ( #125241 )
...
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-03-23 14:45:21 +00:00
A. Jiang
6038077dde
[libc++] Bump __cpp_lib_constexpr_algorithms
for P2562R1 in C++26 ( #132075 )
...
Completes P2562R1.
2025-03-21 07:33:52 +08:00
Alexander Kornienko
d1156fcb56
Revert "[libc++] Optimize num_put integral functions" ( #131613 )
...
Reverts llvm/llvm-project#120859
This change breaks formatting of `0` with `std::showbase` + `std::hex`
or `std::oct`, as well as `+0` with `std::showpos`. I believe the new
behavior is violating the standard. See
https://github.com/llvm/llvm-project/pull/120859#issuecomment-2723970242
and later comments for details and explanation.
2025-03-18 02:05:51 +01:00
Peng Liu
4baf1c03fa
[libc++] Optimize ranges::rotate for vector<bool>::iterator ( #121168 )
...
This PR optimizes the performance of `std::ranges::rotate` for
`vector<bool>::iterator`. The optimization yields a performance
improvement of up to 2096x.
Closes #64038 .
2025-03-13 14:07:23 -04:00
Hristo Hristov
262a775582
[libc++][NFC] Fixed bad link in 21.rst ( #130428 )
2025-03-09 00:52:51 +02:00
Hristo Hristov
6d9dfd75e4
[libc++][type_traits] Implements "A type trait to detect reference binding to temporary" ( #128649 )
...
Implements partially: [P2255R2: A type trait to detect reference binding
to temporary](https://wg21.link/P2255R2 )
Issue: https://github.com/llvm/llvm-project/issues/105180
https://eel.is/c++draft/meta.type.synop
https://eel.is/c++draft/meta.unary.prop
Implented type traits:
- [x] `reference_constructs_from_temporary`
- [x] `reference_converts_from_temporary`
Closes #129049
Minor drive-by tweak to `std::is_implicit_lifetime` tests.
---------
Co-authored-by: Hristo Hristov <zingam@outlook.com>
2025-03-08 15:20:56 +01:00
A. Jiang
94714fb303
[libc++] Deprecate is_pod(_v)
since C++20 ( #129471 )
...
Previously, commit 042f07eed8c1acba19ea04310137bee12b18045a claimed that
P0767R1 was implemented in LLVM 7.0, but no deprecation warning was
implemented. This patch adds the missing warnings.
2025-03-07 16:02:57 +08:00
Nikolas Klauser
15edf8725a
[libc++] Optimize num_put integral functions ( #120859 )
...
```
-------------------------------------------------------
Benchmark old new
-------------------------------------------------------
BM_num_put<bool> 76.2 ns 32.0 ns
BM_num_put<long> 76.9 ns 33.1 ns
BM_num_put<long long> 77.9 ns 34.2 ns
BM_num_put<unsigned long> 78.4 ns 33.1 ns
BM_num_put<unsigned long long> 78.0 ns 34.4 ns
BM_num_put<double> 224 ns 228 ns
BM_num_put<long double> 239 ns 230 ns
BM_num_put<const void*> 68.7 ns 35.1 ns
```
Fixes #40109 .
2025-03-05 14:18:49 +01:00
Peng Liu
a12744ff05
[libc++] Optimize ranges::swap_ranges for vector<bool>::iterator ( #121150 )
...
This PR optimizes the performance of `std::ranges::swap_ranges` for
`vector<bool>::iterator`, addressing a subtask outlined in issue #64038 .
The optimizations yield performance improvements of up to **611x** for
aligned range swap and **78x** for unaligned range swap comparison.
Additionally, comprehensive tests covering up to 4 storage words (256
bytes) with odd and even bit sizes are provided, which validate the
proposed optimizations in this patch.
2025-03-04 17:15:36 -05:00