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.
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.
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
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
`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>
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>`.
Add `[[nodiscard]]` attribute to `std::prev` and `std::next`. Those are
potential pitfalls for users who might think they mutate the iterator.
Fixes#109452
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.
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.
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>
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.
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.
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
~~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
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.
## 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)
This pull request implements LWG3643: Missing constexpr in
std::counted_iterator. Specifically, one overload of
std::counted_operator::operator++ was not marked as constexpr,
despite being eligible for it after the introduction of try-block
support in constexpr functions in C++20.
Currently, the bounds check in `std::ranges::advance(it, n, s)` is done
_before_ `n` is checked. This results in one extra, unneeded bounds
check.
Thus, `std::ranges::advance(it, 1, s)` currently is _not_ simply
equivalent to:
```c++
if (it != s) {
++it;
}
```
This difference in behavior matters when the check involves some
"expensive" logic. For example, the `==` operator of
`std::istreambuf_iterator` may actually have to read the underlying
`streambuf`.
Swapping around the checks in the `while` results in the expected
behavior.
These headers have become very small by using compiler builtins, often
containing only two declarations. This merges these headers, since
there doesn't seem to be much of a benefit keeping them separate.
Specifically, `is_{,_nothrow,_trivially}{assignable,constructible}` are
kept and the `copy`, `move` and `default` versions of these type traits
are moved in to the respective headers.
Previously, `__bounded_iter` only checked `operator*`. It allowed the
pointer to go out of bounds with `operator++`, etc., and relied on
`operator*` (which checked `begin <= current < end`) to handle
everything. This has several unfortunate consequences:
First, pointer arithmetic is UB if it goes out of bounds. So by the time
`operator*` checks, it may be too late and the optimizer may have done
something bad. Checking both operations is safer.
Second, `std::copy` and friends currently bypass bounded iterator
checks. I think the only hope we have to fix this is to key on `iter +
n` doing a check. See #78771 for further discussion. Note this PR is not
sufficient to fix this. It adds the output bounds check, but ends up
doing it after the `memmove`, which is too late.
Finally, doing these checks is actually *more* optimizable. See #78829,
which is fixed by this PR. Keeping the iterator always in bounds means
`operator*` can rely on some invariants and only needs to check `current
!= end`. This aligns better with common iterator patterns, which use
`!=` instead of `<`, so it's easier to delete checks with local
reasoning.
See https://godbolt.org/z/vEWrWEf8h for how this new `__bounded_iter`
impacts compiler output. The old `__bounded_iter` injected checks inside
the loops for all the `sum()` functions, which not only added a check
inside a loop, but also impeded Clang's vectorization. The new
`__bounded_iter` allows all the checks to be optimized out and we emit
the same code as if it wasn't here.
Not everything is ideal however. `add_and_deref` ends up emitting two
comparisons now instead of one. This is because a missed optimization in
Clang. I've filed #78875 for that. I suspect (with no data) that this PR
is still a net performance win because impeding ranged-for loops is
particularly egregious. But ideally we'd fix the optimizer and make
`add_and_deref` fine too.
There's also something funny going on with `std::ranges::find` which I
have not yet figured out yet, but I suspect there are some further
missed optimization opportunities.
Fixes#78829.
(CC @danakj)
std::string_view and std::array iterators don't have to be raw pointers,
and in fact other implementations don't represent them as raw pointers.
Them being raw pointers in libc++ makes it easier for users to write
non-portable code. This is bad in itself, but this is even worse when
considering efforts like hardening where we want an easy ability to
swap for a different iterator type. If users depend on iterators being
raw pointers, this becomes a build break.
Hence, this patch enables the use of __wrap_iter in the unstable ABI,
creating a long term path towards making this the default. This patch
may break code that assumes these iterators are raw pointers for
people compiling with the unstable ABI.
This patch also removes several assumptions that array iterators are
raw pointers in the code base and in the test suite.
We recently noticed that the unwrap_iter.h file was pushing macros, but
it was pushing them again instead of popping them at the end of the
file. This led to libc++ basically swallowing any custom definition of
these macros in user code:
#define min HELLO
#include <algorithm>
// min is not HELLO anymore, it's not defined
While investigating this issue, I noticed that our push/pop pragmas were
actually entirely wrong too. Indeed, instead of pushing macros like
`move`, we'd push `move(int, int)` in the pragma, which is not a valid
macro name. As a result, we would not actually push macros like `move`
-- instead we'd simply undefine them. This led to the following code not
working:
#define move HELLO
#include <algorithm>
// move is not HELLO anymore
Fixing the pragma push/pop incantations led to a cascade of issues
because we use identifiers like `move` in a large number of places, and
all of these headers would now need to do the push/pop dance.
This patch fixes all these issues. First, it adds a check that we don't
swallow important names like min, max, move or refresh as explained
above. This is done by augmenting the existing
system_reserved_names.gen.py test to also check that the macros are what
we expect after including each header.
Second, it fixes the push/pop pragmas to work properly and adds missing
pragmas to all the files I could detect a failure in via the newly added
test.
rdar://121365472
Also introduce `_LIBCPP_ASSERT_PEDANTIC` for assertions violating which
results in a no-op or other benign behavior, but which may nevertheless
indicate a bug in the invoking code.
This patch runs clang-format on all of libcxx/include and libcxx/src, in
accordance with the RFC discussed at [1]. Follow-up patches will format
the benchmarks, the test suite and remaining parts of the code. I'm
splitting this one into its own patch so the diff is a bit easier to
review.
This patch was generated with:
find libcxx/include libcxx/src -type f \
| grep -v 'module.modulemap.in' \
| grep -v 'CMakeLists.txt' \
| grep -v 'README.txt' \
| grep -v 'libcxx.imp' \
| grep -v '__config_site.in' \
| xargs clang-format -i
A Git merge driver is available in libcxx/utils/clang-format-merge-driver.sh
to help resolve merge and rebase issues across these formatting changes.
[1]: https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
This is in preparation for clang-formatting the whole code base. These
annotations are required either to avoid clang-format bugs or because
the manually formatted code is significantly more readable than the
clang-formatted alternative. All in all, it seems like very few
annotations are required, which means that clang-format is doing a very
good job in most cases.
In preparation for running clang-format on the whole code base, we are
also removing mentions of the legacy _LIBCPP_INLINE_VISIBILITY macro in
favor of the newer _LIBCPP_HIDE_FROM_ABI.
We're still leaving the definition of _LIBCPP_INLINE_VISIBILITY to avoid
creating needless breakage in case some older patches are checked-in
with mentions of the old macro. After we branch for LLVM 18, we can do
another pass to clean up remaining uses of the macro that might have
gotten introduced by mistake (if any) and remove the macro itself at the
same time. This is just a minor convenience to smooth out the transition
as much as possible.
See
https://discourse.llvm.org/t/rfc-clang-formatting-all-of-libc-once-and-for-all
for the clang-format proposal.
There's no reason for them to be public AFAICT. I came across this while
auditing the code bases for places where we'd be using
[[no_unique_address]] incorrectly. Since one of these members is marked
as [[no_unique_address]], this is an extra reason to keep this private
to ensure the member isn't escaped anywhere.
We did not mark std::begin/std::end as noexcept for C-style arrays, we
did not have conditional noexcept on cbegin/cend, and we did not mark
array cbegin/cend as constexpr in all Standard modes. Since this is a
LWG issue, we should implement it as a DR in all Standard modes as
usual.
This patch fixes these issues and adds test coverage. Fixes#67471.
Notice that because Holder<Incomplete> is _possible_ to complete, but
_unsafe_ to complete, that means that Holder<Incomplete>* is basically
not an iterator and it's not even safe to ask if
input_iterator<Holder<Incomplete>*> because that _will_ necessarily
complete the type. So it's totally expected that we still cannot safely
ask e.g.
static_assert(std::indirect_unary_predicate<bool(&)(Holder<Incomplete>&),
Holder<Incomplete>*>);
or even
static_assert(!std::indirect_unary_predicate<int, Holder<Incomplete>*>);
This was originally uploaded as https://reviews.llvm.org/D119029 and I
picked it up here as part of the Github PR transition.
Co-authored-by: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
This brings most of the enable_ifs in libc++ to the same style. It also has the nice side-effect of reducing the size of names of these symbols, since the arguments don't get mangled anymore.
Reviewed By: #libc, Mordante
Spies: Mordante, libcxx-commits
Differential Revision: https://reviews.llvm.org/D157748