252 Commits

Author SHA1 Message Date
Nikolas Klauser
f038dfd22d
[libc++] Merge is_{,un}bounded_array.h into is_array.h (#167479)
These headers are incredibly simple and closely related, so this merges
them into a single one.
2025-11-13 09:29:28 +01:00
Nikolas Klauser
189d1853e4
[libc++] Add an initial modulemap for the test support headers (#162800)
This should improve the time it takes to run the test suite a bit. Right
now there are only a handful of headers in the modulemap because we're
missing a lot of includes in the tests. New headers should be added
there from the start, and we should fill up the modulemap over time
until it contains all the test support headers.
2025-11-13 08:28:48 +00:00
Nikolas Klauser
5c3323a59f
[libc++] Remove <stdbool.h> (#164595)
`<stdbool.h>` is provided by the compiler and both Clang and GCC provide
C++-aware versions of these headers, making our own wrapper header
entirely unnecessary.
2025-11-11 22:55:24 +01:00
Louis Dionne
17ce48f2b6
[libc++] Remove __is_replaceable emulation (#167355)
The Trivial Relocation feature has been removed from the C++26 working
draft. Based on discussions in Kona, it is unlikely that the
"replaceable" type concept will come back in the C++29 time frame.

Since we don't have a use for the type trait in the library at the
moment, remove the code associated to it. If we end up needing something
like it in the future, we can always add it back.
2025-11-11 07:53:56 -05:00
Louis Dionne
d2521f14a7
[libc++] Split macros related to hardening into their own header (#167069)
Hardening macros are easy to extract into their own header, and doing so
decreases the complexity of the main __config file.
2025-11-10 12:57:41 -05:00
Nikolas Klauser
152bda7269
[libc++] Replace the last uses of __tuple_types with __type_list (#167214)
`__tuple_types` is at this point just a `__type_list` with a weird name,
so we can just replace the few places it's still used.
2025-11-10 10:09:14 +01:00
Yuxuan Chen
adc7932461
[libcxx] Implement C++20 std::chrono::is_clock, std::chrono::is_clock_v (#160607)
Implemented
[[*time.traits.is.clock*]](https://eel.is/c++draft/time.traits.is.clock)
from [P0355R7](https://wg21.link/p0355r7).

This patch implements the C++20 feature `is_clock` and `is_clock_v`
based on the documentation [on
cppreference](https://en.cppreference.com/w/cpp/chrono/is_clock.html)

Fixes #166049.
2025-11-06 12:33:44 -08:00
Nikolas Klauser
2527b071ba
[libc++] P2641R4: Checking if a union alternative is active (std::is_within_lifetime) (#165243)
<https://wg21.link/P2641R4>

Implements the C++26 function in `<type_traits>` [meta.const.eval] (and
the corresponding feature test macro `__cpp_lib_is_within_lifetime`)

```c++
template<class T>
  consteval bool is_within_lifetime(const T*) noexcept;
```

This is done with the `__builtin_is_within_lifetime` builtin added to
Clang 20 by #91895 / 2a07509c8d3c8b5b2c88e4f73dde0071bf506870. This is
not (currently) available with GCC.

This implementation has provisions for LWG4138
<https://cplusplus.github.io/LWG/issue4138> where it is ill-formed to
instantiate `is_within_lifetime<T>` with a function type `T`.

Closes #105381

Co-authored-by: Mital Ashok <mital@mitalashok.co.uk>
2025-11-02 10:30:31 +01:00
Alex Rønne Petersen
e9389436e5
[libc++] Fix locale-related compilation errors on NetBSD (#143055)
To my knowledge, NetBSD is mostly like other BSDs, but doesn't have
`xlocale.h`. I think c664a7f may have inadvertently broken this.

With this change, I was able to run
[zig-bootstrap](https://github.com/ziglang/zig-bootstrap) to completion
for `x86_64-netbsd10.1-none`.
2025-10-29 21:30:54 +01:00
Nikolas Klauser
6d663cd365
[libc++] Simplify tuple_cat further (#163741) 2025-10-20 12:54:30 +02:00
Nikolas Klauser
55803b8af1
Reapply "[libc++] Avoid constructing additional objects when using map::at" (#160738) (#161485)
This reverts commit b86aaacf28b358b187071bc87075f1faa2d65c4e.

The issue in LLVM has been fixed now.
2025-10-02 11:15:33 +02:00
Nikolas Klauser
97367d1046
[libc++] Vectorize std::find (#156431)
```
Apple M4:
-----------------------------------------------------------------------------
Benchmark                                                 old             new
-----------------------------------------------------------------------------
std::find(vector<char>) (bail 25%)/8                  1.43 ns         1.44 ns
std::find(vector<char>) (bail 25%)/1024               5.54 ns         5.59 ns
std::find(vector<char>) (bail 25%)/8192               38.4 ns         39.1 ns
std::find(vector<char>) (bail 25%)/32768               134 ns          136 ns
std::find(vector<int>) (bail 25%)/8                   1.56 ns         1.57 ns
std::find(vector<int>) (bail 25%)/1024                65.3 ns         65.4 ns
std::find(vector<int>) (bail 25%)/8192                 465 ns          464 ns
std::find(vector<int>) (bail 25%)/32768               1832 ns         1832 ns
std::find(vector<long long>) (bail 25%)/8            0.920 ns         1.20 ns
std::find(vector<long long>) (bail 25%)/1024          65.2 ns         31.2 ns
std::find(vector<long long>) (bail 25%)/8192           464 ns          255 ns
std::find(vector<long long>) (bail 25%)/32768         1833 ns          992 ns
std::find(vector<char>) (process all)/8               1.21 ns         1.22 ns
std::find(vector<char>) (process all)/50              1.92 ns         1.93 ns
std::find(vector<char>) (process all)/1024            16.6 ns         16.9 ns
std::find(vector<char>) (process all)/8192             134 ns          136 ns
std::find(vector<char>) (process all)/32768            488 ns          503 ns
std::find(vector<int>) (process all)/8                2.45 ns         2.48 ns
std::find(vector<int>) (process all)/50               12.7 ns         12.7 ns
std::find(vector<int>) (process all)/1024              236 ns          236 ns
std::find(vector<int>) (process all)/8192             1830 ns         1834 ns
std::find(vector<int>) (process all)/32768            7351 ns         7346 ns
std::find(vector<long long>) (process all)/8          2.02 ns         1.45 ns
std::find(vector<long long>) (process all)/50         12.0 ns         6.12 ns
std::find(vector<long long>) (process all)/1024        235 ns          123 ns
std::find(vector<long long>) (process all)/8192       1830 ns          983 ns
std::find(vector<long long>) (process all)/32768      7306 ns         3969 ns
std::find(vector<bool>) (process all)/8               1.14 ns         1.15 ns
std::find(vector<bool>) (process all)/50              1.16 ns         1.17 ns
std::find(vector<bool>) (process all)/1024            4.51 ns         4.53 ns
std::find(vector<bool>) (process all)/8192            33.6 ns         33.5 ns
std::find(vector<bool>) (process all)/1048576         3660 ns         3660 ns
```
2025-09-29 11:10:19 +02:00
Nikolas Klauser
1ab4113d0e
[libc++] Remove a bunch of unused includes from <flat_*> (#160658) 2025-09-28 09:19:15 +02:00
Andrew Lazarev
b86aaacf28
Revert "[libc++] Avoid constructing additional objects when using map::at" (#160738)
Reverts llvm/llvm-project#157866

It breaks a lot of sanitizer buildbots
2025-09-25 15:10:37 -07:00
Nikolas Klauser
833d5f0cd8
[libc++] Avoid constructing additional objects when using map::at (#157866)
This patch adds additional overloads to `map::at` in case its known that
the argument is transparently comparable to the key type. This avoids
actually constructing the key type in some cases, potentially removing
allocations.

```
--------------------------------------------------------
Benchmark                            old             new
--------------------------------------------------------
BM_map_find_string_literal       12.8 ns         2.68 ns
```
2025-09-25 11:35:41 +02:00
Nikolas Klauser
8cb03a05ff
[libc++][NFC] Refactor __is_allocator to be a variable template (#159584) 2025-09-24 10:41:29 +02:00
Damien L-G
c1720822b6
[libc++][atomic_ref] Use __atomic_fetch_{add,sub} builtins on floating-points whenever possible (#135685)
Fix #135109

Clang is able to emit an `atomicrmw` instruction from the
`__atomic_fetch_add` and `__atomic_fetch_sub` builtins on floating-point
types.
2025-09-23 10:33:33 -05:00
Nikolas Klauser
1d131ffff8
[libc++] Optimize most of the __tree search algorithms (#155245)
This patch introduces a new comparator, namely `__lazy_synth_three_way`,
which tries to provide an efficient three way comparator for known types
and falls back to using the provided comparator if it doesn't know how
to do that. Currently, an efficient three way comparison is only
provided when using one of the `less` comparions object from the
standard library and `std::string`. This will be extended in future
patches.

```
------------------------------------------------------------------------------------------------------------------------------
Benchmark                                                                                                  old             new
------------------------------------------------------------------------------------------------------------------------------
std::map<std::string, int>::ctor(const&)/0                                                             12.6 ns         12.6 ns
std::map<std::string, int>::ctor(const&)/32                                                             858 ns          837 ns
std::map<std::string, int>::ctor(const&)/1024                                                         46700 ns        46739 ns
std::map<std::string, int>::ctor(const&)/8192                                                        458100 ns       449806 ns
std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/0                             12.8 ns         12.7 ns
std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/32                            1286 ns         1266 ns
std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/1024                         93812 ns        84686 ns
std::map<std::string, int>::ctor(iterator, iterator) (unsorted sequence)/8192                       1480346 ns      1385924 ns
std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/0                               12.9 ns         12.8 ns
std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/32                              1044 ns         1055 ns
std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/1024                           63071 ns        62861 ns
std::map<std::string, int>::ctor(iterator, iterator) (sorted sequence)/8192                          595046 ns       590223 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/0                               13.6 ns         13.6 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/32                               880 ns          911 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/1024                           48627 ns        47808 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/8192                          458552 ns       454497 ns
std::map<std::string, int>::operator=(const&) (into partially populated Container)/0                   13.8 ns         13.6 ns
std::map<std::string, int>::operator=(const&) (into partially populated Container)/32                   864 ns          851 ns
std::map<std::string, int>::operator=(const&) (into partially populated Container)/1024               49483 ns        49555 ns
std::map<std::string, int>::operator=(const&) (into partially populated Container)/8192              456977 ns       457894 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/0                             1.31 ns         1.31 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/32                             425 ns          415 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/1024                         14248 ns        14225 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/8192                        136684 ns       133696 ns
std::map<std::string, int>::insert(value) (already present)/0                                          21.5 ns         16.2 ns
std::map<std::string, int>::insert(value) (already present)/32                                         22.7 ns         25.1 ns
std::map<std::string, int>::insert(value) (already present)/1024                                       54.5 ns         29.1 ns
std::map<std::string, int>::insert(value) (already present)/8192                                       78.4 ns         30.4 ns
std::map<std::string, int>::insert(value) (new value)/0                                                40.9 ns         39.0 ns
std::map<std::string, int>::insert(value) (new value)/32                                               58.3 ns         47.2 ns
std::map<std::string, int>::insert(value) (new value)/1024                                              120 ns         71.3 ns
std::map<std::string, int>::insert(value) (new value)/8192                                              157 ns          129 ns
std::map<std::string, int>::insert(hint, value) (good hint)/0                                          40.3 ns         40.7 ns
std::map<std::string, int>::insert(hint, value) (good hint)/32                                         48.0 ns         30.0 ns
std::map<std::string, int>::insert(hint, value) (good hint)/1024                                        107 ns         63.2 ns
std::map<std::string, int>::insert(hint, value) (good hint)/8192                                        132 ns          107 ns
std::map<std::string, int>::insert(hint, value) (bad hint)/0                                           27.0 ns         40.9 ns
std::map<std::string, int>::insert(hint, value) (bad hint)/32                                          68.3 ns         58.4 ns
std::map<std::string, int>::insert(hint, value) (bad hint)/1024                                         125 ns         82.0 ns
std::map<std::string, int>::insert(hint, value) (bad hint)/8192                                         155 ns          150 ns
std::map<std::string, int>::insert(iterator, iterator) (all new keys)/0                                 404 ns          405 ns
std::map<std::string, int>::insert(iterator, iterator) (all new keys)/32                               2004 ns         1805 ns
std::map<std::string, int>::insert(iterator, iterator) (all new keys)/1024                           102820 ns        76102 ns
std::map<std::string, int>::insert(iterator, iterator) (all new keys)/8192                          1144590 ns       949266 ns
std::map<std::string, int>::insert(iterator, iterator) (half new keys)/0                                408 ns          404 ns
std::map<std::string, int>::insert(iterator, iterator) (half new keys)/32                              1592 ns         1377 ns
std::map<std::string, int>::insert(iterator, iterator) (half new keys)/1024                           74847 ns        53921 ns
std::map<std::string, int>::insert(iterator, iterator) (half new keys)/8192                          828505 ns       698716 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/0              407 ns          407 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/32            1584 ns         1557 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/1024         47157 ns        47443 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from same type)/8192        623887 ns       628385 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/0               405 ns          403 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/32             1478 ns         1510 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/1024          47852 ns        47835 ns
std::map<std::string, int>::insert(iterator, iterator) (product_iterator from zip_view)/8192         605311 ns       606951 ns
std::map<std::string, int>::erase(key) (existent)/0                                                     129 ns         94.0 ns
std::map<std::string, int>::erase(key) (existent)/32                                                    110 ns          106 ns
std::map<std::string, int>::erase(key) (existent)/1024                                                  121 ns          128 ns
std::map<std::string, int>::erase(key) (existent)/8192                                                  165 ns         66.9 ns
std::map<std::string, int>::erase(key) (non-existent)/0                                               0.269 ns        0.257 ns
std::map<std::string, int>::erase(key) (non-existent)/32                                               21.9 ns         11.3 ns
std::map<std::string, int>::erase(key) (non-existent)/1024                                             53.5 ns         25.4 ns
std::map<std::string, int>::erase(key) (non-existent)/8192                                             67.3 ns         31.9 ns
std::map<std::string, int>::erase(iterator)/0                                                          46.3 ns         46.7 ns
std::map<std::string, int>::erase(iterator)/32                                                         44.4 ns         41.8 ns
std::map<std::string, int>::erase(iterator)/1024                                                       43.7 ns         46.4 ns
std::map<std::string, int>::erase(iterator)/8192                                                       45.2 ns         44.1 ns
std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/0                      407 ns          407 ns
std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/32                     876 ns          906 ns
std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/1024                 20880 ns        20444 ns
std::map<std::string, int>::erase(iterator, iterator) (erase half the container)/8192                252881 ns       241583 ns
std::map<std::string, int>::clear()/0                                                                   407 ns          408 ns
std::map<std::string, int>::clear()/32                                                                 1252 ns         1323 ns
std::map<std::string, int>::clear()/1024                                                              38488 ns        38017 ns
std::map<std::string, int>::clear()/8192                                                             416492 ns       428534 ns
std::map<std::string, int>::find(key) (existent)/0                                                    0.008 ns        0.008 ns
std::map<std::string, int>::find(key) (existent)/32                                                    33.9 ns         15.3 ns
std::map<std::string, int>::find(key) (existent)/1024                                                  43.0 ns         25.5 ns
std::map<std::string, int>::find(key) (existent)/8192                                                  44.6 ns         29.3 ns
std::map<std::string, int>::find(key) (non-existent)/0                                                0.259 ns        0.257 ns
std::map<std::string, int>::find(key) (non-existent)/32                                                22.6 ns         11.4 ns
std::map<std::string, int>::find(key) (non-existent)/1024                                              48.6 ns         25.1 ns
std::map<std::string, int>::find(key) (non-existent)/8192                                              64.1 ns         31.1 ns
std::map<std::string, int>::count(key) (existent)/0                                                   0.008 ns        0.008 ns
std::map<std::string, int>::count(key) (existent)/32                                                   32.2 ns         17.3 ns
std::map<std::string, int>::count(key) (existent)/1024                                                 42.4 ns         25.3 ns
std::map<std::string, int>::count(key) (existent)/8192                                                 44.4 ns         31.6 ns
std::map<std::string, int>::count(key) (non-existent)/0                                               0.260 ns        0.259 ns
std::map<std::string, int>::count(key) (non-existent)/32                                               22.9 ns         11.3 ns
std::map<std::string, int>::count(key) (non-existent)/1024                                             49.8 ns         25.5 ns
std::map<std::string, int>::count(key) (non-existent)/8192                                             66.3 ns         31.9 ns
std::map<std::string, int>::contains(key) (existent)/0                                                0.008 ns        0.008 ns
std::map<std::string, int>::contains(key) (existent)/32                                                31.4 ns         18.0 ns
std::map<std::string, int>::contains(key) (existent)/1024                                              44.3 ns         26.5 ns
std::map<std::string, int>::contains(key) (existent)/8192                                              47.4 ns         30.2 ns
std::map<std::string, int>::contains(key) (non-existent)/0                                            0.452 ns        0.441 ns
std::map<std::string, int>::contains(key) (non-existent)/32                                            23.1 ns         11.5 ns
std::map<std::string, int>::contains(key) (non-existent)/1024                                          46.2 ns         26.3 ns
std::map<std::string, int>::contains(key) (non-existent)/8192                                          63.4 ns         31.4 ns
std::map<std::string, int>::lower_bound(key) (existent)/0                                             0.008 ns        0.008 ns
std::map<std::string, int>::lower_bound(key) (existent)/32                                             17.2 ns         19.0 ns
std::map<std::string, int>::lower_bound(key) (existent)/1024                                           27.1 ns         26.2 ns
std::map<std::string, int>::lower_bound(key) (existent)/8192                                           34.0 ns         36.0 ns
std::map<std::string, int>::lower_bound(key) (non-existent)/0                                         0.259 ns        0.257 ns
std::map<std::string, int>::lower_bound(key) (non-existent)/32                                         11.6 ns         11.5 ns
std::map<std::string, int>::lower_bound(key) (non-existent)/1024                                       24.8 ns         25.6 ns
std::map<std::string, int>::lower_bound(key) (non-existent)/8192                                       31.7 ns         31.6 ns
std::map<std::string, int>::upper_bound(key) (existent)/0                                             0.008 ns        0.008 ns
std::map<std::string, int>::upper_bound(key) (existent)/32                                             18.8 ns         19.7 ns
std::map<std::string, int>::upper_bound(key) (existent)/1024                                           25.3 ns         27.7 ns
std::map<std::string, int>::upper_bound(key) (existent)/8192                                           30.2 ns         29.9 ns
std::map<std::string, int>::upper_bound(key) (non-existent)/0                                         0.260 ns        0.259 ns
std::map<std::string, int>::upper_bound(key) (non-existent)/32                                         11.3 ns         12.0 ns
std::map<std::string, int>::upper_bound(key) (non-existent)/1024                                       25.6 ns         25.9 ns
std::map<std::string, int>::upper_bound(key) (non-existent)/8192                                       33.1 ns         34.2 ns
std::map<std::string, int>::equal_range(key) (existent)/0                                             0.008 ns        0.008 ns
std::map<std::string, int>::equal_range(key) (existent)/32                                             33.5 ns         15.8 ns
std::map<std::string, int>::equal_range(key) (existent)/1024                                           43.0 ns         25.1 ns
std::map<std::string, int>::equal_range(key) (existent)/8192                                           54.1 ns         30.7 ns
std::map<std::string, int>::equal_range(key) (non-existent)/0                                         0.265 ns        0.259 ns
std::map<std::string, int>::equal_range(key) (non-existent)/32                                         22.1 ns         12.1 ns
std::map<std::string, int>::equal_range(key) (non-existent)/1024                                       44.8 ns         24.4 ns
std::map<std::string, int>::equal_range(key) (non-existent)/8192                                       62.2 ns         40.1 ns
```

Fixes #66577
2025-09-08 09:56:14 +02:00
Nikolas Klauser
34d4f0c136
[libc++][NFC] Use llvm.org/PR to link to bug reports (#156288)
We've built up quite a few links directly to github within the code
base. We should instead use `llvm.org/PR<issue-number>` to link to bugs,
since that is resilient to the bug tracker changing in the future. This
is especially relevant for tests linking to bugs, since they will
probably be there for decades to come. A nice side effect is that these
links are significantly shorter than the GH links, making them much less
of an eyesore.

This patch also replaces a few links that linked to the old bugzilla
instance on llvm.org.
2025-09-04 09:20:02 +02:00
Nikolas Klauser
74b9484fd6
[libc++] Simplify <tuple> further (#156351)
This essentially inlines `__make_tuple_types` and simplifies the support
code. This significantly simplifies the implementation, since
`__make_tuple_types` has multiple features, but the different places
that use it only make use of a subset of the features. Inlining it
separates concerns better and leads to less code in total.
2025-09-02 08:42:39 +02:00
Nikolas Klauser
8a65c4f11a
[libc++] Disable cv-qualified arithmetic hash specializations (#155786)
#140407 accidentally enabled `hash` for cv-qualified types. This patch
disables these specializations again.
2025-08-29 18:13:26 +02:00
Nikolas Klauser
823e44401a
Reapply "[libc++] Refactor key extraction for __hash_table and __tree (#154512)" (#155565)
The original PR has been reverted because of an LLDB test failure. This
patch now works around the test failure by simply allowing the new
symbols to show up in a stack trace.

This reverts commit 72c04bb882ad70230bce309c3013d9cc2c99e9a7.

Original commit message:

This patch replaces `__can_extract_key` with an overload set to try to
extract the key. This simplifies the code, since we don't need to have
separate overload sets for the unordered and associative containers. It
also allows extending the set of extraction cases more easily, since we
have a single place to define how the key is extracted.
2025-08-27 14:38:14 +02:00
Aiden Grossman
72c04bb882 Revert "[libc++] Refactor key extraction for __hash_table and __tree (#154512)"
This reverts commit af1f06e41b05c267480f1629dc0fcdf18f3b59f6.

This is causing some build failures in premerge as some of the LLDB
tests fail.
2025-08-26 16:13:56 +00:00
Nikolas Klauser
af1f06e41b
[libc++] Refactor key extraction for __hash_table and __tree (#154512)
This patch replaces `__can_extract_key` with an overload set to try to
extract the key. This simplifies the code, since we don't need to have
separate overload sets for the unordered and associative containers. It
also allows extending the set of extraction cases more easily, since we
have a single place to define how the key is extracted.
2025-08-26 16:26:59 +02:00
Nikolas Klauser
6897ca460e
[libc++] Remove unnecessary friend declarations from <__tree> (#152133)
Removing the unnecessary friend declarations from `<__tree>` also
removes the need for forward declaration headers for `map` and `set`,
which this patch also removes.
2025-08-07 09:18:31 +02:00
Nikolas Klauser
091c33b1f5
[libc++] Remove SFINAE on __tuple_impl constructors (#151654)
The SFINAE isn't required, since the primary `tuple` class already does
the SFINAE checks. This removes a bit of code that was only used for
these constraints.

This also moves the `tuple_element` specialization for `tuple` to
`__fwd/tuple.h` to avoid a dependency on `__tuple/sfinae_helpers.h`
(which should be moved in a follow-up).
2025-08-05 09:48:46 +02:00
A. Jiang
a749e68ac4
[libc++][format][NFC] Granularize __fmt_pair_like (#150583)
`<optional>` needs `format_kind` and `range_format` since C++26, but it
shouldn't drag in too many other stuffs necessary for
`<__format/concepts.h>`.
2025-07-29 16:40:06 +08:00
Konstantin Varlamov
d750c6de8a
[libc++][hardening] Add an experimental function to log hardening errors (#149452)
Unlike `verbose_abort`, this function merely logs the error but does not
terminate execution. It is intended to make it possible to implement the
`observe` semantic for Hardening.
2025-07-24 13:39:48 -04:00
Nikolas Klauser
6c257754d9
[libc++] Refactor internal index_sequence API to match the public one (#149475)
The internal API is a lot more complicated than it actually needs to be.
This refactors the internal API to match the features and names of the
public one.
2025-07-20 11:23:31 +02: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
William Tran-Viet
2194bca2b7
[libc++] Granularize range_format and format_kind declarations (#148876)
While working on #105430 I ran into an issue implementing
[[optional.syn]](https://eel.is/c++draft/optional.syn) because of a
circular include that looked like the following: `optional ->
__format/range_default_formatter.h -> __format/range_formatter.h ->
__format/format_context.h -> optional`. Only `format_kind` and
`range_format` are needed, and so they looked like candidates to be put
into an internal header.
2025-07-17 09:43:12 +02:00
enh-google
62bd778fd4
Remove workarounds for NDK versions before 2017's r16. (#148879) 2025-07-16 07:39:17 -04:00
Nikolas Klauser
fda3fbee6f
Revert "[libc++][hardening] Introduce a dylib function to log hardening errors." (#148787)
Reverts llvm/llvm-project#148266

I'm reverting this temporarily, since the release branch is today and
this is ABI sensitive. Let's wait until after the branch so that we have
plenty time to discuss the patch.
2025-07-15 12:12:41 +02:00
Konstantin Varlamov
49d2b5f1cd
[libc++][hardening] Introduce a dylib function to log hardening errors. (#148266)
Unlike `verbose_abort`, this function merely logs the error but does not
terminate execution. It is intended to make it possible to implement the
`observe` semantic for Hardening.
2025-07-14 17:04:33 -07:00
Konstantin Varlamov
5951c44573
[libc++] Introduce the _LIBCPP_VERBOSE_TRAP macro (#148262)
Split out the calls to __builtin_verbose_trap into a separate header.
This is just a refactoring to make the code a bit more structured.
2025-07-14 09:56:19 -04:00
Hui
13f7a1fb59
[libc++] LWG 3987 provide iterator.range access from flat_{map,set} (#137524)
fixes #105309
2025-07-06 12:25:18 +01:00
Hui
9eb4fc7006
[libc++] constexpr flat_set (#140360)
Fixes #128675
2025-07-05 17:38:45 +01:00
Nikolas Klauser
ca697096aa
[libc++] Granularize <locale> (#146650) 2025-07-05 18:11:58 +02:00
Nikolas Klauser
1121d64ba9
[libc++][NFC] Merge add_{r,l}value_reference.h (#147022)
The implementation is now quite simple, so it doesn't make a ton of
sense to have these in separate headers.
2025-07-05 18:11:36 +02:00
Nikolas Klauser
e0864b56b0
[libc++] Fix <charconv> not exporting std::errc (#146268)
`<charconv>` doesn't properly export `std::errc` with locales disabled,
which causes the CI to fail. This fixed the modulemap to let
`from_chars_result` export `std::errc`, like it's supposed to do.
2025-06-30 10:06:34 +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
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
Nikolas Klauser
3c56437eaf
[libc++] Refactor signed/unsigned integer traits (#142750)
This patch does a few things:
- `__libcpp_is_signed_integer` and `__libcpp_is_unsigned_integer` are
refactored to be variable templates instead of class templates.
- the two traits are merged into a single header
`<__type_traits/integer_traits.h>`.
- `__libcpp_signed_integer`, `__libcpp_unsigned_integer` and
`__libcpp_integer` are moved into the same header.
- The above mentioned concepts are renamed to `__signed_integer`,
`__unsigned_integer` and `__signed_or_unsigned_integer` respectively.
2025-06-11 14:31:13 +02: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
Louis Dionne
45d493b680
[libc++] Add the __is_replaceable type trait (#132408)
That type trait represents whether move-assigning an object is
equivalent to destroying it and then move-constructing a new one from
the same argument. This will be useful in a few places where we may want
to destroy + construct instead of doing an assignment, in particular
when implementing some container operations in terms of relocation.

This is effectively adding a library emulation of P2786R12's
is_replaceable trait, similarly to what we do for trivial relocation.
Eventually, we can replace this library emulation by the real
compiler-backed trait.

This is building towards #129328.
2025-05-08 16:35:00 -04:00
Nikolas Klauser
e43e8ec7af
[libc++] Remove dead implementation of is_nothrow_convertible and merge the remaining code into is_convertible.h (#137717)
We can use the `__is_nothrow_convertible` builtin unconditionally now,
which makes the implementation very simple, so there isn't much of a
need to keep a separate header around.
2025-04-29 08:46:06 +02:00
Louis Dionne
860e88411d
[libc++] Make __config_site modular (#134699)
This patch makes the __config_site header modular, which solves various
problems with non-modular headers. This requires going back to
generating the modulemap file, since we only know how to make
__config_site modular when we're not using the per-target runtime dir.

The patch also adds a test that we support
-Wnon-modular-include-in-module, which warns about non-modular includes
from modules.

---------

Co-authored-by: Konstantin Varlamov <varconst@apple.com>
2025-04-18 06:06:25 -07:00
Louis Dionne
6fd27d5b03
[libc++] Don't generate the modulemap file (#80352)
We actually didn't generate anything in that file, so generating it via
CMake is useless.
2024-03-04 18:16:16 -05:00
Nikolas Klauser
33de5a316c
[libc++] Rename __fwd/hash.h to __fwd/functional.h and add reference_wrapper (#81445)
We forward declare `reference_wrapper` in multiple places already. This
moves the declaration to the canonical place and removes unnecessary
includes of `__functional/reference_wrapper.h`.
2024-03-03 20:45:17 +01:00