300 Commits

Author SHA1 Message Date
Hristo Hristov
acc609bc29
[libc++][NFC] Removed an EOL stray white space in Release Notes (#189654) 2026-03-31 17:02:49 +03:00
A. Jiang
2e02135cec
[libc++] Remove non-conforming __bit_reference::operator& (#188714)
The overloaded `operator&` caused non-conforming behavior when
- using `operator==` to compare "addresses" of proxy reference objects,
and
- relying on the exact type of `&ref`.

No deprecation warning is added, becaue it should be portable to write
`&ref` where `ref` is a proxy reference variable, and this patch just
corrects the behavior.

`__bit_const_reference::operator&` is kept, because when one defines
`_LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL` to make the
libc++ implementation strategy conforming, the `operator&` will never be
exposed to users.
2026-03-31 13:45:20 +08:00
Nikhil Kotikalapudi
feae3bc202
[libc++] Remove non-standard member type iterator_type from __wrap_iter (#186871)
Resolves #186801 
Removed the non-standard member type `iterator_type` from `__wrap_iter`.
This member exposed the underlying iterator type, and its removal
prevents users from relying on the implementation detail.
2026-03-25 11:04:14 +08:00
A. Jiang
fe04edc5a0
[libc++] Fix strict aliasing violation for deque::const_iterator (#136067)
When the allocators use fancy pointers, the internal map of `deque`
stores `FancyPtr<T>` objects, and the previous strategy accessed these
objects via `const FancyPtr<const T>` lvalues, which usually caused core
language undefined behavior. Now `const_iterator` stores `FancyPtr<const
FancyPtr<T>>` instead of `FancyPtr<const FancyPtr<const T>>`, and ABI
break can happen when such two types have incompatible layouts.

This is necessary for reducing undefined behavior and `constexpr`
support for `deque` in C++26, and I currently don't want to provide any
way to opt-out of that behavior.

For `iterator`, the current strategy makes it store
`FancyPtr<FancyPtr<T>>`. But it would make more sense to also store
`FancyPtr<const FancyPtr<T>>` because we never modify the map via
`iterator`.

For some pathological combinations of allocators and fancy pointers, the
rebinding trick doesn't work. These cases are rejected by
`static_assert`.

The existing test coverage seems to be sufficient.
2026-03-10 16:00:38 +08:00
Nikolas Klauser
e830ee8006
[libc++] Don't double-wrap iterators when bounded iterators are used (#182264)
There is no reason to double-wrap iterators, since we can already
achieve anything we want within `__bounded_iter`itself.

This is technically ABI breaking, but people using bounded iterators
shouldn't require ABI stability currently.

Fixes #178521
2026-03-07 09:12:25 +01:00
William Tran-Viet
65d378d82d
[libc++] Remove __wrap_iter::base() (#179389)
Resolves #126442

- Converts all the relevant functions that used `.base()` into friends
- Fixed usage in `<regex>`

---------

Co-authored-by: A. Jiang <de34@live.cn>
2026-03-05 20:06:46 +08:00
Louis Dionne
5de92856bd
[libc++] Introduce a escape hatch for the changed behavior of map and set search operations (#183190)
In #155245, we implemented an optimization to std::map and std::set
search operations. That optimization took advantage of something that is
guaranteed by the Standard, namely that the comparator provided to the
associative container is a valid strict weak ordering.

Sadly, some code in the wild did not satisfy this requirement, such as
Boost.ICL: boostorg/icl#51

Since this can have extremely tricky runtime consequences, this patch
introduces a temporary escape hatch for the LLVM 22 release that allows
reverting to the previous behavior. It also explicitly calls out the
change in the release notes, adds some regression tests and adds debug
mode support for catching some of these invalid predicates.

Fixes #183189
2026-02-26 10:22:59 -05:00
Nikolas Klauser
b101f01382
[libc++] Optimize using std::copy with an ostreambuf_iterator (#181815)
```
Benchmark                                                  old             new    Difference    % Difference
----------------------------------------------  --------------  --------------  ------------  --------------
std::copy(CharT*,_CharT*,_ostreambuf_iterator)         8115.45          329.54      -7785.91         -95.94%
```
2026-02-26 12:01:07 +01:00
Hui
d7a24d30f6
[libc++] Implement ranges::shift_right (#177847)
Implement the `ranges::shift_right` algorithm from
[P2440R1](https://wg21.link/P2440R1).

Fixes #134062
Fixes #105184
2026-02-14 17:34:44 +00:00
h-vetinari
d4854177dd
[libc++] Increase the minimum deployment target on macOS to 11.0 (#176094)
#166172 moved the effective minimum deployment target on macOS to 10.15
(because `aligned_alloc` is not defined before that in the C stdlib),
and indeed, it was mentioned in that PR that libc++ only supports macOS
11 and later.

This PR rectifies the documentation and the code to reflect the actually
supported deployment targets on macOS. See [1] for additional discussion
about this.

[1]: https://discourse.llvm.org/t/minimum-macos-deployment-target-increases-to-11-0-in-v22-1-visibility-discussion-on-update-policy
2026-02-13 17:03:41 -05:00
Connector Switch
2d106844e7
[libcxx] Optimize ranges::fold_left_with_iter for segmented iterators (#177853)
Part of https://github.com/llvm/llvm-project/issues/102817.

This patch attempts to optimize the performance of
`ranges::fold_left_with_iter` for segmented iterators.

- before

```
# | rng::fold_left(vector<int>)/8             2.78 ns         2.78 ns    241953718
# | rng::fold_left(vector<int>)/32            12.2 ns         12.2 ns     57579851
# | rng::fold_left(vector<int>)/50            19.2 ns         19.2 ns     36487764
# | rng::fold_left(vector<int>)/8192          3226 ns         3226 ns       216811
# | rng::fold_left(vector<int>)/1048576     441842 ns       441839 ns         1592
# | rng::fold_left(deque<int>)/8              2.83 ns         2.83 ns    243888678
# | rng::fold_left(deque<int>)/32             16.6 ns         16.6 ns     42297458
# | rng::fold_left(deque<int>)/50             22.3 ns         22.3 ns     31387998
# | rng::fold_left(deque<int>)/8192           2492 ns         2492 ns       281637
# | rng::fold_left(deque<int>)/1048576      324936 ns       324936 ns         2154
# | rng::fold_left(list<int>)/8               2.54 ns         2.54 ns    275946635
# | rng::fold_left(list<int>)/32              16.2 ns         16.2 ns     42901634
# | rng::fold_left(list<int>)/50              54.7 ns         54.7 ns     12767450
# | rng::fold_left(list<int>)/8192           15154 ns        15154 ns        56744
# | rng::fold_left(list<int>)/1048576      4976906 ns      4976867 ns          158
```

- after

```
# | rng::fold_left(vector<int>)/8             2.74 ns         2.74 ns    255954900
# | rng::fold_left(vector<int>)/32            12.1 ns         12.1 ns     57843462
# | rng::fold_left(vector<int>)/50            19.2 ns         19.2 ns     36422594
# | rng::fold_left(vector<int>)/8192          3202 ns         3202 ns       218265
# | rng::fold_left(vector<int>)/1048576     435718 ns       435709 ns         1609
# | rng::fold_left(deque<int>)/8              2.52 ns         2.52 ns    277288254
# | rng::fold_left(deque<int>)/32             14.1 ns         14.1 ns     52244463
# | rng::fold_left(deque<int>)/50             16.2 ns         16.2 ns     43131857
# | rng::fold_left(deque<int>)/8192           1695 ns         1695 ns       415620
# | rng::fold_left(deque<int>)/1048576      277729 ns       277731 ns         2532
# | rng::fold_left(list<int>)/8               2.55 ns         2.55 ns    277025050
# | rng::fold_left(list<int>)/32              16.2 ns         16.2 ns     43058857
# | rng::fold_left(list<int>)/50              54.7 ns         54.7 ns     12705516
# | rng::fold_left(list<int>)/8192           15236 ns        15235 ns        56840
# | rng::fold_left(list<int>)/1048576      4827263 ns      4827147 ns          152
```
2026-02-05 21:12:36 +08:00
sohail
9bde15d76d
[libc++] Deprecate std::launch::any extension (#173397)
`std::launch::any` was a draft C++11 feature that was removed before the
final standard but it has remained in libc++ as an extension. This patch
marks it as deprecated and suggests using `std::launch::async |
std::launch::deferred` instead.

- Used `_LIBCPP_DEPRECATED_` to mark `std::launch::any` as deprecated
with an associated warning message recommending `std::launch::async |
std::launch::deferred` instead.
- Added a `.verify.cpp` test to validate the deprecation warning.
- Updated existing tests to avoid using the deprecated extension.
- Added note about deprecation in docs.

Fixes #173219

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2026-01-30 13:51:52 +08:00
xiaoyang-sde
9311996261
[libc++][ranges] implement ranges::shift_left (#83231)
Implement the `ranges::shift_left` algorithm from
[P2440R1](https://wg21.link/P2440R1).

Closes: #134061

---------

Co-authored-by: Hui Xie <hui.xie1990@gmail.com>
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2026-01-25 10:35:43 +00:00
Hui
985d75a57a
[libc++] define FTM __cpp_lib_ranges_zip (#176569)
P2321R2 has been implemented in various PRs. Based on the discussion
in #105169, the last bit in iterator.concept.winc doesn't require
any changes, so we can actually mark this as done.

Fixes #105169
2026-01-19 15:18:57 -05:00
Louis Dionne
ec983ad611
[runtimes] Post-branch tasks for the LLVM 23 release (#176007)
This performs most of the post-branch tasks to start working on the LLVM
23 release. Things that are left to do:
- Update the unicode version
- Update CI versions and supported compiler versions
2026-01-14 18:39:02 +00:00
Nikolas Klauser
89c8a253d7
[libc++] Make optional::iterator experimental (#173470)
We haven't yet decided what we want the `optional::iterator` type to be
in the end, so let's make it experimental for now so that we don't
commit to an ABI yet.
2026-01-09 10:21:48 -05:00
Nikolas Klauser
b6bfb199cc
[libc++] Fix {deque,vector}::append_range assuming too much about the types (#162438)
Currently, `deque` and `vector`'s `append_range` is implemented in terms
of `insert_range`. The problem with that is that `insert_range` has more
preconditions, resulting in us rejecting valid code.

This also significantly improves performance for `deque` in some cases.
2026-01-09 12:06:43 +01:00
Nikolas Klauser
9a8421fa61
[libc++] Update our release notes for the upcoming release (#174625) 2026-01-08 13:26:04 +01:00
Nikolas Klauser
06c6a5020f
[libc++] Optimize search_n (#171389)
This changes the algorithm to more efficiently skip ranges which cannot
match the needle for random access iterators. Specifically, we now
search for a mismatching element from the back of the subrange we want
to check. When a mismatch occurs we can directly start one after the
mismatched element, since there cannot possibly be a matching subrange
starting between the start of the subrange we checked and the mismatched
element (since all elements have to be equal). The algorithm also
remembers the subrange which was already match as being equal and
doesn't try to compare it a second time, reducing the time spent in case
of a match.

```
Benchmark                                                       old             new    Difference    % Difference
---------------------------------------------------  --------------  --------------  ------------  --------------
rng::search_n(deque<int>)_(no_match)/1000                    458.33           14.22       -444.11         -96.90%
rng::search_n(deque<int>)_(no_match)/1024                    456.17           13.89       -442.28         -96.95%
rng::search_n(deque<int>)_(no_match)/1048576              453420.38           17.69    -453402.69        -100.00%
rng::search_n(deque<int>)_(no_match)/8192                   3566.08           17.60      -3548.49         -99.51%
rng::search_n(deque<int>,_pred)_(no_match)/1000              597.88           15.25       -582.63         -97.45%
rng::search_n(deque<int>,_pred)_(no_match)/1024              608.42           15.39       -593.03         -97.47%
rng::search_n(deque<int>,_pred)_(no_match)/1048576        594533.99           18.91    -594515.08        -100.00%
rng::search_n(deque<int>,_pred)_(no_match)/8192             4670.23           18.88      -4651.35         -99.60%
rng::search_n(list<int>)_(no_match)/1000                     733.72          730.22         -3.50          -0.48%
rng::search_n(list<int>)_(no_match)/1024                     759.93          753.10         -6.84          -0.90%
rng::search_n(list<int>)_(no_match)/1048576               833841.54       813483.75     -20357.79          -2.44%
rng::search_n(list<int>)_(no_match)/8192                    8352.18         8417.31         65.14           0.78%
rng::search_n(list<int>,_pred)_(no_match)/1000               776.79          789.72         12.93           1.66%
rng::search_n(list<int>,_pred)_(no_match)/1024               788.42          806.70         18.28           2.32%
rng::search_n(list<int>,_pred)_(no_match)/1048576         955536.40       982976.81      27440.41           2.87%
rng::search_n(list<int>,_pred)_(no_match)/8192              8874.02         8915.18         41.16           0.46%
rng::search_n(vector<int>)_(no_match)/1000                   212.69            3.79       -208.90         -98.22%
rng::search_n(vector<int>)_(no_match)/1024                   219.67            3.70       -215.96         -98.31%
rng::search_n(vector<int>)_(no_match)/1048576             209622.54            3.67    -209618.87        -100.00%
rng::search_n(vector<int>)_(no_match)/8192                  1643.80            3.83      -1639.98         -99.77%
rng::search_n(vector<int>,_pred)_(no_match)/1000             461.93            7.55       -454.38         -98.36%
rng::search_n(vector<int>,_pred)_(no_match)/1024             472.43            7.74       -464.69         -98.36%
rng::search_n(vector<int>,_pred)_(no_match)/1048576       546180.29            8.71    -546171.58        -100.00%
rng::search_n(vector<int>,_pred)_(no_match)/8192            3786.26            7.88      -3778.38         -99.79%
std::search_n(deque<int>)_(no_match)/1000                    455.53           14.19       -441.34         -96.88%
std::search_n(deque<int>)_(no_match)/1024                    459.79           13.98       -445.81         -96.96%
std::search_n(deque<int>)_(no_match)/1048576              449780.32           17.99    -449762.33        -100.00%
std::search_n(deque<int>)_(no_match)/8192                   3508.55           17.97      -3490.58         -99.49%
std::search_n(deque<int>,_pred)_(no_match)/1000              571.53           17.16       -554.37         -97.00%
std::search_n(deque<int>,_pred)_(no_match)/1024              584.43           17.09       -567.34         -97.08%
std::search_n(deque<int>,_pred)_(no_match)/1048576        581418.31           19.16    -581399.15        -100.00%
std::search_n(deque<int>,_pred)_(no_match)/8192             4661.97           19.36      -4642.61         -99.58%
std::search_n(list<int>)_(no_match)/1000                     722.45          710.39        -12.06          -1.67%
std::search_n(list<int>)_(no_match)/1024                     748.50          727.08        -21.42          -2.86%
std::search_n(list<int>)_(no_match)/1048576               821655.28       784520.12     -37135.16          -4.52%
std::search_n(list<int>)_(no_match)/8192                    7941.73         8002.05         60.32           0.76%
std::search_n(list<int>,_pred)_(no_match)/1000               766.59          786.31         19.72           2.57%
std::search_n(list<int>,_pred)_(no_match)/1024               785.92          804.43         18.51           2.35%
std::search_n(list<int>,_pred)_(no_match)/1048576         948252.76       969125.41      20872.65           2.20%
std::search_n(list<int>,_pred)_(no_match)/8192              8658.99         8825.71        166.72           1.93%
std::search_n(vector<int>)_(no_match)/1000                   210.36            3.47       -206.89         -98.35%
std::search_n(vector<int>)_(no_match)/1024                   217.60            4.13       -213.47         -98.10%
std::search_n(vector<int>)_(no_match)/1048576             209386.43            3.51    -209382.92        -100.00%
std::search_n(vector<int>)_(no_match)/8192                  1643.79            3.50      -1640.29         -99.79%
std::search_n(vector<int>,_pred)_(no_match)/1000             460.88            5.44       -455.45         -98.82%
std::search_n(vector<int>,_pred)_(no_match)/1024             475.36            5.43       -469.93         -98.86%
std::search_n(vector<int>,_pred)_(no_match)/1048576       682722.75            7.15    -682715.60        -100.00%
std::search_n(vector<int>,_pred)_(no_match)/8192            3779.95            5.43      -3774.52         -99.86%
Geomean                                                     4956.15           87.96      -4868.19         -98.23%
```

Fixes #129327
2026-01-08 11:26:08 +01:00
Rafail Shakhin ogly
ec7b63771c
[libc++][chrono] P2592R3: Hashing for chrono (#165132) 2026-01-03 10:32:14 +08:00
Matthias Wippich
617b446176
[libc++] Implement P1789R3: Library Support for Expansion Statements (#167184)
[P1789R3](https://isocpp.org/files/papers/P1789R3.pdf) was accepted for
C++26 through LWG motion 14 at the 2025 Kona meeting. This patch
implements it, along with tests and documentation changes.

Closes #167268

---------

Co-authored-by: Tsche <che@pydong.org>
2025-12-26 09:07:13 +08:00
Hristo Hristov
94c014a5fd
[libc++][NFC] Fixed formatting in Release Notes (#173526) 2025-12-25 11:37:00 +02:00
William Tran-Viet
4c9d1bdf94
[libc++] Implement P3836R2: Make optional<T&> trivially copyable (#171528)
Resolves #171275

- `*_assign_base` base class trivial overloads needed to be updated to
allow references.
- Add tests
- Update release notes
2025-12-24 15:44:32 +08:00
Nikolas Klauser
79a88949cd
[libc++] Optimize rotate (#120890)
This implements a new algorithm for `rotate` with random access
iterators, which uses `swap_ranges`. This reduces cache misses and
allows for vectorization.

Apple M4:
```
Benchmark                                                       old             new    Difference    % Difference
---------------------------------------------------  --------------  --------------  ------------  --------------
rng::rotate(deque<int>)_(1_element_backward)/1024             46.17           45.13         -1.04          -2.26%
rng::rotate(deque<int>)_(1_element_backward)/32                4.90            4.92          0.02           0.45%
rng::rotate(deque<int>)_(1_element_backward)/50                6.12            6.02         -0.10          -1.56%
rng::rotate(deque<int>)_(1_element_backward)/8192            329.97          330.49          0.52           0.16%
rng::rotate(deque<int>)_(1_element_forward)/1024              42.20           42.99          0.79           1.87%
rng::rotate(deque<int>)_(1_element_forward)/32                 4.99            5.26          0.27           5.37%
rng::rotate(deque<int>)_(1_element_forward)/50                 6.33            6.48          0.14           2.28%
rng::rotate(deque<int>)_(1_element_forward)/8192             317.40          318.68          1.28           0.40%
rng::rotate(deque<int>)_(by_1/2)/1024                        185.42          184.23         -1.18          -0.64%
rng::rotate(deque<int>)_(by_1/2)/32                            8.72            8.99          0.27           3.14%
rng::rotate(deque<int>)_(by_1/2)/50                           12.03           11.60         -0.43          -3.59%
rng::rotate(deque<int>)_(by_1/2)/8192                       1549.94         1549.30         -0.64          -0.04%
rng::rotate(deque<int>)_(by_1/3)/1024                       1886.50          409.41      -1477.09         -78.30%
rng::rotate(deque<int>)_(by_1/3)/32                           46.51           21.68        -24.84         -53.40%
rng::rotate(deque<int>)_(by_1/3)/50                           77.70           29.85        -47.85         -61.58%
rng::rotate(deque<int>)_(by_1/3)/8192                      22814.91         3171.92     -19642.99         -86.10%
rng::rotate(deque<int>)_(by_1/4)/1024                        811.39          283.28       -528.11         -65.09%
rng::rotate(deque<int>)_(by_1/4)/32                           30.30           14.44        -15.86         -52.35%
rng::rotate(deque<int>)_(by_1/4)/50                           76.23           29.29        -46.94         -61.58%
rng::rotate(deque<int>)_(by_1/4)/8192                       7154.50         2357.48      -4797.02         -67.05%
rng::rotate(list<int>)_(1_element_backward)/1024            1483.46          742.31       -741.15         -49.96%
rng::rotate(list<int>)_(1_element_backward)/32                16.17           16.37          0.20           1.24%
rng::rotate(list<int>)_(1_element_backward)/50                29.31           29.20         -0.10          -0.34%
rng::rotate(list<int>)_(1_element_backward)/8192            8896.07         8949.56         53.49           0.60%
rng::rotate(list<int>)_(1_element_forward)/1024             1481.36          742.24       -739.12         -49.89%
rng::rotate(list<int>)_(1_element_forward)/32                 15.72           16.22          0.50           3.19%
rng::rotate(list<int>)_(1_element_forward)/50                 28.91           28.87         -0.03          -0.12%
rng::rotate(list<int>)_(1_element_forward)/8192             9595.63         9846.80        251.16           2.62%
rng::rotate(list<int>)_(by_1/2)/1024                         833.67          408.22       -425.46         -51.03%
rng::rotate(list<int>)_(by_1/2)/32                             8.88            8.76         -0.11          -1.25%
rng::rotate(list<int>)_(by_1/2)/50                            15.67           15.73          0.06           0.40%
rng::rotate(list<int>)_(by_1/2)/8192                        6392.01         6597.30        205.30           3.21%
rng::rotate(list<int>)_(by_1/3)/1024                        1360.66          872.00       -488.66         -35.91%
rng::rotate(list<int>)_(by_1/3)/32                            19.72           19.37         -0.35          -1.80%
rng::rotate(list<int>)_(by_1/3)/50                            33.15           33.12         -0.04          -0.12%
rng::rotate(list<int>)_(by_1/3)/8192                       10807.14        11216.71        409.58           3.79%
rng::rotate(list<int>)_(by_1/4)/1024                         624.92          625.80          0.88           0.14%
rng::rotate(list<int>)_(by_1/4)/32                            15.28           15.37          0.09           0.60%
rng::rotate(list<int>)_(by_1/4)/50                            32.27           32.78          0.52           1.60%
rng::rotate(list<int>)_(by_1/4)/8192                       11266.66         9594.79      -1671.87         -14.84%
rng::rotate(vector<bool>)_(1_element_backward)/1024           32.10           31.94         -0.16          -0.51%
rng::rotate(vector<bool>)_(1_element_backward)/32             18.48           18.07         -0.41          -2.21%
rng::rotate(vector<bool>)_(1_element_backward)/50             18.49           18.19         -0.30          -1.64%
rng::rotate(vector<bool>)_(1_element_backward)/8192          113.76          112.91         -0.85          -0.75%
rng::rotate(vector<bool>)_(1_element_forward)/1024            30.87           30.72         -0.15          -0.48%
rng::rotate(vector<bool>)_(1_element_forward)/32              18.16           17.98         -0.18          -1.01%
rng::rotate(vector<bool>)_(1_element_forward)/50              17.98           17.98          0.01           0.03%
rng::rotate(vector<bool>)_(1_element_forward)/8192           111.84          111.50         -0.34          -0.31%
rng::rotate(vector<bool>)_(by_1/2)/1024                        9.27            9.34          0.07           0.75%
rng::rotate(vector<bool>)_(by_1/2)/32                         18.32           17.90         -0.42          -2.29%
rng::rotate(vector<bool>)_(by_1/2)/50                         18.14           17.69         -0.45          -2.49%
rng::rotate(vector<bool>)_(by_1/2)/8192                       16.23           16.80          0.57           3.49%
rng::rotate(vector<bool>)_(by_1/3)/1024                       58.89           58.74         -0.15          -0.25%
rng::rotate(vector<bool>)_(by_1/3)/32                         18.16           17.74         -0.41          -2.28%
rng::rotate(vector<bool>)_(by_1/3)/50                         18.15           17.72         -0.43          -2.38%
rng::rotate(vector<bool>)_(by_1/3)/8192                      164.52          166.17          1.65           1.00%
rng::rotate(vector<bool>)_(by_1/4)/1024                       13.44           14.20          0.76           5.65%
rng::rotate(vector<bool>)_(by_1/4)/32                         18.38           17.86         -0.52          -2.84%
rng::rotate(vector<bool>)_(by_1/4)/50                         18.26           17.75         -0.51          -2.79%
rng::rotate(vector<bool>)_(by_1/4)/8192                       34.49           34.59          0.11           0.31%
rng::rotate(vector<int>)_(1_element_backward)/1024            37.22           37.55          0.33           0.88%
rng::rotate(vector<int>)_(1_element_backward)/32               3.02            3.01         -0.00          -0.10%
rng::rotate(vector<int>)_(1_element_backward)/50               5.31            5.33          0.02           0.31%
rng::rotate(vector<int>)_(1_element_backward)/8192           302.96          295.02         -7.94          -2.62%
rng::rotate(vector<int>)_(1_element_forward)/1024             36.78           36.97          0.19           0.51%
rng::rotate(vector<int>)_(1_element_forward)/32                3.08            3.19          0.11           3.56%
rng::rotate(vector<int>)_(1_element_forward)/50                5.33            5.33         -0.00          -0.05%
rng::rotate(vector<int>)_(1_element_forward)/8192            288.25          285.28         -2.97          -1.03%
rng::rotate(vector<int>)_(by_1/2)/1024                        32.49           32.13         -0.36          -1.10%
rng::rotate(vector<int>)_(by_1/2)/32                           3.80            2.63         -1.17         -30.82%
rng::rotate(vector<int>)_(by_1/2)/50                           5.29            3.69         -1.59         -30.13%
rng::rotate(vector<int>)_(by_1/2)/8192                       256.13          252.05         -4.07          -1.59%
rng::rotate(vector<int>)_(by_1/3)/1024                      1389.57          135.85      -1253.72         -90.22%
rng::rotate(vector<int>)_(by_1/3)/32                          21.73           11.99         -9.73         -44.80%
rng::rotate(vector<int>)_(by_1/3)/50                          40.23           11.88        -28.35         -70.48%
rng::rotate(vector<int>)_(by_1/3)/8192                     11040.23          946.51     -10093.72         -91.43%
rng::rotate(vector<int>)_(by_1/4)/1024                       335.13           49.05       -286.08         -85.36%
rng::rotate(vector<int>)_(by_1/4)/32                          12.32            6.06         -6.26         -50.83%
rng::rotate(vector<int>)_(by_1/4)/50                          40.54           12.54        -28.00         -69.07%
rng::rotate(vector<int>)_(by_1/4)/8192                      2648.84          391.91      -2256.93         -85.20%
std::rotate(deque<int>)_(1_element_backward)/1024             45.81           45.88          0.08           0.16%
std::rotate(deque<int>)_(1_element_backward)/32                4.81            4.85          0.04           0.76%
std::rotate(deque<int>)_(1_element_backward)/50                6.11            6.10         -0.01          -0.13%
std::rotate(deque<int>)_(1_element_backward)/8192            329.99          330.63          0.64           0.19%
std::rotate(deque<int>)_(1_element_forward)/1024              42.45           42.21         -0.24          -0.57%
std::rotate(deque<int>)_(1_element_forward)/32                 5.03            5.14          0.11           2.23%
std::rotate(deque<int>)_(1_element_forward)/50                 5.96            6.04          0.09           1.43%
std::rotate(deque<int>)_(1_element_forward)/8192             316.09          317.73          1.64           0.52%
std::rotate(deque<int>)_(by_1/2)/1024                        185.34          185.41          0.07           0.04%
std::rotate(deque<int>)_(by_1/2)/32                            8.08            8.57          0.49           6.01%
std::rotate(deque<int>)_(by_1/2)/50                           11.13           11.61          0.48           4.35%
std::rotate(deque<int>)_(by_1/2)/8192                       1549.74         1527.97        -21.77          -1.40%
std::rotate(deque<int>)_(by_1/3)/1024                       1837.15          410.26      -1426.89         -77.67%
std::rotate(deque<int>)_(by_1/3)/32                           46.73           22.85        -23.88         -51.11%
std::rotate(deque<int>)_(by_1/3)/50                           78.05           29.61        -48.43         -62.06%
std::rotate(deque<int>)_(by_1/3)/8192                      22784.08         3174.02     -19610.06         -86.07%
std::rotate(deque<int>)_(by_1/4)/1024                        874.13          282.91       -591.22         -67.64%
std::rotate(deque<int>)_(by_1/4)/32                           31.14           14.31        -16.83         -54.05%
std::rotate(deque<int>)_(by_1/4)/50                           77.39           28.67        -48.72         -62.96%
std::rotate(deque<int>)_(by_1/4)/8192                       7207.73         2344.73      -4863.00         -67.47%
std::rotate(list<int>)_(1_element_backward)/1024            1490.45          745.80       -744.65         -49.96%
std::rotate(list<int>)_(1_element_backward)/32                16.15           16.43          0.28           1.71%
std::rotate(list<int>)_(1_element_backward)/50                29.28           29.29          0.01           0.02%
std::rotate(list<int>)_(1_element_backward)/8192            9305.23        10372.35       1067.13          11.47%
std::rotate(list<int>)_(1_element_forward)/1024             1479.13          743.71       -735.42         -49.72%
std::rotate(list<int>)_(1_element_forward)/32                 15.86           16.21          0.35           2.20%
std::rotate(list<int>)_(1_element_forward)/50                 28.91           28.90         -0.01          -0.04%
std::rotate(list<int>)_(1_element_forward)/8192             9796.34         8826.58       -969.76          -9.90%
std::rotate(list<int>)_(by_1/2)/1024                         851.06          411.44       -439.61         -51.66%
std::rotate(list<int>)_(by_1/2)/32                             8.90            8.80         -0.10          -1.10%
std::rotate(list<int>)_(by_1/2)/50                            15.69           15.69          0.00           0.02%
std::rotate(list<int>)_(by_1/2)/8192                        6479.34         6599.58        120.24           1.86%
std::rotate(list<int>)_(by_1/3)/1024                         865.82          877.81         11.99           1.38%
std::rotate(list<int>)_(by_1/3)/32                            19.52           19.44         -0.09          -0.44%
std::rotate(list<int>)_(by_1/3)/50                            33.67           33.14         -0.53          -1.59%
std::rotate(list<int>)_(by_1/3)/8192                       10513.57        10355.02       -158.55          -1.51%
std::rotate(list<int>)_(by_1/4)/1024                         639.35          655.30         15.95           2.49%
std::rotate(list<int>)_(by_1/4)/32                            15.22           15.45          0.24           1.55%
std::rotate(list<int>)_(by_1/4)/50                            32.51           32.93          0.42           1.29%
std::rotate(list<int>)_(by_1/4)/8192                        9883.06         9284.28       -598.79          -6.06%
std::rotate(vector<bool>)_(1_element_backward)/1024           30.77           30.95          0.18           0.58%
std::rotate(vector<bool>)_(1_element_backward)/32             17.73           17.57         -0.16          -0.89%
std::rotate(vector<bool>)_(1_element_backward)/50             17.74           17.58         -0.16          -0.91%
std::rotate(vector<bool>)_(1_element_backward)/8192          111.37          111.04         -0.33          -0.29%
std::rotate(vector<bool>)_(1_element_forward)/1024            30.16           29.92         -0.24          -0.81%
std::rotate(vector<bool>)_(1_element_forward)/32              17.22           17.38          0.16           0.94%
std::rotate(vector<bool>)_(1_element_forward)/50              17.22           17.36          0.14           0.83%
std::rotate(vector<bool>)_(1_element_forward)/8192           111.28          111.19         -0.09          -0.08%
std::rotate(vector<bool>)_(by_1/2)/1024                        9.20            9.65          0.46           4.96%
std::rotate(vector<bool>)_(by_1/2)/32                         17.23           17.12         -0.11          -0.62%
std::rotate(vector<bool>)_(by_1/2)/50                         17.18           17.04         -0.14          -0.82%
std::rotate(vector<bool>)_(by_1/2)/8192                       15.93           16.92          0.99           6.22%
std::rotate(vector<bool>)_(by_1/3)/1024                       57.99           58.05          0.06           0.10%
std::rotate(vector<bool>)_(by_1/3)/32                         17.14           17.06         -0.08          -0.47%
std::rotate(vector<bool>)_(by_1/3)/50                         17.09           16.95         -0.15          -0.87%
std::rotate(vector<bool>)_(by_1/3)/8192                      164.14          165.70          1.56           0.95%
std::rotate(vector<bool>)_(by_1/4)/1024                       14.00           14.21          0.21           1.49%
std::rotate(vector<bool>)_(by_1/4)/32                         17.20           17.20         -0.00          -0.00%
std::rotate(vector<bool>)_(by_1/4)/50                         17.09           17.10          0.01           0.08%
std::rotate(vector<bool>)_(by_1/4)/8192                       33.90           34.16          0.26           0.76%
std::rotate(vector<int>)_(1_element_backward)/1024            37.04           37.54          0.50           1.35%
std::rotate(vector<int>)_(1_element_backward)/32               3.01            3.01          0.00           0.04%
std::rotate(vector<int>)_(1_element_backward)/50               5.30            4.96         -0.34          -6.44%
std::rotate(vector<int>)_(1_element_backward)/8192           302.63          286.92        -15.71          -5.19%
std::rotate(vector<int>)_(1_element_forward)/1024             36.83           36.88          0.05           0.15%
std::rotate(vector<int>)_(1_element_forward)/32                3.08            3.06         -0.02          -0.56%
std::rotate(vector<int>)_(1_element_forward)/50                5.34            5.07         -0.26          -4.95%
std::rotate(vector<int>)_(1_element_forward)/8192            283.85          284.99          1.14           0.40%
std::rotate(vector<int>)_(by_1/2)/1024                        32.12           32.19          0.06           0.20%
std::rotate(vector<int>)_(by_1/2)/32                           3.83            2.22         -1.61         -42.16%
std::rotate(vector<int>)_(by_1/2)/50                           4.28            4.38          0.09           2.19%
std::rotate(vector<int>)_(by_1/2)/8192                       256.28          252.63         -3.65          -1.42%
std::rotate(vector<int>)_(by_1/3)/1024                      1386.79          142.76      -1244.03         -89.71%
std::rotate(vector<int>)_(by_1/3)/32                          21.76           11.54        -10.22         -46.98%
std::rotate(vector<int>)_(by_1/3)/50                          40.30           11.79        -28.51         -70.74%
std::rotate(vector<int>)_(by_1/3)/8192                     11017.09          949.95     -10067.14         -91.38%
std::rotate(vector<int>)_(by_1/4)/1024                       335.51           48.69       -286.83         -85.49%
std::rotate(vector<int>)_(by_1/4)/32                          12.31            6.09         -6.22         -50.51%
std::rotate(vector<int>)_(by_1/4)/50                          40.82           13.03        -27.79         -68.07%
std::rotate(vector<int>)_(by_1/4)/8192                      2647.90          392.58      -2255.32         -85.17%
Geomean                                                       76.74           56.58        -20.16         -26.27%
```

Fixes #54949
2025-12-23 10:18:43 +01:00
Hui
fc4661aa11
[libc++] Implement adjacent_transform (#168208)
This patch implements std::ranges::adjacent_transform_view. This is part
of P2321R2 tracked
by #105169.
2025-12-21 09:08:09 +00:00
Hui
cd13170aea
[libc++] Implement P3567R2 flat_meow fixes (#162022)
Fixes #171272

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-12-20 21:18:44 +00:00
Janet Cobb
ef190061d3
[libc++][concepts] P2404R3: Move-only types for equality_comparable_with, totally_ordered_with, and three_way_comparable_with (#99420)
This implements all of [P2404R3](https://wg21.link/p2404r3)'s concept
changes.

---------

Co-authored-by: A. Jiang <de34@live.cn>
Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-12-19 17:56:32 +08:00
saipubw
1c06165c9b
[libc++] Make std::align an inline function (#167472)
`std::align` is heavily used in memory allocators. When we attempted to
switch from libstdc++ to libc++, we observed a **50%** performance
regression in a database query bench: the issue is that `std::align` in
libc++ is not an inline function, which prevents the compiler from
performing inlining optimizations.

make `std::align` an inline function will run about 2x faster. See
[benchmark
result](https://quick-bench.com/q/wPTnt9JCGn2S-3bu5gY9YrEf6KU).

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-12-18 17:55:28 +08:00
Hui
1e15dbe311
[libc++] Implement adjacent_view (#165089) 2025-12-13 19:33:32 +00:00
Nikolas Klauser
a34a92d9e2
[libc++] Always return bool from bitset::operator[](size_t) const (#169894)
This takes an ABI break unconditionally, since it's small enough that
nobody should be affected. This both simplifies `bitset` a bit and makes
us more conforming.
2025-12-12 09:06:50 +01:00
Nikolas Klauser
4fc5b6d8c4
[libc++] Optimize {std,ranges}::for_each for iterating over __trees (#164405)
This patch optimizes how `for_each` iterates over trees by using
recursion and storing pointers to the next nodes on the stack. This
avoids pointer chasing through the `__parent_` pointer, reducing cache
misses. It also makes use of the compiler being able tail-call optimize
the recursive function, removing back-tracking the iterators have to do.

```
Benchmark                                                      old             new    Difference    % Difference
--------------------------------------------------  --------------  --------------  ------------  --------------
rng::for_each(map<int>)/32                                   35.19           26.67         -8.52         -24.21%
rng::for_each(map<int>)/50                                   64.13           40.68        -23.45         -36.57%
rng::for_each(map<int>)/8                                     5.06            6.49          1.43          28.21%
rng::for_each(map<int>)/8192                              22893.89         9266.68     -13627.21         -59.52%
rng::for_each(map<int>::iterator)/32                         35.51           26.88         -8.63         -24.31%
rng::for_each(map<int>::iterator)/50                         64.39           41.24        -23.15         -35.95%
rng::for_each(map<int>::iterator)/8                           5.12            5.93          0.81          15.80%
rng::for_each(map<int>::iterator)/8192                    21283.14         9736.83     -11546.31         -54.25%
rng::for_each(multimap<int>)/32                              35.22           26.61         -8.61         -24.45%
rng::for_each(multimap<int>)/50                              64.10           40.07        -24.03         -37.49%
rng::for_each(multimap<int>)/8                                5.08            6.69          1.61          31.70%
rng::for_each(multimap<int>)/8192                         23130.44         9026.16     -14104.28         -60.98%
rng::for_each(multimap<int>::iterator)/32                    35.40           25.08        -10.32         -29.15%
rng::for_each(multimap<int>::iterator)/50                    64.19           38.15        -26.04         -40.56%
rng::for_each(multimap<int>::iterator)/8                      5.04            5.25          0.22           4.31%
rng::for_each(multimap<int>::iterator)/8192               22875.97         9392.08     -13483.89         -58.94%
rng::for_each(multiset<int>)/32                              35.82           27.11         -8.72         -24.33%
rng::for_each(multiset<int>)/50                              62.92           41.59        -21.32         -33.89%
rng::for_each(multiset<int>)/8                                4.79            6.79          2.00          41.70%
rng::for_each(multiset<int>)/8192                         22642.68         9280.95     -13361.73         -59.01%
rng::for_each(multiset<int>::iterator)/32                    35.76           26.71         -9.04         -25.28%
rng::for_each(multiset<int>::iterator)/50                    63.44           39.00        -24.44         -38.53%
rng::for_each(multiset<int>::iterator)/8                      4.90            5.21          0.30           6.18%
rng::for_each(multiset<int>::iterator)/8192               19930.45         9867.60     -10062.85         -50.49%
rng::for_each(set<int>)/32                                   35.90           27.30         -8.60         -23.96%
rng::for_each(set<int>)/50                                   63.15           40.75        -22.40         -35.47%
rng::for_each(set<int>)/8                                     4.77            6.83          2.06          43.23%
rng::for_each(set<int>)/8192                              20262.77         9381.57     -10881.20         -53.70%
rng::for_each(set<int>::iterator)/32                         36.02           26.42         -9.60         -26.64%
rng::for_each(set<int>::iterator)/50                         63.29           37.97        -25.32         -40.01%
rng::for_each(set<int>::iterator)/8                           4.72            5.22          0.50          10.50%
rng::for_each(set<int>::iterator)/8192                    20041.91         9831.91     -10210.00         -50.94%
```
2025-12-12 09:05:51 +01:00
Nikolas Klauser
df6c27e752
[libc++] Make std::allocator always trivially default constructible (#169914)
This is technically ABI breaking, since `is_trivial` and
`is_trivially_default_constructible` now return different results.
However, I don't think that's a significant issue, since `allocator` is
almost always used in classes which own memory, making them non-trivial
anyways.
2025-12-11 10:27:43 +01:00
Nikolas Klauser
c567e28a9d
[libc++] Optimize vector<bool>::reserve (#170137)
Apple M4:
```
Benchmark                                                                      old        new    Difference    % Difference
--------------------------------------------------------------------------  ------  ----------  ------------  --------------
vector<bool>(const_vector<bool>&)                                            12.73       12.87          0.14           1.07%
vector<bool>(size_type,_const_value_type&)                                    9.39        9.41          0.02           0.22%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(different_allocators)   16.87       15.22         -1.65          -9.80%
vector<bool>(vector<bool>&&,_const_allocator_type&)_(equal_allocators)        2.68        2.73          0.05           1.90%
vector<bool>::reserve()                                                      11.81        9.43         -2.38         -20.14%
Geomean                                                                       9.14        8.62         -0.53          -5.76%
```
2025-12-10 10:18:59 +01:00
Hui
73a13839d3
[libc++] Allows any types of size 4 and 8 to use native platform ulock_wait (#161086)
This is to address #146145

The issue before was that, for `std::atomic::wait/notify`, we only
support `uint64_t` to go through the native `ulock_wait` directly. Any
other types will go through the global contention table's `atomic`,
increasing the chances of spurious wakeup. This PR tries to allow any
types that are of size 4 or 8 to directly go to the `ulock_wait`.

This PR is just proof of concept. If we like this idea, I can go further
to update the Linux/FreeBSD branch and add ABI macros so the existing
behaviours are reserved under the stable ABI

Here are some benchmark results

```
Benchmark                                                               Time             CPU      Time Old      Time New       CPU Old       CPU New
----------------------------------------------------------------------------------------------------------------------------------------------------
BM_stop_token_single_thread_reg_unreg_callback/1024                  -0.1113         -0.1165         51519         45785         51397         45408
BM_stop_token_single_thread_reg_unreg_callback/4096                  -0.2727         -0.1447        249685        181608        211865        181203
BM_stop_token_single_thread_reg_unreg_callback/65536                 -0.1241         -0.1237       3308930       2898396       3300986       2892608
BM_stop_token_single_thread_reg_unreg_callback/262144                +0.0335         -0.1920      13237682      13681632      13208849      10673254
OVERALL_GEOMEAN                                                      -0.1254         -0.1447             0             0             0             0
```

```
Benchmark                                                                                    Time             CPU      Time Old      Time New       CPU Old       CPU New
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_1_atomic_1_waiter_1_notifier<KeepNotifying, NumHighPrioTasks<0>>/65536                 -0.3344         -0.2424       5960741       3967212       5232250       3964085
BM_1_atomic_1_waiter_1_notifier<KeepNotifying, NumHighPrioTasks<0>>/131072                -0.1474         -0.1475       9144356       7796745       9137547       7790193
BM_1_atomic_1_waiter_1_notifier<KeepNotifying, NumHighPrioTasks<0>>/262144                -0.1336         -0.1340      18333441      15883805      18323711      15868500
OVERALL_GEOMEAN                                                                           -0.2107         -0.1761             0             0             0             0
```

```
Benchmark                                                                                                             Time             CPU      Time Old      Time New       CPU Old       CPU New
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<2>, NumHighPrioTasks<0>>/16384                +0.2321         -0.0081        836618       1030772        833197        826476
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<2>, NumHighPrioTasks<0>>/32768                -0.3034         -0.1329       2182721       1520569       1747211       1515028
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<2>, NumHighPrioTasks<0>>/65536                -0.0924         -0.0924       3389098       3075897       3378486       3066448
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<8>, NumHighPrioTasks<0>>/4096                 +0.0464         +0.0474        664233        695080        657736        688892
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<8>, NumHighPrioTasks<0>>/8192                 -0.0279         -0.0267       1336041       1298794       1324270       1288953
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<8>, NumHighPrioTasks<0>>/16384                +0.0270         +0.0304       2543004       2611786       2517471       2593975
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<32>, NumHighPrioTasks<0>>/1024                +0.0423         +0.0941        473621        493657        325604        356245
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<32>, NumHighPrioTasks<0>>/2048                +0.0420         +0.0675        906266        944349        636253        679169
BM_1_atomic_multi_waiter_1_notifier<KeepNotifying, NumWaitingThreads<32>, NumHighPrioTasks<0>>/4096                +0.0359         +0.0378       1761584       1824783       1015092       1053439
OVERALL_GEOMEAN                                                                                                    -0.0097         -0.0007             0             0             0             0
```

```
Benchmark                                                                                                        Time             CPU      Time Old      Time New       CPU Old       CPU New
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<2>, NumHighPrioTasks<0>>/4096                 -0.0990         -0.1001        371100        334370        369984        332955
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<2>, NumHighPrioTasks<0>>/8192                 -0.0305         -0.0314        698228        676908        696418        674585
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<2>, NumHighPrioTasks<0>>/16384                -0.0258         -0.0268       1383530       1347894       1380665       1343680
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<8>, NumHighPrioTasks<0>>/1024                 +0.0465         +0.4702        937821        981388        472087        694082
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<8>, NumHighPrioTasks<0>>/2048                 +0.1596         +0.9140       1704819       1976899        616419       1179852
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<8>, NumHighPrioTasks<0>>/4096                 -0.1018         -0.2316       3793976       3407609       1912209       1469331
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<32>, NumHighPrioTasks<0>>/256                 +0.0395         +0.5818      30102662      31292982        174650        276270
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<32>, NumHighPrioTasks<0>>/512                 -0.0065         +1.2860      33079634      32863968        162150        370680
BM_N_atomics_N_waiter_N_notifier<KeepNotifying, NumberOfAtomics<32>, NumHighPrioTasks<0>>/1024                -0.0325         +0.4683      36581740      35392385        282320        414520
OVERALL_GEOMEAN                                                                                               -0.0084         +0.2878             0             0             0             0
```

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-12-07 12:04:11 +00:00
Nikolas Klauser
2bdd1357c8
[libc++] Optimize num_get integral functions (#121795)
```
---------------------------------------------------
Benchmark                            old        new
---------------------------------------------------
BM_num_get<bool>                 86.5 ns    32.3 ns
BM_num_get<long>                 82.1 ns    30.3 ns
BM_num_get<long long>            85.2 ns    33.4 ns
BM_num_get<unsigned short>       85.3 ns    31.2 ns
BM_num_get<unsigned int>         84.2 ns    31.1 ns
BM_num_get<unsigned long>        83.6 ns    31.9 ns
BM_num_get<unsigned long long>   87.7 ns    31.5 ns
BM_num_get<float>                 116 ns     114 ns
BM_num_get<double>                114 ns     114 ns
BM_num_get<long double>           113 ns     114 ns
BM_num_get<void*>                 151 ns     144 ns
```

This patch applies multiple optimizations:
- Stages two and three of do_get are merged and a custom integer parser
has been implemented
This avoids allocations, removes the need for strto{,u}ll and avoids
__stage2_int_loop (avoiding extra writes to memory)
- std::find has been replaced with __atoms_offset, which uses vector
instructions to look for a character

Fixes #158100
Fixes #158102
2025-11-24 16:53:58 +01:00
Jordan Rupprecht
347512ff38
[libc++] Revert fstream::read optimizations (#168894)
This causes various runtime failures, as reported in #168628.

This reverts both #165223 and #167779
2025-11-21 07:08:15 -06:00
Nikolas Klauser
ad31e11ab6
[libc++] Make views::iota aware of __int128 (#167869)
Fixes #167991
2025-11-19 15:19:54 +01:00
William Tran-Viet
389a23c538
[libc++] Implement P2988R12: std::optional<T&> (#155202)
Resolves #148131

- Unlock `std::optional<T&>` implementation
- Allow instantiations of `optional<T(&)(...)>` and `optional<T(&)[]>`
but disables `value_or()` and `optional::iterator` + all `iterator`
related functions
- Update documentation
- Update tests
2025-11-12 11:00:08 +08:00
Nikolas Klauser
9b114c5d9a
[libc++] Optimize fstream::read (#165223)
```
Benchmark         old       new    Difference    % Difference
-----------  --------  --------  ------------  --------------
bm_read       2468.45    736.27      -1732.18         -70.17%
```
2025-11-07 10:31:31 +00:00
A. Jiang
bfcd67c347
[libc++][docs] Update status for P2641R4 (#166073)
Follows-up 2527b071ba2e39fdd62eeb73b89318468595c316 which missed
updating the status in the documentations.
2025-11-03 11:59:10 +08:00
Connector Switch
0621fd0b88
[libcxx] Optimize rng::generate_n for segmented iterators (#165280)
Part of #102817.

This patch optimizes `rng::generate_n` for segmented iterators by
forwarding the implementation directly to `std::generate_n`.

- before

```
rng::generate_n(deque<int>)/32          21.7 ns         22.0 ns     32000000
rng::generate_n(deque<int>)/50          30.8 ns         30.7 ns     22400000
rng::generate_n(deque<int>)/1024         492 ns          488 ns      1120000
rng::generate_n(deque<int>)/8192        3938 ns         3924 ns       179200
```

- after

```
rng::generate_n(deque<int>)/32          11.0 ns         11.0 ns     64000000
rng::generate_n(deque<int>)/50          16.2 ns         16.1 ns     40727273
rng::generate_n(deque<int>)/1024         292 ns          286 ns      2240000
rng::generate_n(deque<int>)/8192        2291 ns         2302 ns       298667
```
2025-10-28 22:22:26 +08:00
Connector Switch
c06ae43e26
[libcxx] Optimize std::generate_n for segmented iterators (#164266)
Part of #102817.

This is a natural follow-up to #163006. We are forwarding
`std::generate_n` to `std::__for_each_n` (`std::for_each_n` needs
c++17), resulting in improved performance for segmented iterators.

before:

```
std::generate_n(deque<int>)/32          17.5 ns         17.3 ns     40727273
std::generate_n(deque<int>)/50          25.7 ns         25.5 ns     26352941
std::generate_n(deque<int>)/1024         490 ns          487 ns      1445161
std::generate_n(deque<int>)/8192        3908 ns         3924 ns       179200
```

after:

```
std::generate_n(deque<int>)/32          11.1 ns         11.0 ns     64000000
std::generate_n(deque<int>)/50          16.1 ns         16.0 ns     44800000
std::generate_n(deque<int>)/1024         291 ns          292 ns      2357895
std::generate_n(deque<int>)/8192        2269 ns         2250 ns       298667
```
2025-10-21 12:01:36 +02:00
Nikolas Klauser
253e435908
Reapply "[libc++] Optimize __hash_table::erase(iterator, iterator)" (#162850)
This reapplication fixes the use after free caused by not properly
updating the bucket list in one case.

Original commit message:
Instead of just calling the single element `erase` on every element of
the range, we can combine some of the operations in a custom
implementation. Specifically, we don't need to search for the previous
node or re-link the list every iteration. Removing this unnecessary work
results in some nice performance improvements:
```
-----------------------------------------------------------------------------------------------------------------------
Benchmark                                                                                             old           new
-----------------------------------------------------------------------------------------------------------------------
std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/0                    457 ns        459 ns
std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/32                   995 ns        626 ns
std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/1024               18196 ns       7995 ns
std::unordered_set<int>::erase(iterator, iterator) (erase half the container)/8192              124722 ns      70125 ns
std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/0            456 ns        461 ns
std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/32          1183 ns        769 ns
std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/1024       27827 ns      18614 ns
std::unordered_set<std::string>::erase(iterator, iterator) (erase half the container)/8192      266681 ns     226107 ns
std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/0               455 ns        462 ns
std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/32              996 ns        659 ns
std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/1024          15963 ns       8108 ns
std::unordered_map<int, int>::erase(iterator, iterator) (erase half the container)/8192         136493 ns      71848 ns
std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/0               454 ns        455 ns
std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/32              985 ns        703 ns
std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/1024          16277 ns       9085 ns
std::unordered_multiset<int>::erase(iterator, iterator) (erase half the container)/8192         125736 ns      82710 ns
std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/0          457 ns        454 ns
std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/32        1091 ns        646 ns
std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/1024     17784 ns       7664 ns
std::unordered_multimap<int, int>::erase(iterator, iterator) (erase half the container)/8192    127098 ns      72806 ns
```


This reverts commit acc3a6234a91369b818fdd6482ded0ac32d8ffa6.
2025-10-21 10:20:06 +02:00
Connector Switch
46e8816928
[libcxx] Optimize std::generate for segmented iterators (#163006)
Part of #102817.

This patch attempts to optimize the performance of `std::generate` for
segmented iterators. Below are the benchmark numbers from
`libcxx\test\benchmarks\algorithms\modifying\generate.bench.cpp`. Test
cases that use segmented iterators have also been added.

- before

```
std::generate(deque<int>)/32           194 ns          193 ns      3733333
std::generate(deque<int>)/50           276 ns          276 ns      2488889
std::generate(deque<int>)/1024        5096 ns         5022 ns       112000
std::generate(deque<int>)/8192       40806 ns        40806 ns        17231
```

- after

```
std::generate(deque<int>)/32           106 ns          105 ns      6400000
std::generate(deque<int>)/50           139 ns          138 ns      4977778
std::generate(deque<int>)/1024        2713 ns         2699 ns       248889
std::generate(deque<int>)/8192       18983 ns        19252 ns        37333
```

---------

Co-authored-by: A. Jiang <de34@live.cn>
2025-10-20 19:37:33 +08:00
A. Jiang
cecde43009
[libc++][docs] Retarget completion of P2944R3 to LLVM 22 (#163753)
The completion of P2944R3 (4a509f853fa4821ecdb0f6bc3b90ddd48794cc8c)
just missed LLVM 21 release, and it seems controversial that whether
such feature completion should be backported.

I'm aware of following-up cleanup and bugfix about `<tuple>`. Perhaps it
will become more and more unwise to backport the changes. So let's
retarget P2944R3 to LLVM 22 in documentations.

Drive-by: Also fixes the formatting of the entry of P3379R0.
2025-10-19 15:35:47 +08:00
Peng Liu
d0cee6939a
[libc++] Optimize std::{,ranges}::{fill,fill_n} for segmented iterators (#132665)
This patch optimizes `std::fill`, `std::fill_n`, `std::ranges::fill`,
and `std::ranges::fill_n` for segmented iterators, achieving substantial
performance improvements. Specifically, for `deque<int>` iterators, the
performance improvements are above 10x for all these algorithms. The
optimization also enables filling segmented memory of `deque<int>` to
approach the performance of filling contiguous memory of `vector<int>`.


Benchmark results comparing the before and after implementations are
provided below. For additional context, we’ve included `vector<int>`
results, which remain unchanged, as this patch specifically targets
segmented iterators and leaves non-segmented iterator behavior
untouched.



Fixes two subtasks outlined in #102817.

#### `fill_n`

```
-----------------------------------------------------------------------------
Benchmark                                Before            After      Speedup
-----------------------------------------------------------------------------
std::fill_n(deque<int>)/32              11.4 ns          2.28 ns        5.0x
std::fill_n(deque<int>)/50              19.7 ns          3.40 ns        5.8x
std::fill_n(deque<int>)/1024             391 ns          37.3 ns       10.5x
std::fill_n(deque<int>)/8192            3174 ns           301 ns       10.5x
std::fill_n(deque<int>)/65536          26504 ns          2951 ns        9.0x
std::fill_n(deque<int>)/1048576       407960 ns         80658 ns        5.1x
rng::fill_n(deque<int>)/32              14.3 ns          2.15 ns        6.6x
rng::fill_n(deque<int>)/50              20.2 ns          3.22 ns        6.3x
rng::fill_n(deque<int>)/1024             381 ns          37.8 ns       10.1x
rng::fill_n(deque<int>)/8192            3101 ns           294 ns       10.5x
rng::fill_n(deque<int>)/65536          25098 ns          2926 ns        8.6x
rng::fill_n(deque<int>)/1048576       394342 ns         78874 ns        5.0x
std::fill_n(vector<int>)/32             1.76 ns          1.72 ns        1.0x
std::fill_n(vector<int>)/50             3.00 ns          2.73 ns        1.1x
std::fill_n(vector<int>)/1024           38.4 ns          37.9 ns        1.0x
std::fill_n(vector<int>)/8192            258 ns           252 ns        1.0x
std::fill_n(vector<int>)/65536          2993 ns          2889 ns        1.0x
std::fill_n(vector<int>)/1048576       80328 ns         80468 ns        1.0x
rng::fill_n(vector<int>)/32             1.99 ns          1.35 ns        1.5x
rng::fill_n(vector<int>)/50             2.66 ns          2.12 ns        1.3x
rng::fill_n(vector<int>)/1024           37.7 ns          35.8 ns        1.1x
rng::fill_n(vector<int>)/8192            253 ns           250 ns        1.0x
rng::fill_n(vector<int>)/65536          2922 ns          2930 ns        1.0x
rng::fill_n(vector<int>)/1048576       79739 ns         79742 ns        1.0x
```

#### `fill`

```
--------------------------------------------------------------------------
Benchmark                              Before            After     Speedup
--------------------------------------------------------------------------
std::fill(deque<int>)/32              13.7 ns          2.45 ns        5.6x
std::fill(deque<int>)/50              21.7 ns          4.57 ns        4.7x
std::fill(deque<int>)/1024             367 ns          38.5 ns        9.5x
std::fill(deque<int>)/8192            2896 ns           247 ns       11.7x
std::fill(deque<int>)/65536          23723 ns          2907 ns        8.2x
std::fill(deque<int>)/1048576       379043 ns         79885 ns        4.7x
rng::fill(deque<int>)/32              13.6 ns          2.70 ns        5.0x
rng::fill(deque<int>)/50              23.4 ns          3.94 ns        5.9x
rng::fill(deque<int>)/1024             377 ns          37.9 ns        9.9x
rng::fill(deque<int>)/8192            2914 ns           286 ns       10.2x
rng::fill(deque<int>)/65536          23612 ns          2939 ns        8.0x
rng::fill(deque<int>)/1048576       379841 ns         80079 ns        4.7x
std::fill(vector<int>)/32             1.99 ns          1.79 ns        1.1x
std::fill(vector<int>)/50             3.05 ns          3.06 ns        1.0x
std::fill(vector<int>)/1024           37.6 ns          38.0 ns        1.0x
std::fill(vector<int>)/8192            255 ns           257 ns        1.0x
std::fill(vector<int>)/65536          2966 ns          2981 ns        1.0x
std::fill(vector<int>)/1048576       78300 ns         80348 ns        1.0x
rng::fill(vector<int>)/32             1.77 ns          1.75 ns        1.0x
rng::fill(vector<int>)/50             4.85 ns          2.31 ns        2.1x
rng::fill(vector<int>)/1024           39.6 ns          36.1 ns        1.1x
rng::fill(vector<int>)/8192            238 ns           251 ns        0.9x
rng::fill(vector<int>)/65536          2941 ns          2918 ns        1.0x
rng::fill(vector<int>)/1048576       80497 ns         80442 ns        1.0x
```

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Co-authored-by: A. Jiang <de34@live.cn>
2025-10-17 07:41:24 +08:00
Peng Liu
fd08af0a96
[libc++] Optimize {std,ranges}::distance for segmented iterators (#133612)
This patch enhances the performance of `std::distance` and
`std::ranges::distance` for non-random-access segmented iterators, e.g.,
`std::join_view` iterators. The original implementation operates in
linear time, `O(n)`, where `n` is the total number of elements. The
optimized version reduces this to approximately `O(n / segment_size)` by
leveraging segmented structure, where `segment_size` is the average size
of each segment.

The table below summarizes the peak performance improvements observed
across different segment sizes, with the total element count `n` ranging
up to `1 << 20` (1,048,576 elements), based on benchmark results.

```
----------------------------------------------------------------------------------------
Container/n/segment_size                          std::distance     std::ranges::distance
----------------------------------------------------------------------------------------
join_view(vector<vector<int>>)/1048576/256	         401.6x	              422.9x
join_view(deque<deque<int>>)/1048576/256 	         112.1x	              132.6x
join_view(vector<vector<int>>)/1048576/1024         1669.2x              1559.1x
join_view(deque<deque<int>>)/1048576/1024            487.7x               497.4x
```

## Benchmarks


#### Segment size = 1024

```
-----------------------------------------------------------------------------------------
Benchmark                                                    Before      After    Speedup
-----------------------------------------------------------------------------------------
std::distance(join_view(vector<vector<int>>))/50            38.8 ns     1.01 ns     38.4x
std::distance(join_view(vector<vector<int>>))/1024           660 ns     1.02 ns    647.1x
std::distance(join_view(vector<vector<int>>))/4096          2934 ns     1.98 ns   1481.8x
std::distance(join_view(vector<vector<int>>))/8192          5751 ns     3.92 ns   1466.8x
std::distance(join_view(vector<vector<int>>))/16384        11520 ns     7.06 ns   1631.7x
std::distance(join_view(vector<vector<int>>))/65536        46367 ns     32.2 ns   1440.6x
std::distance(join_view(vector<vector<int>>))/262144      182611 ns      114 ns   1601.9x
std::distance(join_view(vector<vector<int>>))/1048576     737785 ns      442 ns   1669.2x
std::distance(join_view(deque<deque<int>>))/50              53.1 ns     6.13 ns      8.7x
std::distance(join_view(deque<deque<int>>))/1024             854 ns     7.53 ns    113.4x
std::distance(join_view(deque<deque<int>>))/4096            3507 ns     14.7 ns    238.6x
std::distance(join_view(deque<deque<int>>))/8192            7114 ns     17.6 ns    404.2x
std::distance(join_view(deque<deque<int>>))/16384          13997 ns     30.7 ns    455.9x
std::distance(join_view(deque<deque<int>>))/65536          55598 ns      114 ns    487.7x
std::distance(join_view(deque<deque<int>>))/262144        214293 ns      480 ns    446.4x
std::distance(join_view(deque<deque<int>>))/1048576       833000 ns     2183 ns    381.6x
rng::distance(join_view(vector<vector<int>>))/50            39.1 ns     1.10 ns     35.5x
rng::distance(join_view(vector<vector<int>>))/1024           689 ns     1.14 ns    604.4x
rng::distance(join_view(vector<vector<int>>))/4096          2753 ns     2.15 ns   1280.5x
rng::distance(join_view(vector<vector<int>>))/8192          5530 ns     4.61 ns   1199.6x
rng::distance(join_view(vector<vector<int>>))/16384        10968 ns     7.97 ns   1376.2x
rng::distance(join_view(vector<vector<int>>))/65536        46009 ns     35.3 ns   1303.4x
rng::distance(join_view(vector<vector<int>>))/262144      190569 ns      124 ns   1536.9x
rng::distance(join_view(vector<vector<int>>))/1048576     746724 ns      479 ns   1559.1x
rng::distance(join_view(deque<deque<int>>))/50              51.6 ns     6.57 ns      7.9x
rng::distance(join_view(deque<deque<int>>))/1024             826 ns     6.50 ns    127.1x
rng::distance(join_view(deque<deque<int>>))/4096            3323 ns     12.5 ns    265.8x
rng::distance(join_view(deque<deque<int>>))/8192            6619 ns     19.1 ns    346.5x
rng::distance(join_view(deque<deque<int>>))/16384          13495 ns     33.2 ns    406.5x
rng::distance(join_view(deque<deque<int>>))/65536          53668 ns      114 ns    470.8x
rng::distance(join_view(deque<deque<int>>))/262144        236277 ns      475 ns    497.4x
rng::distance(join_view(deque<deque<int>>))/1048576       914177 ns     2157 ns    423.8x
-----------------------------------------------------------------------------------------
```



#### Segment size = 256

```
-----------------------------------------------------------------------------------------
Benchmark                                                    Before      After    Speedup
-----------------------------------------------------------------------------------------
std::distance(join_view(vector<vector<int>>))/50            38.1 ns     1.02 ns     37.4x
std::distance(join_view(vector<vector<int>>))/1024           689 ns     2.06 ns    334.5x
std::distance(join_view(vector<vector<int>>))/4096          2815 ns     7.01 ns    401.6x
std::distance(join_view(vector<vector<int>>))/8192          5507 ns     14.3 ns    385.1x
std::distance(join_view(vector<vector<int>>))/16384        11050 ns     33.7 ns    327.9x
std::distance(join_view(vector<vector<int>>))/65536        44197 ns      118 ns    374.6x
std::distance(join_view(vector<vector<int>>))/262144      175793 ns      449 ns    391.5x
std::distance(join_view(vector<vector<int>>))/1048576     703242 ns     2140 ns    328.7x
std::distance(join_view(deque<deque<int>>))/50              50.2 ns     6.12 ns      8.2x
std::distance(join_view(deque<deque<int>>))/1024             835 ns     11.4 ns     73.2x
std::distance(join_view(deque<deque<int>>))/4096            3353 ns     32.9 ns    101.9x
std::distance(join_view(deque<deque<int>>))/8192            6711 ns     64.2 ns    104.5x
std::distance(join_view(deque<deque<int>>))/16384          13231 ns      118 ns    112.1x
std::distance(join_view(deque<deque<int>>))/65536          53523 ns      556 ns     96.3x
std::distance(join_view(deque<deque<int>>))/262144        219101 ns     2166 ns    101.2x
std::distance(join_view(deque<deque<int>>))/1048576       880277 ns    15852 ns     55.5x
rng::distance(join_view(vector<vector<int>>))/50            37.7 ns     1.13 ns     33.4x
rng::distance(join_view(vector<vector<int>>))/1024           697 ns     2.14 ns    325.7x
rng::distance(join_view(vector<vector<int>>))/4096          2804 ns     7.52 ns    373.0x
rng::distance(join_view(vector<vector<int>>))/8192          5749 ns     15.2 ns    378.2x
rng::distance(join_view(vector<vector<int>>))/16384        11742 ns     34.8 ns    337.4x
rng::distance(join_view(vector<vector<int>>))/65536        47274 ns      116 ns    407.7x
rng::distance(join_view(vector<vector<int>>))/262144      187774 ns      444 ns    422.9x
rng::distance(join_view(vector<vector<int>>))/1048576     749724 ns     2109 ns    355.5x
rng::distance(join_view(deque<deque<int>>))/50              53.0 ns     6.09 ns      8.7x
rng::distance(join_view(deque<deque<int>>))/1024             895 ns     11.0 ns     81.4x
rng::distance(join_view(deque<deque<int>>))/4096            3825 ns     30.6 ns    125.0x
rng::distance(join_view(deque<deque<int>>))/8192            7550 ns     60.5 ns    124.8x
rng::distance(join_view(deque<deque<int>>))/16384          14847 ns      112 ns    132.6x
rng::distance(join_view(deque<deque<int>>))/65536          56888 ns      453 ns    125.6x
rng::distance(join_view(deque<deque<int>>))/262144        231395 ns     2034 ns    113.8x
rng::distance(join_view(deque<deque<int>>))/1048576       933093 ns    15012 ns     62.2x
-----------------------------------------------------------------------------------------
```

Addresses a subtask of #102817.

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
Co-authored-by: A. Jiang <de34@live.cn>
2025-10-16 07:44:35 +08:00
Hristo Hristov
8a27b48122
[libc++][atomic] P2835R7: Expose std::atomic_ref's object address (#162236)
Implements https://wg21.link/P2835R7

Closes #118377

# References

- https://wg21.link/atomics.ref.generic.general
- https://wg21.link/atomics.ref.int
- https://wg21.link/atomics.ref.float
- https://wg21.link/atomics.ref.pointer

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2025-10-13 20:27:02 +08:00
Hristo Hristov
45c41247f8
[libc++][ranges] P3060R3: Add std::views::indices(n) (#146823)
Implements [P3060R3](https://wg21.link/P3060R3)

Closes #148175

# References

- https://github.com/cplusplus/draft/issues/7966
- https://github.com/cplusplus/draft/pull/8006
- https://wg21.link/customization.point.object
- https://wg21.link/range.iota.overview
- https://wg21.link/ranges.syn

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
Co-authored-by: A. Jiang <de34@live.cn>
2025-10-06 18:13:25 +03:00
Hristo Hristov
ccd06e4809
[libc++][istream] P3223R2: Making std::istream::ignore less surprising (#147007)
Implements https://wg21.link/P3223R2 as a DR as, as recommended in
https://github.com/cplusplus/papers/issues/1871#issuecomment-2993018698.
Resolves -1L ambiguity.

Closes #148178
2025-09-30 11:26:30 -04:00