270 Commits

Author SHA1 Message Date
Nikolas Klauser
ccb58432e3
[libc++] Use views::reverse to implement ranges::reverse_copy (#177123)
We currently have a custom utility `__reverse_range`, which does
basically the same thing as `views::reverse` and the only place where we
use it is in `ranges::reverse_copy`. Instead of this special utility, we
can simply use `views::reverse`.

This has originally been introduced due to compile time concerns.
However, there doesn't seem to actually be a significant compile time
regression overall.
2026-02-04 20:58:16 +01:00
William Tran-Viet
7b6f1235b9
[libc++] Implement a type-safe iterator for optional (#154239)
Create a new `__capacity_aware_iterator` iterator type which wraps an
existing iterator, takes its container as a template parameter, and
encodes the maximum amount of elements the container can hold. The main
objective is to prevent iterator mixups between different containers
(e.g. `vector`).
2026-02-02 16:18:39 -05:00
Hristo Hristov
503db9859e
[libc++][NFC] Reformat wrap_iter.h (#177127)
As a pre-requisite to https://github.com/llvm/llvm-project/pull/172200
2026-01-22 04:40:28 +02:00
Hristo Hristov
66c65f0132
[libc++][iterator][NFC] Fixed copy&paste mistake in comment (#173879) 2025-12-30 09:06:18 +08: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
fc5e0c071b
[libc++] Simplify most of the segmented iterator optimizations (#164797)
This patch does two things.
(1) It replaces SFINAE with `if constexpr`, avoiding some overload
resolution and unnecessary boilerplate.
(2) It removes an overload from `__for_each_n` to forward to
`__for_each`, since `__for_each` doesn't provide any further
optimizations.
2025-11-07 08:27:55 +01:00
Nikolas Klauser
bb1158f14a
[libc++] Fix LLVM 22 TODOs (#153367)
We've upgraded to LLVM 22 now, so we can remove a bunch of TODOs.
2025-10-30 10:34:41 +01: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
Nikolas Klauser
70b7874ab2
[libc++] Make the naming of the iterator_traits aliases consistent (#161661)
This renames all the `iterator_traits` alises to be
`__iterator_<type-name>`. e.g `iterator_traits<T>::value_type` will be
`__iterator_value_type<T>`.
2025-10-07 14:42:11 +02:00
Nikolas Klauser
34d4f0c136
[libc++][NFC] Use llvm.org/PR to link to bug reports (#156288)
We've built up quite a few links directly to github within the code
base. We should instead use `llvm.org/PR<issue-number>` to link to bugs,
since that is resilient to the bug tracker changing in the future. This
is especially relevant for tests linking to bugs, since they will
probably be there for decades to come. A nice side effect is that these
links are significantly shorter than the GH links, making them much less
of an eyesore.

This patch also replaces a few links that linked to the old bugzilla
instance on llvm.org.
2025-09-04 09:20:02 +02:00
Nikolas Klauser
e8fa13ca4e
[libc++] Split ABI flag for removing iterator bases and removing the second member in reverse_iterator (#143079)
Currently `_LIBCPP_NO_ITERATOR_BASES` controls both whether specific
classes derive from `iterator` and whether `reverse_iterator` has a
second member variable. These two changes are orthogonal though, and one
can be applied in all langauge modes while the other change is only
conforming for C++17 and later.
2025-09-04 09:18:49 +02:00
William Tran-Viet
1c51886920
[libc++] Implement P3168R2: Give optional range support (#149441)
Resolves #105430

- Implement all required pieces of P3168R2
- Leverage existing `wrap_iter` and `bounded_iter` classes to implement
the `optional` regular and hardened iterator type, respectively
- Update documentation to match
2025-08-18 18:04:45 +03:00
Nikolas Klauser
cdb67e1131
[libc++][NFC] Make __is_segmented_iterator a variable template (#149976) 2025-07-25 16:27:34 +02:00
Hui
34b2e934ea
[libc++] Introduce __product_iterator_traits and optimise flat_map::insert (#139454)
Fixes #108624

This allows `flat_map::insert(Iter, Iter)` to directly forward to
underlying containers' `insert(Iter, Iter)`, instead of inserting one
element at a time, when input models "product iterator". atm,
`flat_map::iterator` and `zip_view::iterator` are "product iterator"s.

This gives about almost 10x speed up in my benchmark with -03 (for both
before and after)

```cpp
Benchmark                                                          Time             CPU      Time Old      Time New       CPU Old       CPU New
-----------------------------------------------------------------------------------------------------------------------------------------------
flat_map::insert_product_iterator_flat_map/32                   -0.5028         -0.5320           149            74           149            70
flat_map::insert_product_iterator_flat_map/1024                 -0.8617         -0.8618          3113           430          3112           430
flat_map::insert_product_iterator_flat_map/8192                 -0.8877         -0.8877         26682          2995         26679          2995
flat_map::insert_product_iterator_flat_map/65536                -0.8769         -0.8769        226235         27844        226221         27841
flat_map::insert_product_iterator_zip/32                        -0.5844         -0.5844           162            67           162            67
flat_map::insert_product_iterator_zip/1024                      -0.8754         -0.8754          3427           427          3427           427
flat_map::insert_product_iterator_zip/8192                      -0.8934         -0.8934         28134          3000         28132          3000
flat_map::insert_product_iterator_zip/65536                     -0.8783         -0.8783        229783         27960        229767         27958
OVERALL_GEOMEAN                                                 -0.8319         -0.8332             0             0             0             0
```

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2025-06-28 13:42:50 +01:00
Nikolas Klauser
9db7502d22
[libc++] Move __has_iterator_typedefs to the up-to-C++17 implementation of iterator_traits (#144265)
`__has_iterator_typedefs` is only used in the up-to-C++17 implementation
of `type_traits`. To make that clearer the struct is moved into that
code block.
2025-06-18 15:55:06 +02:00
Nikolas Klauser
1d68abccb5
[libc++] Move _ITER_TRAITS and _ITER_CONCEPT into <__iterator/concepts.h> (#140528)
`_ITER_TRAITS` and `_ITER_CONCEPT` are really implenentation details of
`<__iterator/concetps.h>`, so it makes more sense to put them there than
into `<__iterator/iterator_traits.h>`.
2025-06-06 08:33:15 +02:00
Ksar
b71255705b
[libc++] P2165R4: Update deduction guides for map containers and container adaptors (#136011)
Fixes #135351

This PR update CATD guides to associative containers (`std::map`,
`std::multimap`, `std::unordered_map`, `std::unordered_multimap`,
`std::flat_map`, `std::flat_multimap`).

- Updated template alias for deduction guides for the relevant
associative containers.
- Added a new test to verify the deduction guides with `std::map`,
`std::multimap`, `std::unordered_map`, `std::unordered_multimap`,
`std::flat_map`, `std::flat_multimap`.
2025-05-30 15:17:06 +08:00
Peng Liu
09c266b75d
[libc++] Optimize std::for_each_n for segmented iterators (#135468)
This patch enhances the performance of `std::for_each_n` when used with
segmented iterators, leading to significant performance improvements,
summarized in the tables below. This addresses a subtask of
https://github.com/llvm/llvm-project/issues/102817.
2025-05-21 12:10:50 -04:00
Louis Dionne
e33ca9adc8
[libc++] Reword std::advance assertion message for consistency with ranges::advance (#138749)
As brought up in https://github.com/llvm/llvm-project/pull/133276.
2025-05-07 12:59:38 -04:00
Louis Dionne
d05ab119e1
[libc++] Remove redundant and somewhat confusing assertions around advance() (#133276)
The std::advance function has a clear precondition that it can only be
called with a negative distance when a bidirectional iterator is used.
However, prev() and next() don't have such preconditions explicitly,
they inherit it from calling advance().

This patch removes assertions in prev() and next() that were duplicates
of similar ones in advance(), and removes a copy-pasted comment that was
trying to justify the use of _LIBCPP_ASSERT_PEDANTIC but IMO is creating
confusion with little benefit.
2025-05-06 15:44:26 -04:00
Nikolas Klauser
af9c04fa68
[libc++] Remove _LIBCPP_TEMPLATE_VIS (#134885)
The need for `_LIBCPP_TEMPLATE_VIS` has been removed in #133233.
2025-04-09 23:47:57 +02:00
A. Jiang
ab95005a05
[libc++] P3247R2: Deprecate is_trivial(_v) (#130573)
Requirements on character-like types are updated unconditionally,
because `basic_string` does requires the default-constructibility. It
might be possible to make `basic_string_view` support classes with
non-public trivial default constructor, but this doesn't seem sensible.

libcxxabi's `ItaniumDemangle.h` is also updated to avoid deprecated
features.
2025-04-09 07:40:01 +08:00
Louis Dionne
646ad89108
[libc++] Unify __can_reference and __is_referenceable_v (#133278)
Both traits do the same thing. This patch renames __can_reference to
__referenceable and moves it to the is_referenceable header.
2025-03-29 10:07:31 +01:00
Nikolas Klauser
3b2b918813
[libc++] Use __detected_or_t to implement __has_iterator_{category,concept}_convertible_to (#124456)
This simplifies the implementation a bit.
2025-03-26 08:55:47 +01:00
Nikolas Klauser
fb44f00641
[libc++] Add [[gnu::nodebug]] on type traits (#128502) 2025-03-23 21:01:25 +01:00
Mark de Wever
65f105b6cf
[libc++] Implements LWG3600 Making istream_iterator copy constructor trivial is an ABI break (#127343)
Closes: #105003
2025-03-01 12:29:21 +01:00
Mark de Wever
da618cf0a7
[NFC][libc++] Guard against operator& hijacking. (#128351)
This set usage of operator& instead of std::addressof seems not be easy
to "abuse". Some seem easy to misuse, like basic_ostream::operator<<,
trying to do that results in compilation errors since the `widen`
function is not specialized for the hijacking character type. Hence
there are no tests.
2025-02-27 17:47:34 +01:00
Nikolas Klauser
f69585235e
[libc++] Put _LIBCPP_NODEBUG on all internal aliases (#118710)
This significantly reduces the amount of debug information generated
for codebases using libc++, without hurting the debugging experience.
2025-01-08 11:12:59 -05:00
A. Jiang
b5bc528c14
[libc++] Guard __pad_and_output with _LIBCPP_HAS_LOCALIZATION (#116580)
This fixes errors for no-localization builds (possibly introduced by
#116223).
2024-11-18 17:03:29 +08:00
A. Jiang
9f471fd12b
[libc++][hardening] Constrain construction for __{(static_)bounded,wrap}_iter (#115271)
This PR restricts construction to cases where reference types of
source/destination iterators are (`T&`, `T&`) or (`T&`, `const T&`) (
where `T` can be const).

Fixes #50058.
2024-11-11 23:04:38 +08:00
A. Jiang
1645d99bc9
[libc++][hardening] Use static_assert for __(static_)bounded_iter (#115304)
We can't `static_assert` `__libcpp_is_contiguous_iterator` for
`__wrap_iter` currently because `__wrap_iter` is also used for wrapping
user-defined fancy pointers.

Fixes #115002.
2024-11-08 22:59:21 +08:00
Louis Dionne
427a5cf105
[libc++] Add support for bounded iterators in std::array (#110729)
This patch introduces a new kind of bounded iterator that knows the size
of its valid range at compile-time, as in std::array. This allows computing
the end of the range from the start of the range and the size, which requires
storing only the start of the range in the iterator instead of both the start
and the size (or start and end). The iterator wrapper is otherwise identical
in design to the existing __bounded_iter.

Since this requires changing the type of the iterators returned by
std::array, this new bounded iterator is controlled by an ABI flag.

As a drive-by, centralize the tests for std::array::operator[] and add
missing tests for OOB operator[] on non-empty arrays.

Fixes #70864
2024-11-07 09:23:21 -05:00
Nikolas Klauser
e99c4906e4
[libc++] Granularize <cstddef> includes (#108696) 2024-10-31 02:20:10 +01:00
Hui
a5d919b4b2
[libc++] Disallow std::prev(non_cpp17_bidi_iterator) (#112102)
The std::prev function appeared to work on non Cpp17BidirectionalIterators, however it
behaved strangely by being the identity function. That was extremely misleading and
potentially dangerous, since several recent iterators that are C++20 bidirectional_iterators
don't satisfy the Cpp17BidirectionalIterator named requirement. For example:

    auto zv = std::views::zip(vec1, vec2);
    auto it = zv.begin() + 5;
    auto it2 = std::prev(it); // "it2" will be the same as "it",  instead of the previous one

Here, zip_view::iterator is a c++20 random_access_iterator, but it only satisfies the
Cpp17InputIterator named requirement because its reference type is a proxy type. Hence
`std::prev` would silently accept that iterator but it would do a no-op instead of going
to the previous position.

This patch changes `std::prev(it)` to produce an error at compile-time when instantiated
with a type that is not a Cpp17BidirectionalIterator.

Fixes #109456
2024-10-23 14:42:15 -04:00
Hui
1bbf3a3705
[libc++] Fix reverse_iterator when underlying is c++20 bidirectional_iterator but not Cpp17BidirectionalIterator (#112100)
`reverse_iterator` supports either c++20 `bidirectional_iterator` or
`Cpp17BidirectionalIterator `
http://eel.is/c++draft/reverse.iter.requirements

The current `reverse_iterator` uses `std::prev` in its `operator->`,
which only supports the `Cpp17BidirectionalIterator` properly.

If the underlying iterator is c++20 `bidirectional_iterator` but does
not satisfy the named requirement `Cpp17BidirectionalIterator`,
(examples are `zip_view::iterator`, `flat_map::iterator`), the current
`std::prev` silently compiles but does a no-op and returns the same
iterator back. So `reverse_iterator::operator->` will silently give a
wrong answer.

Even if we fix the behaviour of `std::prev`, at best, we could fail to
compile the code. But this is not ok, because we need to support this
kind of iterators in `reverse_iterator`.

The solution is simply to not use `std::prev`.

---------

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2024-10-19 11:09:25 +01:00
Nikolas Klauser
ba87515fea
[libc++][RFC] Always define internal feature test macros (#89178)
Currently, the library-internal feature test macros are only defined if
the feature is not available, and always have the prefix
`_LIBCPP_HAS_NO_`. This patch changes that, so that they are always
defined and have the prefix `_LIBCPP_HAS_` instead. This changes the
canonical use of these macros to `#if _LIBCPP_HAS_FEATURE`, which means
that using an undefined macro (e.g. due to a missing include) is
diagnosed now. While this is rather unlikely currently, a similar change
in `<__configuration/availability.h>` caught a few bugs. This also
improves readability, since it removes the double-negation of `#ifndef
_LIBCPP_HAS_NO_FEATURE`.

The current patch only touches the macros defined in `<__config>`. If
people are happy with this approach, I'll make a follow-up PR to also
change the macros defined in `<__config_site>`.
2024-10-12 09:49:52 +02:00
Marc Auberer
e9c0c6604e
[libc++] Add [[nodiscard]] to std::prev and std::next (#109550)
Add `[[nodiscard]]` attribute to `std::prev` and `std::next`. Those are
potential pitfalls for users who might think they mutate the iterator.

Fixes #109452
2024-09-28 22:56:11 +02:00
Louis Dionne
09e3a36058
[libc++][modules] Fix missing and incorrect includes (#108850)
This patch adds a large number of missing includes in the libc++ headers
and the test suite. Those were found as part of the effort to move
towards a mostly monolithic top-level std module.
2024-09-16 15:06:20 -04:00
NoumanAmir-10xe
6776d65cea
[libc++] Implement LWG3953 (#107535)
Closes #105303
2024-09-09 14:49:22 -04:00
Louis Dionne
d6832a611a
[libc++][modules] Modularize <cstddef> (#107254)
Many headers include `<cstddef>` just for size_t, and pulling in
additional content (e.g. the traits used for std::byte) is unnecessary.
To solve this problem, this patch splits up `<cstddef>` into
subcomponents so that headers can include only the parts that they
actually require.

This has the added benefit of making the modules build a lot stricter
with respect to IWYU, and also providing a canonical location where we
define `std::size_t` and friends (which were previously defined in
multiple headers like `<cstddef>` and `<ctime>`).

After this patch, there's still many places in the codebase where we
include `<cstddef>` when `<__cstddef/size_t.h>` would be sufficient.
This patch focuses on removing `<cstddef>` includes from __type_traits
to make these headers non-circular with `<cstddef>`. Additional
refactorings can be tackled separately.
2024-09-05 08:28:33 -04:00
A. Jiang
026210e80d
[libc++][ranges] P2609R3: Relaxing Ranges Just A Smidge (#101715)
This patch implements https://wg21.link/p2609r3.
The test code was originally authored by JMazurkiewicz.

Notes:
- P2609R3 is not officially a Defect Report, but MSVC STL
  implements it in C++20 mode.

  Moreover, P2609R3 and P2997R1 touch exactly the same set of
  concepts, and MSVC STL and libc++ have already treated P2997R1
  as a DR.

- This patch also adjusted feature-test macros.
  + In C++20 mode, the value of __cpp_lib_ranges should be `202110L` because
    - `202202L` covers `range_adaptor_closure` (P2387R3), and
    - `202207L` covers move-only types in range adaptors (P2494R2).
  And all of these changes are only available since C++23 mode.

  + In C++23 mode, the value should be `202406L` because
    - `202211L` covers removing poison overloads (P2602R2),
    - `202302L` covers relaxing projected value types (P2609R3), and
    - `202406L` covers removing requirements on `iter_common_reference_t` (P2997R1).
  And all of these changes are already or being implemented.

Fixes #105253.

Co-authored-by: Jakub Mazurkiewicz <mazkuba3@gmail.com>
2024-08-28 08:55:44 -04:00
Christopher Di Bella
d10dc5a06f
[libc++] Remove dedicated namespaces for ranges functions (#76543)
We originally put implementation-detail function objects into individual
namespaces for `std::ranges` without a good reason for doing so. This
practice was continued, presumably because there was prior art. Since
there's no reason to keep these namespaces, this commit removes them,
which will slightly impact binary size.

This commit does not apply to CPOs, some of which need additional work.
2024-08-01 08:54:06 -04:00
Mark de Wever
39b6900852
[libc++][spaceship] Removes unneeded relational operators. (#100441)
This is a followup of https://github.com/llvm/llvm-project/pull/99343.
Since that patch was quite late in the LLVM-19 release cycle some of the
unneeded relational operator were not removed in C++20.

This removes them and gives the change a bit more "baking" time, just in
case there are issues with this change in user code. This change is
intended to be an NFC.
2024-07-30 19:06:15 +02:00
Mark de Wever
8d3252a898
[libc++][spaceship] Implements X::iterator container requirements. (#99343)
This implements the requirements for the container iterator requirements
for array, deque, vector, and `vector<bool>`.

Implements:
- LWG3352 strong_equality isn't a thing

Implements parts of:
- P1614R2 The Mothership has Landed

Fixes: https://github.com/llvm/llvm-project/issues/62486
2024-07-24 19:42:48 +02:00
David Benjamin
bcf9fb9802
[libc++][hardening] Use bounded iterators in std::vector and std::string (#78929)
~~NB: This PR depends on #78876. Ignore the first commit when reviewing,
and don't merge it until #78876 is resolved. When/if #78876 lands, I'll
clean this up.~~

This partially restores parity with the old, since removed debug build.
We now can re-enable a bunch of the disabled tests. Some things of note:

- `bounded_iter`'s converting constructor has never worked. It needs a
friend declaration to access the other `bound_iter` instantiation's
private fields.

- The old debug iterators also checked that callers did not try to
compare iterators from different objects. `bounded_iter` does not
currently do this, so I've left those disabled. However, I think we
probably should add those. See
https://github.com/llvm/llvm-project/issues/78771#issuecomment-1902999181

- The `std::vector` iterators are bounded up to capacity, not size. This
makes for a weaker safety check. This is because the STL promises not to
invalidate iterators when appending up to the capacity. Since we cannot
retroactively update all the iterators on `push_back()`, I've instead
sized it to the capacity. This is not as good, but at least will stop
the iterator from going off the end of the buffer.

There was also no test for this, so I've added one in the `std`
directory.

- `std::string` has two ambiguities to deal with. First, I opted not to
size it against the capacity. https://eel.is/c++draft/string.require#4
says iterators are invalidated on an non-const operation. Second,
whether the iterator can reach the NUL terminator. The previous debug
tests and the special-case in https://eel.is/c++draft/string.access#2
suggest no. If either of these causes widespread problems, I figure we
can revisit.

- `resize_and_overwrite.pass.cpp` assumed `std::string`'s iterator
supported `s.begin().base()`, but I see no promise of this in the
standard. GCC also doesn't support this. I fixed the test to use
`std::to_address`.

- `alignof.compile.pass.cpp`'s pointer isn't enough of a real pointer.
(It needs to satisfy `NullablePointer`, `LegacyRandomAccessIterator`,
and `LegacyContiguousIterator`.) `__bounded_iter` seems to instantiate
enough to notice. I've added a few more bits to satisfy it.

Fixes #78805
2024-07-22 22:44:25 -07:00
Hristo Hristov
cb3de24b5c
[libc++][iterator][ranges] P2997R1: Removing the common reference requirement from the indirectly invocable concepts (#98817)
Implements as DR against C++20: https://wg21.link/P2997R1

References:
- https://eel.is/c++draft/indirectcallable.indirectinvocable
- https://eel.is/c++draft/version.syn#header:%3cversion%3e

---------

Co-authored-by: Hristo Hristov <zingam@outlook.com>
2024-07-18 14:54:29 +03:00
Nikolas Klauser
4814628531
[libc++][NFC] Replace conditional<>::type with __conditional_t (#96745)
`__conditional_t` is move efficient than `conditional`, since it avoids
instantiating a template for every type combination.
2024-06-29 01:27:17 +02:00
Nikolas Klauser
1f98ac095e
[libc++][NFC] Replace _NOEXCEPT and _LIBCPP_CONSTEXPR macros with the keywords in C++11 code (#96387) 2024-06-23 22:03:41 +02:00
Louis Dionne
e2c2ffbe7a
[libc++][NFC] Run clang-format on libcxx/include again (#95874)
As time went by, a few files have become mis-formatted w.r.t.
clang-format. This was made worse by the fact that formatting was not
being enforced in extensionless headers. This commit simply brings all
of libcxx/include in-line with clang-format again.

We might have to do this from time to time as we update our clang-format
version, but frankly this is really low effort now that we've formatted
everything once.
2024-06-18 09:13:45 -04:00
Xiaoyang Liu
f03430f5e3
[libc++] LWG3672: common_iterator::operator->() should return by value (#87899)
## Abstract

This pull request implements LWG3672: `common_iterator::operator->()`
should return by value. The current implementation specifies that this
function should return the underlying pointer by reference (`T*
const&`), but it would be more intuitive to return it by value (`T*`).

## Reference

- [Draft C++ Standard:
[common.iter.access]](https://eel.is/c++draft/common.iter.access)
- [LWG3672](https://cplusplus.github.io/LWG/issue3672)
2024-05-16 19:25:04 +02:00