1648 Commits

Author SHA1 Message Date
Timothy Choi
d282452e4c
[libc++] Avoid string reallocation in std::filesystem::path::lexically_relative (#152964)
Improves runtime by around 20 to 40%. (1.3x to 1.7x)

```
Benchmark                                                           Time             CPU      Time Old      Time New       CPU Old       CPU New
------------------------------------------------------------------------------------------------------------------------------------------------
BM_LexicallyRelative/small_path/2                                -0.2111         -0.2082           229           181           228           180
BM_LexicallyRelative/small_path/4                                -0.2579         -0.2550           455           338           452           337
BM_LexicallyRelative/small_path/8                                -0.2643         -0.2616           844           621           838           619
BM_LexicallyRelative/small_path/16                               -0.2582         -0.2556          1562          1158          1551          1155
BM_LexicallyRelative/small_path/32                               -0.2518         -0.2496          3023          2262          3004          2254
BM_LexicallyRelative/small_path/64                               -0.2806         -0.2775          6344          4564          6295          4549
BM_LexicallyRelative/small_path/128                              -0.2165         -0.2137         11762          9216         11683          9186
BM_LexicallyRelative/small_path/256                              -0.2672         -0.2645         24499         17953         24324         17891
BM_LexicallyRelative/large_path/2                                -0.3268         -0.3236           426           287           422           285
BM_LexicallyRelative/large_path/4                                -0.3274         -0.3248           734           494           729           492
BM_LexicallyRelative/large_path/8                                -0.3586         -0.3560          1409           904          1399           901
BM_LexicallyRelative/large_path/16                               -0.3978         -0.3951          2764          1665          2743          1659
BM_LexicallyRelative/large_path/32                               -0.3934         -0.3908          5323          3229          5283          3218
BM_LexicallyRelative/large_path/64                               -0.3629         -0.3605         10340          6587         10265          6564
BM_LexicallyRelative/large_path/128                              -0.3450         -0.3423         19379         12694         19233         12649
BM_LexicallyRelative/large_path/256                              -0.3097         -0.3054         36293         25052         35943         24965
```

---------

Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
2025-08-20 16:58:21 +02:00
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
Hristo Hristov
f3008c1140
[libc++][flat_set] LWG3751, LWG3774 (#153934)
- LWG3751: Missing feature macro for `flat_set`

Implemented in LLVM21:
7013b51548

Closes  #105021

- LWG3774: `<flat_set>` should include `<compare>`

Implemented in LLVM21:
2f1416bbcd

684797b644/libcxx/include/flat_set (L77)

Closes #105036
2025-08-17 09:52:07 +08:00
Hristo Hristov
0561ede6c6
[libc++][jthread] LWG3788: jthread::operator=(jthread&&) postconditions are unimplementable under self-assignment (#153758)
Already implemented in LLVM18:
[695138c](695138ca84)

For details see:
https://github.com/llvm/llvm-project/issues/105045#issuecomment-3190674947

Closes #105045
2025-08-16 11:17:30 +08: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
Hristo Hristov
6d40257b05
[libc++][ranges] LWG4096: views::iota(views::iota(0)) should be rejected (#152855)
Fixes #105352
2025-08-13 19:21:13 -04:00
yronglin
24b772769f
[libc++] Implement LWG4222 'expected' constructor from a single value missing a constraint (#152676)
Implement [LWG4222](https://wg21.link/LWG4222).
Closes https://github.com/llvm/llvm-project/issues/148208

Signed-off-by: yronglin <yronglin777@gmail.com>
2025-08-10 01:11:20 +08:00
cmtice
5a47a1828a
[libcxx] Update testing documentation about CI container images. (#149192)
Add information to the libcxx testing documentation, about the names of
the new CI libcxx runner sets, their current values, and how to change
the values or the runner set being used.
2025-08-06 13:14:47 -07: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
A. Jiang
3d688233bd
[libc++][docs] Add missing entry for status pages, fix bad formatting, and deduplicate (#148186)
In a previously PR, the entry for P3491R3 define_static_{string,object,array} was missing.
This patch adds it back.

The number of LWG2687, LWG2709, LWG3315, LWG3395, LWG3987, and LWG4113
were duplicated in the title. It seems better to avoid such duplicates.

Also fixes some formatting to properly use italic and code styles, and
remove one improper leading space from the title of P3682R0 (which
caused incorrect alignment in the generated page).
2025-07-15 11:14:41 -04:00
Louis Dionne
d145f716ae
[libc++] Bump Xcode support (#148651)
Libc++'s policy is to support only the latest released Xcode, which is
Xcode 16.x. We did update our CI jobs to Xcode 16.x, but we forgot to
update the documentation, which still mentioned Xcode 15. This patch
updates the documentation and cleans up outdated mentions of
apple-clang-15 in the test suite.
2025-07-15 10:45:37 -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
Hristo Hristov
5fc844acd8
[libc++] P2944R3: Constrained comparisons - optional (#144249)
Partially implements [P2944R3](https://wg21.link/P2944R3) which adds
constrained comparisons to std::optional.

Closes #136767


# References
[optional.relops](https://wg21.link/optional.relops)
[optional.comp.with.t](https://wg21.link/optional.comp.with.t)

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2025-07-15 10:12:39 +02: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
A. Jiang
e8a50a2568
[libc++][docs] Update paper & LWG issue lists after 2025-06 meeting (#147668)
CWG papers requiring library support are also listed.
2025-07-10 08:56:36 +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
Louis Dionne
a34db6f889 [libc++] Mark a few LWG issues as complete instead of Nothing To Do
A few LWG issues did require some testing changes and were not just
non-normative wording changes in the spec, so those should be
"Complete" instead of "Nothing to do".

Also mark LWG3987 and LWG4113 as complete:
- LWG3987 was done in https://github.com/llvm/llvm-project/pull/137524
- LWG4113 was done in https://github.com/llvm/llvm-project/pull/138291
2025-07-09 09:21:27 -04:00
A. Jiang
8ff636309d
[libc++][docs] Fix bad status and links in Cxx2cIssues.csv (#147669)
Currently, versions for (already implemented) LWG4024 and LWG4157 are
listed, but they are not marked "Complete" yet.
- LWG4024 was implemented together with P1020R1 + P1973R1 in 9af9d39a47d.
- LWG4157 was implemented together with P2167R3 in 557f7e1398e1.

Moreover, links for LWG issues resolved in 2025-02 Hagenberg meeting
were broken, they need to be fixed.
2025-07-09 09:20:35 -04: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
Nikolas Klauser
22f8ceded4
[libc++] Add the thread safety annotations unconditionally (#117497)
For these annotations to do anything you need `-Wthread-safety`, in
which case users most likely enable them anyways. This avoids that users
have to explictly define a macro just to use the feature they already
had to opt-in to.
2025-07-05 18:07:07 +02: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
Hristo Hristov
a19d37044b
[libc++] P2944R3: Constrained comparisions - tuple (#145677)
Implements P2944R3 partially, which adds constrained comparisons
`std::tuple`.
The missing overloads introduced in [P2165R4](https://wg21.link/P2165R4)
are not implemented.

Uses
[`__all`](f7af33a9eb/libcxx/include/__type_traits/conjunction.h (L45))
instead of a fold expression, see comment:
https://github.com/llvm/llvm-project/pull/141396#discussion_r2161166077

Relates to #136765

# References

[tuple.rel](https://wg21.link//tuple.rel)
2025-06-27 20:12:18 +03:00
Hristo Hristov
f2f4b557aa
[libc++] P2944R3: Constrained comparisions - variant (#141396)
This is a follow-up and depends on #139368 being merged first.

Implements [P2944R3](https://wg21.link/P2944R3) partially, which adds
constrained comparisons to `std::variant`

Closes #136769

Depends on #139368

# References

[variant.relops](https://wg21.link/variant.relops)
2025-06-25 12:12:23 +03: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
Kazu Hirata
ca9a09dbe6
[libc++] Fix a typo in documentation (#144763) 2025-06-18 15:03:17 -04: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
Peng Liu
13510c0736
[libc++] Make list constexpr as part of P3372R3 (#129799)
This patch makes `std::list` constexpr as part of P3372R3.

Fixes #128659.
2025-06-18 12:13:50 -04:00
Hristo Hristov
a0c00ccd5f
[libc++] P2944R3: Constrained comparisons - update reference_wrapper implementation (#139368)
Updates the implementation `std::reference_wrapper` -
[P2944R3](https://wg21.link/P2944R3) as discussed in
https://github.com/llvm/llvm-project/pull/117664#discussion_r1857826166
This PR also refactors the tests in preparation to implements the
constrained comparisons for `optional`, `variant` etc.

- Moves the test helpers (concepts and types) for testing constrained
comparisons to `test_comparisons.h`.
- Updates the `std::reference_wrapper` implementation to use the concept
`__core_convertible_to<bool>` as per comments in #135759.

Closes #138233

# References:
- [refwrap.comparisons](https://wg21.link/refwrap.comparisons)

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
Co-authored-by: Nikolas Klauser <nikolasklauser@berlin.de>
2025-06-15 07:45:48 +03:00
Kazu Hirata
5c1a021f7f
[libc++] Fix typos in documentation (#143912) 2025-06-12 10:54:36 -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
Nikolas Klauser
42c82fcc29
[libc++] Upgrade to GCC 15 (#138293) 2025-06-11 20:19:26 +02:00
Peng Liu
38fb0117ab
[libc++] Make forward_list constexpr as part of P3372R3 (#129435)
Fixes #128658
2025-06-11 12:13:36 -04:00
Nikolas Klauser
f2fede6095
[libc++] Document our ABI guarantees and what ABI flags exist to modify these guarantees (#132615) 2025-06-10 12:59:08 +02:00
Peng Liu
ec5610c4a2
[libc++] Ensure strong exception guarantee for forward_list::resize (#131025)
The current implementation of `forward_list::resize` does not meet the
strong exception safety guarantee required by [forward.list.modifiers]:

    If an exception is thrown by any of these member functions there is no
    effect on the container.

This patch refactors `resize()` to provide strong exception safety and
introduces additional tests to validate the strong exception guarantees
for other `forward_list` modifiers.

Fixes #118366.
2025-06-04 13:04:19 -04: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
3e5fd77d32
[libc++] constexpr priority_queue (#140634)
This patch makes `priority_queue` constexpr as part of P3372R3.

Fixes #128671.
2025-06-04 19:58:25 +08:00
David Spickett
783b399346 [libcxx][docs] Fix bullet point in Additional Tools section
Without a blank line after the ":", it was rendered on the same
line instead of a new one.
2025-05-28 08:35:54 +00: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