475 Commits

Author SHA1 Message Date
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
Michael G. Kazakov
4ccdd2ffac
[libc++][pstl] Generic implementation of parallel std::is_sorted (#176129)
This PR implements a generic backend-agnostic parallel `std::is_sorted`
based on `std::transform_reduce`.

While this approach is suboptimal comparing a direct backend-specific
implementation, since it doesn't support early termination and requires
a reduction operation, it does show speedup when the dataset is large
enough and the comparator is not absolutely trivial.

Parent issue: #99938
2026-01-27 13:43:23 -05: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
A. Jiang
11c0fd4f44
[libc++][test] Fix constexpr stdver. for tests for find_if(_not) (#176303)
Until C++20, `std::find_if(_not)` were not `constexpr`, so uses of
`TEST_CONSTEXPR_CXX17` make the test functions ill-formed, no diagnostic
required in C++17 mode.

The uses were introduced in 2b4b26ea84fd9c95d0ff25ce338c15ea5e74a4e4,
while the transformation looked incorrect - `TEST_CONSTEXPR_CXX20`
should be used instead.

Drive-by changes: Fix comments in both changed test files to match the
actually standardized wording.
2026-01-16 11:33:29 +01:00
Nikolas Klauser
4304106dc2
Reapply "[libc++] Optimize std::find_if" (#175903) (#175921)
#175913 removed that `__builtin_assume_dereferenceable(ptr, 0)` implies
`ptr != nullptr`, which should allow us to use the builtin with LLVM 23.

This reverts commit 776c09c212e945fdceeae240b42c38df3dd34727.
2026-01-15 10:16:45 +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
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
A. Jiang
05218825ee
[libc++] Fix ranges::for_each taking whole associative containers (#172605)
Currently, the version of `ranges::for_each` which takes whole
associative containers treats `__root->__get_value()` as an existing
element even when the container is empty.

We should exit earlier in `__specialized_algorithm<...>::operator()`
when the tree is empty.
2025-12-17 12:31:46 -05:00
Nikolas Klauser
57aab63417
[libc++] Fix std::for_each(associative-container) not using std:invoke and projections (#171984)
#164405 added specializations of `for_each` that didn't do the ranges
call shenanigans, but instead just did what the classic algorithms have
to do. This updates the calls to work for the ranges overloads as well.
2025-12-15 12:05:59 +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
f3ce5dec69
[libc++] Forward std::all_of and std::none_of to std::any_of (#167670)
This allows propagating optimizations to different algorithms by just
optimizing the lowest one. This is especially relevant now that we start
optimizing how we're iterating through ranges (e.g. the segmented
iterator optimizations) and adding assumptions so the compier can better
leverage semantics guaranteed by the standard (e.g.
`__builtin_assume_dereferenceable`).
2025-11-24 11:09:40 +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
a516cc0bad
[libc++][C++03] Fix alg.count/count.pass.cpp (#163751) 2025-10-22 18:22:43 +02: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
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
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
Nikolas Klauser
be5941e974
[libc++][C++03] Fix alg.copy/copy.pass.cpp (#163365) 2025-10-16 09:31:04 +02:00
lbonn
d1b5607dc1
[libc++][ranges] Fix ranges::join_view segmented iterator trait (#158347)
The outer iterator needs to move to the next segment when calling
__compose.

Without this change, `find_segment_if` would never reach the end of the
join_view which caused erroneous result when calling `ranges::find` on a
join_view of bidirectional ranges.

Other specializations using the segmented iterator trait were likely to
be affected as well.

Fixes #158279
Fixes #93180
2025-09-27 22:49:54 +08:00
Jonathan Wakely
69e3ff67ac
[libc++] Fix ranges_rotate.pass.cpp complexity checks (#158144)
The complexity is "at most N swaps" _for each invocation of `rotate`_,
but the tests currently assert that the total number of swaps for N
calls is at most N. The standard allows that to be N squared, so the
test is either requiring more than the standard (and the comment in the
test) promises, or somebody just forgot to reset the counter on each
iteration.
2025-09-11 20:42:08 -04:00
Nikolas Klauser
3fb9412b79
[libc++][C++03] partially cherry-pick #122641 (#157596)
This patch only cherry-picks the parts that actually fix the issue, but
not the numerous NFC refactorings around it.
2025-09-11 10:14:30 +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
Stephan T. Lavavej
abf91449a3
[libcxx][test] Fix typos (#155217)
I noticed a typo in the directory name `refwrap.comparissons`, then did
a quick pass to fix typos elsewhere in the tests.

All fixes were manual (some carefully search-and-replaced); I used
[cspell](https://www.npmjs.com/package/cspell) to find them.
2025-08-25 03:02:51 -07:00
Peng Liu
9827440f1e
[libc++] Optimize ranges::{for_each, for_each_n} for segmented iterators (#132896)
Previously, the segmented iterator optimization was limited to `std::{for_each, for_each_n}`. This patch
extends the optimization to `std::ranges::for_each` and `std::ranges::for_each_n`, ensuring consistent
optimizations across these algorithms. This patch first generalizes the `std` algorithms by introducing
a `Projection` parameter, which is set to `__identity` for the `std` algorithms. Then we let the `ranges`
algorithms to directly call their `std` counterparts with a general `__proj` argument. Benchmarks
demonstrate performance improvements of up to 21.4x for ``std::deque::iterator`` and 22.3x for
``join_view`` of ``vector<vector<char>>``.

Addresses a subtask of #102817.
2025-06-18 12:22:47 -04:00
Nikolas Klauser
42c82fcc29
[libc++] Upgrade to GCC 15 (#138293) 2025-06-11 20:19:26 +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
cor3ntin
381a649fb9
[Clang] Add warnings when mixing different charN_t types (#138708)
charN_t represent code units of different UTF encodings. Therefore the
values of 2 different charN_t objects do not represent the same
characters.

In order to avoid comparing apples and oranges, we add new warnings to
warn on:
  - Implicit conversions
  - Comparisons
  - Other cases involving arithmetic conversions

We only produce the warning if we cannot establish the comparison would
be safe through constant evaluation.

The new `-Wimplicit-unicode-conversion` warning is enabled by default.

Note that this PR intentionally doesn;t touches char/wchar_t, but it
would be worth considering also warning on extending the new warnings to
these types (in a follow up)

Additionally most arithmetic operations on charN_t don't really make
sense (ie what does it mean to addition code units), so we could add
warnings for that.

Fixes #138526
2025-05-15 18:16:05 +02:00
Peng Liu
f1ecff8f88
[libc++] Improve test coverage and readability for swap_ranges (#133752)
This patch enhances the test coverage of `{std,ranges}::swap_ranges` by
adding larger test cases with 100 elements across different containers.
It also inlines standalone tests for better readability, avoiding
unnecessary navigation.

This patch addresses a follow-up suggestion from PR #121138 to extend
test coverage beyond 3 elements.
2025-05-14 13:02:01 -04:00
A. Jiang
fc281e1b4f
[libc++][docs] Confirm that P3136R1 Retiring niebloids is Complete (#135932)
As libc++ has been implementing niebloids as CPOs since LLVM 14 due to
https://reviews.llvm.org/D116570.

Also changes some comments in test files to use the formal term
"algorithm function object".

Closes #118133.
2025-05-07 15:20:43 -04:00
Peng Liu
7087ee6bc7
[libc++][NFC] Improve test readability for std::fill_n (#133771)
This patch enhances test readability by inlining standalone tests,
eliminating unnecessary navigation. Additionally, several classes with
ad-hoc names have been renamed for better clarity:
- `A` -> `CharWrapper` as it wraps a char
- `B -> CharTransformer` as it accepts a char `xc` but stores `xc + 1`
- `Storage -> CharUnionStorage` as it stores a union of 2 `char`s.  

This patch addresses a follow-up comment from #120909 to inline tests.
2025-05-06 16:17:18 -04:00
Дмитрий Изволов
51b8c66b08
[libc++] Extend the scope of radix sorting inside std::stable_sort to floating-point types (#129452)
These changes speed up `std::stable_sort` in the case of sorting
floating-point types.
This applies only to IEEE 754 floats.
The speedup is similar to that achieved for integers in PR #104683 (see
benchmarks below).

Why does this worth doing?
Previously, `std::stable_sort` had almost no chance of beating
`std::sort`.
Now there are cases when `std::stable_sort` is preferrable, and the
difference is significant.
```
---------------------------------------------------------------------------
Benchmark             |  std::stable_sort  |   std::sort | std::stable_sort
                      | without radix_sort |             | with radix_sort 
---------------------------------------------------------------------------
float_Random_1        |       1.62 ns      |     2.15 ns |          1.61 ns
float_Random_4        |       18.0 ns      |     2.71 ns |          16.3 ns
float_Random_16       |        118 ns      |      113 ns |           112 ns
float_Random_64       |        751 ns      |      647 ns |           730 ns
float_Random_256      |       4715 ns      |     2937 ns |          4669 ns
float_Random_1024     |      25713 ns      |    13172 ns |          5959 ns <--
float_Random_4096     |     131307 ns      |    56870 ns |         19294 ns <--
float_Random_16384    |     624996 ns      |   242953 ns |         64264 ns <--
float_Random_65536    |    2895661 ns      |  1027279 ns |        288553 ns <--
float_Random_262144   |   13285372 ns      |  4342593 ns |       3022377 ns <--
float_Random_1048576  |   60595871 ns      | 19087591 ns |      18690457 ns <--
float_Random_2097152  |  131336117 ns      | 38800396 ns |      52325016 ns
float_Random_4194304  |  270043042 ns      | 79978019 ns |     102907726 ns
double_Random_1       |       1.60 ns      |     2.15 ns |          1.61 ns
double_Random_4       |       15.2 ns      |     2.70 ns |          16.9 ns
double_Random_16      |        104 ns      |      112 ns |           119 ns
double_Random_64      |        712 ns      |      614 ns |           755 ns
double_Random_256     |       4496 ns      |     2966 ns |          4820 ns
double_Random_1024    |      24722 ns      |    12679 ns |          6189 ns <--
double_Random_4096    |     126075 ns      |    54484 ns |         20999 ns <--
double_Random_16384   |     613782 ns      |   232557 ns |        110276 ns <--
double_Random_65536   |    2894972 ns      |   988531 ns |        774302 ns <--
double_Random_262144  |   13460273 ns      |  4278059 ns |       5115123 ns
double_Random_1048576 |   61119996 ns      | 18408462 ns |      27166574 ns
double_Random_2097152 |  132511525 ns      | 37986158 ns |      54423869 ns
double_Random_4194304 |  272949862 ns      | 77912616 ns |     147670834 ns
```

Comparison for only `std::stable_sort`:
```
Benchmark                                                         Time      Time Old      Time New
--------------------------------------------------------------------------------------------------
BM_StableSort_float_Random_1024                                -0.7997         25438          5096
BM_StableSort_float_Random_4096                                -0.8731        128157         16260
BM_StableSort_float_Random_16384                               -0.9024        621271         60623
BM_StableSort_float_Random_65536                               -0.9081       2922413        268619
BM_StableSort_float_Random_262144                              -0.7766      13386345       2990408
BM_StableSort_float_Random_1048576                             -0.6954      60673010      18481751
BM_StableSort_float_Random_2097152                             -0.6026     130977358      52052182
BM_StableSort_float_Random_4194304                             -0.6252     271556583     101770500
BM_StableSort_float_Ascending_1024                             -0.6430          6711          2396
BM_StableSort_float_Ascending_4096                             -0.7979         38460          7773
BM_StableSort_float_Ascending_16384                            -0.8471        191069         29222
BM_StableSort_float_Ascending_65536                            -0.8683        882321        116194
BM_StableSort_float_Ascending_262144                           -0.8346       3868552        639937
BM_StableSort_float_Ascending_1048576                          -0.7460      16521233       4195953
BM_StableSort_float_Ascending_2097152                          -0.5439      21757532       9922776
BM_StableSort_float_Ascending_4194304                          -0.7525      67847496      16791582
BM_StableSort_float_Descending_1024                            -0.6359         15038          5475
BM_StableSort_float_Descending_4096                            -0.7090         62810         18278
BM_StableSort_float_Descending_16384                           -0.7763        311844         69750
BM_StableSort_float_Descending_65536                           -0.7228       1270513        352202
BM_StableSort_float_Descending_262144                          -0.6785       5484173       1763045
BM_StableSort_float_Descending_1048576                         -0.5084      20223149       9941852
BM_StableSort_float_Descending_2097152                         -0.7646      60523254      14247014
BM_StableSort_float_Descending_4194304                         -0.5638      95706839      41748858
BM_StableSort_float_SingleElement_1024                         +0.3715          1732          2375
BM_StableSort_float_SingleElement_4096                         -0.1685          9357          7781
BM_StableSort_float_SingleElement_16384                        -0.3793         47307         29362
BM_StableSort_float_SingleElement_65536                        -0.4925        227666        115536
BM_StableSort_float_SingleElement_262144                       -0.4271       1075853        616387
BM_StableSort_float_SingleElement_1048576                      -0.3736       5097599       3193279
BM_StableSort_float_SingleElement_2097152                      -0.2470       9854161       7420158
BM_StableSort_float_SingleElement_4194304                      -0.3384      22175964      14670720
BM_StableSort_float_PipeOrgan_1024                             -0.4885         10664          5455
BM_StableSort_float_PipeOrgan_4096                             -0.6340         50095         18337
BM_StableSort_float_PipeOrgan_16384                            -0.7078        238700         69739
BM_StableSort_float_PipeOrgan_65536                            -0.6740       1102419        359378
BM_StableSort_float_PipeOrgan_262144                           -0.7460       4698739       1193511
BM_StableSort_float_PipeOrgan_1048576                          -0.5657      18493972       8032392
BM_StableSort_float_PipeOrgan_2097152                          -0.7116      41089206      11850349
BM_StableSort_float_PipeOrgan_4194304                          -0.6650      83445011      27955737
BM_StableSort_float_QuickSortAdversary_1024                    -0.6863         17402          5460
BM_StableSort_float_QuickSortAdversary_4096                    -0.7715         79864         18247
BM_StableSort_float_QuickSortAdversary_16384                   -0.7800        317480         69839
BM_StableSort_float_QuickSortAdversary_65536                   -0.7400       1357601        352967
BM_StableSort_float_QuickSortAdversary_262144                  -0.6450       5662094       2009769
BM_StableSort_float_QuickSortAdversary_1048576                 -0.5092      21173627      10392107
BM_StableSort_float_QuickSortAdversary_2097152                 -0.7333      61748178      16469993
BM_StableSort_float_QuickSortAdversary_4194304                 -0.5607      98459863      43250182
BM_StableSort_double_Random_1024                               -0.7657         24769          5802
BM_StableSort_double_Random_4096                               -0.8441        126449         19717
BM_StableSort_double_Random_16384                              -0.8269        614910        106447
BM_StableSort_double_Random_65536                              -0.7413       2905000        751427
BM_StableSort_double_Random_262144                             -0.6287      13449514       4994348
BM_StableSort_double_Random_1048576                            -0.5635      60863246      26568349
BM_StableSort_double_Random_2097152                            -0.5959     130293892      52654532
BM_StableSort_double_Random_4194304                            -0.4772     272616445     142526267
BM_StableSort_double_Ascending_1024                            -0.4870          6757          3466
BM_StableSort_double_Ascending_4096                            -0.7360         37592          9923
BM_StableSort_double_Ascending_16384                           -0.7971        183967         37324
BM_StableSort_double_Ascending_65536                           -0.7465        897116        227398
BM_StableSort_double_Ascending_262144                          -0.6764       4020980       1301033
BM_StableSort_double_Ascending_1048576                         -0.6407      16421799       5900751
BM_StableSort_double_Ascending_2097152                         -0.6380      29347139      10622419
BM_StableSort_double_Ascending_4194304                         -0.5934      70439925      28644185
BM_StableSort_double_Descending_1024                           -0.5988         15216          6105
BM_StableSort_double_Descending_4096                           -0.6857         65069         20449
BM_StableSort_double_Descending_16384                          -0.6922        329321        101381
BM_StableSort_double_Descending_65536                          -0.7038       1367970        405242
BM_StableSort_double_Descending_262144                         -0.6472       5361644       1891429
BM_StableSort_double_Descending_1048576                        -0.6656      22031404       7366459
BM_StableSort_double_Descending_2097152                        -0.7593      68922467      16591242
BM_StableSort_double_Descending_4194304                        -0.6392      96283643      34743223
BM_StableSort_double_SingleElement_1024                        +0.9128          1895          3625
BM_StableSort_double_SingleElement_4096                        +0.1475         10013         11490
BM_StableSort_double_SingleElement_16384                       -0.1901         52382         42424
BM_StableSort_double_SingleElement_65536                       -0.2096        254698        201313
BM_StableSort_double_SingleElement_262144                      -0.1833       1248478       1019648
BM_StableSort_double_SingleElement_1048576                     -0.1741       5703397       4710603
BM_StableSort_double_SingleElement_2097152                     -0.1751      10922197       9009835
BM_StableSort_double_SingleElement_4194304                     -0.1538      26571923      22485137
BM_StableSort_double_PipeOrgan_1024                            -0.4406         10752          6014
BM_StableSort_double_PipeOrgan_4096                            -0.5917         49456         20195
BM_StableSort_double_PipeOrgan_16384                           -0.6258        270515        101221
BM_StableSort_double_PipeOrgan_65536                           -0.7098       1159462        336457
BM_StableSort_double_PipeOrgan_262144                          -0.6591       4735711       1614433
BM_StableSort_double_PipeOrgan_1048576                         -0.6620      19353110       6541172
BM_StableSort_double_PipeOrgan_2097152                         -0.7288      49131812      13323391
BM_StableSort_double_PipeOrgan_4194304                         -0.5988      81958974      32878171
BM_StableSort_double_QuickSortAdversary_1024                   -0.6516         17948          6254
BM_StableSort_double_QuickSortAdversary_4096                   -0.7527         82359         20363
BM_StableSort_double_QuickSortAdversary_16384                  -0.7009        340410        101811
BM_StableSort_double_QuickSortAdversary_65536                  -0.6854       1487480        467928
BM_StableSort_double_QuickSortAdversary_262144                 -0.6386       5648460       2041377
BM_StableSort_double_QuickSortAdversary_1048576                -0.6127      22859142       8852587
BM_StableSort_double_QuickSortAdversary_2097152                -0.7161      68693975      19499381
BM_StableSort_double_QuickSortAdversary_4194304                -0.5909      95532179      39077491
OVERALL_GEOMEAN                                                -0.6472             0             0
```
2025-04-16 17:34:11 +08:00
James E T Smith
475cbf0ad6
[libc++] Implement ranges::iota (#68494)
# Overview

As a disclaimer, this is my first PR to LLVM and while I've tried to
ensure I've followed the LLVM and libc++ contributing guidelines,
there's probably a good chance I missed something. If I have, just let
me know and I'll try to correct it as soon as I can.

This PR implements `std::ranges::iota` and
`std::ranges::out_value_result` outlined in
[P2440r1](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2440r1.html).

As outlined in the paper above, I've:
- Implemented `out_value_result` and added to `<algorithm>`
- Added `out_value_result`, `iota_result`, and two overloads of `iota`
to `std::ranges` in `<numeric>`
- Updated the version macro `__cpp_lib_ranges_iota` in `<version>`

I've also added tests for `ranges::iota` and `ranges::out_value_result`.
Lastly, I added those structs to the appropriate module files.

Partially implements #105184

EDIT: Forgot to mention in the original post, thanks to @hawkinsw for
taking a look at a preliminary version of this PR!

# TODOs
- [x] Updating the range [status
doc](https://github.com/jamesETsmith/llvm-project/blob/main/libcxx/docs/Status/RangesMajorFeatures.csv)
- [x] Ensure all comments from https://reviews.llvm.org/D121436 are
addressed here
- [X] EDIT (I'll do this in a separate PR). ~~I'm open to implementing
the rest of P2440r1 (`ranges::shift_left` and `ranges::shift_right`) if
that's ok, I just wanted to get feedback on `ranges::iota` first~~
- [x] I've been having trouble building the modules locally and want to
make sure that's working properly

Closes: #134060
2025-04-05 13:46:11 +02:00
A. Jiang
e409464e95
[libc++][test][NFC] Introduce TEST_STD_AT_LEAST_26_OR_RUNTIME_EVALUATED (#132593)
And use it for test cases that became constant-evaluation-suitable due
to P2562R1.

`TEST_STD_AT_LEAST_(20|23)_OR_RUNTIME_EVALUATED` are the precedents.
2025-03-24 10:43:19 +08:00
Stephan T. Lavavej
bf5cdd6358
[libc++][test] Fix issues found by MSVC's STL (#131787)
* libcxx/test/support/min_allocator.h
+ Fix `tiny_size_allocator::rebind` which mistakenly said `T` instead of
`U`.
*
libcxx/test/std/algorithms/alg.modifying.operations/alg.partitions/stable_partition.pass.cpp
  + `std::stable_partition` requires bidirectional iterators.
* libcxx/test/std/containers/sequences/vector.bool/max_size.pass.cpp
+ Fix allocator type given to `std::vector<bool>`. The element types are
required to match, [N5008](https://isocpp.org/files/papers/N5008.pdf)
\[container.alloc.reqmts\]/5: "*Mandates:* `allocator_type::value_type`
is the same as `X::value_type`."
* libcxx/test/std/time/time.clock/time.clock.utc/types.compile.pass.cpp
+ Mark `is_steady` as `[[maybe_unused]]`, as it appears within
`LIBCPP_STATIC_ASSERT` only.
*
libcxx/test/std/algorithms/alg.modifying.operations/alg.rotate/rotate.pass.cpp
*
libcxx/test/std/algorithms/alg.modifying.operations/alg.swap/swap_ranges.pass.cpp
* libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp
+ Fix MSVC warning C4127 "conditional expression is constant".
`TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED` was introduced for this
purpose, so it should be used consistently.
* libcxx/test/std/numerics/numeric.ops/numeric.ops.gcd/gcd.pass.cpp
+ Fix `gcd()` precondition violation for `signed char`. This test case
was causing `-128` to be passed as a `signed char` to `gcd()`, which is
forbidden.
* libcxx/test/std/containers/sequences/array/assert.iterators.pass.cpp
*
libcxx/test/std/containers/sequences/vector/vector.modifiers/assert.push_back.invalidation.pass.cpp
*
libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp
+ Split some REQUIRES and XFAIL lines. This is a "nice to have" for
MSVC's internal test harness, which is extremely simple and looks for
exact comment matches to skip tests. We can recognize the specific lines
"REQUIRES: has-unix-headers" and "XFAIL: msvc", but it's a headache to
maintain if they're chained with other conditions.
* libcxx/test/support/sized_allocator.h
+ Fix x86 truncation warnings. `std::allocator` takes `std::size_t`, so
we need to `static_cast`.
*
libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/offset_range.pass.cpp
+ Fix x86 truncation warning. `std::min()` is returning
`std::streamoff`, which was being unnecessarily narrowed to
`std::size_t`.
*
libcxx/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp
+ Fix MSVC warning C4127 "conditional expression is constant" for an
always-true branch. This was very recently introduced by #129008 making
`N` constexpr. As it's a local constant just nine lines above, we don't
need to test whether 100 is greater than 0.
2025-03-20 15:53:25 +08:00
A. Jiang
053a714add
[libc++] Implement part of P2562R1: constexpr ranges::inplace_merge (#131947)
Drive-by changes:
- Consistently mark `std::__inplace_merge::__inplace_merge_impl`
`_LIBCPP_CONSTEXPR_SINCE_CXX26`.
- This function template is only called by other functions that becomes
constexpr since C++26, and it itself calls `std::__inplace_merge` that
is constexpr since C++26.
- Unblock related test coverage in constant evaluation for
`stable_partition`, `ranges::stable_sort`, `std::stable_sort`,
`std::stable_partition`, and `std::inplace_merge`.
2025-03-20 01:59:32 +08:00
Peng Liu
029cb8aff1
[libc++] Fix copy_backward for vector<bool> with small storage types (#131560)
This patch fixes an issue in libc++ where `std::copy_backward` and
`ranges::copy_backward` incorrectly copy `std::vector<bool>` with small
storage types (e.g., `uint8_t`, `uint16_t`). The problem arises from
flawed bit mask computations involving integral promotions and sign-bit
extension, leading to unintended zeroing of bits. This patch corrects
the bitwise operations to ensure correct bit-level copying.

Fixes #131718.
2025-03-19 11:58:02 -04:00
Peng Liu
a5b3d3a03f
[libc++] Fix {std, ranges}::copy for vector<bool> with small storage types (#131545)
The current implementation of `{std, ranges}::copy` fails to copy
`vector<bool>` correctly when the underlying storage type
(`__storage_type`) is smaller than `int`, such as `unsigned char`,
`unsigned short`, `uint8_t` and `uint16_t`. The root cause is that the
unsigned small storage type undergoes integer promotion to (signed)
`int`, which is then left and right shifted, leading to UB (before
C++20) and sign-bit extension (since C++20) respectively. As a result,
the underlying bit mask evaluations become incorrect, causing erroneous
copying behavior.

This patch resolves the issue by correcting the internal bitwise
operations, ensuring that `{std, ranges}::copy` operates correctly for
`vector<bool>` with any custom (unsigned) storage types.

Fixes #131692.
2025-03-19 11:55:51 -04:00
Peng Liu
c5195ae2d0
[libc++] Fix {std, ranges}::equal for vector<bool> with small storage types (#130394)
The current implementation of `{std, ranges}::equal` fails to correctly
compare `vector<bool>`s when the underlying storage type is smaller than
`int` (e.g., `unsigned char`, `unsigned short`, `uint8_t` and
`uint16_t`). See [demo](https://godbolt.org/z/j4s87s6b3)). The problem
arises due to integral promotions on the intermediate bitwise
operations, leading to incorrect final equality comparison results. This
patch fixes the issue by ensuring that `{std, ranges}::equal` operate
properly for both aligned and unaligned bits.
 
Fixes #126369.
2025-03-19 11:51:21 -04:00
Peng Liu
e53bea5182
[libc++] Fix ambiguous call in {ranges, std}::count (#122529)
This PR fixes an ambiguous call encountered while using the
`std::ranges::count` and `std::count` algorithms with `vector<bool>`
with small `size_type`s.

The ambiguity arises from integral promotions during the internal
bitwise arithmetic of the `count` algorithms for small integral types.
This results in multiple viable candidates:
`__libcpp_popcount(unsigned)`,` __libcpp_popcount(unsigned long)`, and
`__libcpp_popcount(unsigned long long)`, leading to an ambiguous call
error. To resolve this ambiguity, we introduce a dispatcher function,
`__popcount`, which directs calls to the appropriate overloads of
`__libcpp_popcount`. This closes #122528.
2025-03-19 11:36:29 -04:00
A. Jiang
854a4f2bbb
[libc++] Implement part of P2562R1: constexpr std::inplace_merge (#129008)
Drive-by:
- Adds `constexpr_random.h` for pseudo-randomizing or shuffling in tests
for constant evaluation.
2025-03-19 07:42:23 +08:00
Peng Liu
3bd71cbec7
[libc++] Fix ambiguous call in {ranges, std}::find (#122641)
This PR fixes an ambiguous call encountered when using the `std::ranges::find` or `std::find`
algorithms with `vector<bool>` with small `allocator_traits::size_type`s, an issue reported
in #122528. The ambiguity arises from integral promotions during the internal bitwise
arithmetic of the `find` algorithms when applied to `vector<bool>` with small integral
`size_type`s. This leads to multiple viable candidates for small integral types:
__libcpp_ctz(unsigned), __libcpp_ctz(unsigned long), and __libcpp_ctz(unsigned long long),
none of which represent a single best viable match, resulting in an ambiguous call error.

To resolve this, we propose invoking an internal function __countr_zero as a dispatcher
that directs the call to the appropriate overload of __libcpp_ctz. Necessary amendments
have also been made to __countr_zero.
2025-03-13 14:15:03 -04:00
Peng Liu
4baf1c03fa
[libc++] Optimize ranges::rotate for vector<bool>::iterator (#121168)
This PR optimizes the performance of `std::ranges::rotate` for
`vector<bool>::iterator`. The optimization yields a performance
improvement of up to 2096x.

Closes #64038.
2025-03-13 14:07:23 -04:00
AdityaK
deb4b20662
[NFC][libcxx][test] clang-format: search.pass.cpp (#130551) 2025-03-10 11:21:09 -07:00
A. Jiang
ba9aeedf8e
[libc++] Implement part of P2562R1: constexpr ranges::stable_sort (#128860)
Drive-by: Enables test coverage for `ranges::stable_sort` with proxy
iterators, and changes "constexpr in" to "constexpr since" in comments
in `<algorithm>`.
2025-03-07 01:27:48 +08:00
A. Jiang
c28c508962
[libc++] Implement part of P2562R1: constexpr ranges::stable_partition (#129839) 2025-03-06 09:23:55 +08:00
Peng Liu
a12744ff05
[libc++] Optimize ranges::swap_ranges for vector<bool>::iterator (#121150)
This PR optimizes the performance of `std::ranges::swap_ranges` for
`vector<bool>::iterator`, addressing a subtask outlined in issue #64038.
The optimizations yield performance improvements of up to **611x** for
aligned range swap and **78x** for unaligned range swap comparison.
Additionally, comprehensive tests covering up to 4 storage words (256
bytes) with odd and even bit sizes are provided, which validate the
proposed optimizations in this patch.
2025-03-04 17:15:36 -05:00
A. Jiang
bf9bf291a3
[libc++] Implement part of P2562R1: constexpr std::stable_partition (#128868)
Drive-by changes:
- Enables no-memory case for Clang.
- Enables `robust_re_difference_type.compile.pass.cpp` and
`robust_against_proxy_iterators_lifetime_bugs.pass.cpp` test coverage
for `std::stable_sort` in constant evaluation since C++26. The changes
were missing in the PR making `std::stable_sort` `constexpr`.
2025-03-04 09:23:29 +08:00
Peng Liu
7717a549e9
[libc++] Optimize ranges::equal for vector<bool>::iterator (#121084)
This PR optimizes the performance of `std::ranges::equal` for
`vector<bool>::iterator`, addressing a subtask outlined in issue #64038.
The optimizations yield performance improvements of up to 188x for
aligned equality comparison and 82x for unaligned equality
comparison. Moreover, comprehensive tests covering up to 4 storage words
(256 bytes) with odd and even bit sizes are provided, which validate the
proposed optimizations in this patch.
2025-02-26 12:18:25 -05:00
Peng Liu
f161b1b526
[libc++][test] Refactor tests for rotate and rotate_copy (#126458)
This PR refactors the tests and fix some problems:  
- Refactor similar tests using `types::for_each` to remove redundant code;
- Explicitly include the missing header `type_algorithms.h` instead of relying
  on a transitive include;
- Fix the incorrect constexpr declaration in `rotate.pass.cpp`, where
  the `test()` function is incorrectly defined as `TEST_CONSTEXPR_CXX17`,
  which is wrong since `std::rotate()` becomes constexpr only since C++20.
2025-02-26 11:57:57 -05:00
Peng Liu
ffc5d2b5d4
[libc++][test] Refactor tests for ranges::swap_range algorithms (#121138)
This PR refactors tests for `ranges::swap_range`, `std::{swap_range,
iter_swap, swap}` algorithms to eliminate redundant code.
2025-02-26 11:49:19 -05:00
Peng Liu
1d583ed2fb
[libc++][test] Augment ranges::{fill, fill_n, find} with missing tests (#121209)
libc++ currently has very limited test coverage for `std::ranges{fill, fill_n, find}`
with `vector<bool>::iterator` optimizations. Specifically, the existing tests for
`std::ranges::fill` only covers cases of 1 - 2 bytes, which is merely 1/8 to 1/4
of the `__storage_type` word size. This renders the tests insufficient to validate
functionality for whole words, with or without partial words (which necessitates at
least 8 bytes of data). Moreover, no tests were provided for `ranges::{find, fill_n}`
with `vector<bool>::iterator` optimizations. This PR fills in the gap.
2025-02-26 11:38:15 -05:00