diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
| commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
| tree | 1d56ae694a6de602e348dd80165cf881a36600ed /libcxx/include/__iterator | |
| parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
Diffstat (limited to 'libcxx/include/__iterator')
38 files changed, 952 insertions, 237 deletions
diff --git a/libcxx/include/__iterator/access.h b/libcxx/include/__iterator/access.h index 5e0d6b35153b..7abd4c5573d6 100644 --- a/libcxx/include/__iterator/access.h +++ b/libcxx/include/__iterator/access.h @@ -14,7 +14,7 @@ #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/advance.h b/libcxx/include/__iterator/advance.h index 5b0e97d76be9..4b8b0dc970a1 100644 --- a/libcxx/include/__iterator/advance.h +++ b/libcxx/include/__iterator/advance.h @@ -10,19 +10,20 @@ #ifndef _LIBCPP___ITERATOR_ADVANCE_H #define _LIBCPP___ITERATOR_ADVANCE_H +#include <__assert> #include <__config> -#include <__debug> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iterator_traits.h> #include <__utility/move.h> +#include <__utility/unreachable.h> #include <concepts> #include <cstdlib> #include <limits> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -64,7 +65,7 @@ void advance(_InputIter& __i, _Distance __orig_n) { _VSTD::__advance(__i, __n, typename iterator_traits<_InputIter>::iterator_category()); } -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) // [range.iter.op.advance] @@ -116,47 +117,46 @@ public: } } - // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound) denotes a range. + // Preconditions: Either `assignable_from<I&, S> || sized_sentinel_for<S, I>` is modeled, or [i, bound_sentinel) denotes a range. template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr void operator()(_Ip& __i, _Sp __bound) const { - // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound)`. + _LIBCPP_HIDE_FROM_ABI constexpr void operator()(_Ip& __i, _Sp __bound_sentinel) const { + // If `I` and `S` model `assignable_from<I&, S>`, equivalent to `i = std::move(bound_sentinel)`. if constexpr (assignable_from<_Ip&, _Sp>) { - __i = _VSTD::move(__bound); + __i = _VSTD::move(__bound_sentinel); } - // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound - i)`. + // Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent to `ranges::advance(i, bound_sentinel - i)`. else if constexpr (sized_sentinel_for<_Sp, _Ip>) { - (*this)(__i, __bound - __i); + (*this)(__i, __bound_sentinel - __i); } - // Otherwise, while `bool(i != bound)` is true, increments `i`. + // Otherwise, while `bool(i != bound_sentinel)` is true, increments `i`. else { - while (__i != __bound) { + while (__i != __bound_sentinel) { ++__i; } } } // Preconditions: - // * If `n > 0`, [i, bound) denotes a range. - // * If `n == 0`, [i, bound) or [bound, i) denotes a range. - // * If `n < 0`, [bound, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`. - // Returns: `n - M`, where `M` is the difference between the the ending and starting position. + // * If `n > 0`, [i, bound_sentinel) denotes a range. + // * If `n == 0`, [i, bound_sentinel) or [bound_sentinel, i) denotes a range. + // * If `n < 0`, [bound_sentinel, i) denotes a range, `I` models `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`. + // Returns: `n - M`, where `M` is the difference between the ending and starting position. template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, _Sp __bound) const { + _LIBCPP_HIDE_FROM_ABI constexpr iter_difference_t<_Ip> operator()(_Ip& __i, iter_difference_t<_Ip> __n, + _Sp __bound_sentinel) const { _LIBCPP_ASSERT((__n >= 0) || (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>), "If `n < 0`, then `bidirectional_iterator<I> && same_as<I, S>` must be true."); // If `S` and `I` model `sized_sentinel_for<S, I>`: if constexpr (sized_sentinel_for<_Sp, _Ip>) { - // If |n| >= |bound - i|, equivalent to `ranges::advance(i, bound)`. + // If |n| >= |bound_sentinel - i|, equivalent to `ranges::advance(i, bound_sentinel)`. // __magnitude_geq(a, b) returns |a| >= |b|, assuming they have the same sign. auto __magnitude_geq = [](auto __a, auto __b) { return __a == 0 ? __b == 0 : __a > 0 ? __a >= __b : __a <= __b; }; - if (const auto __M = __bound - __i; __magnitude_geq(__n, __M)) { - (*this)(__i, __bound); + if (const auto __M = __bound_sentinel - __i; __magnitude_geq(__n, __M)) { + (*this)(__i, __bound_sentinel); return __n - __M; } @@ -164,16 +164,16 @@ public: (*this)(__i, __n); return 0; } else { - // Otherwise, if `n` is non-negative, while `bool(i != bound)` is true, increments `i` but at + // Otherwise, if `n` is non-negative, while `bool(i != bound_sentinel)` is true, increments `i` but at // most `n` times. - while (__i != __bound && __n > 0) { + while (__i != __bound_sentinel && __n > 0) { ++__i; --__n; } - // Otherwise, while `bool(i != bound)` is true, decrements `i` but at most `-n` times. + // Otherwise, while `bool(i != bound_sentinel)` is true, decrements `i` but at most `-n` times. if constexpr (bidirectional_iterator<_Ip> && same_as<_Ip, _Sp>) { - while (__i != __bound && __n < 0) { + while (__i != __bound_sentinel && __n < 0) { --__i; ++__n; } @@ -181,7 +181,7 @@ public: return __n; } - _LIBCPP_UNREACHABLE(); + __libcpp_unreachable(); } }; @@ -192,7 +192,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/back_insert_iterator.h b/libcxx/include/__iterator/back_insert_iterator.h index 844babe5c5ed..7bbf5b09e0e5 100644 --- a/libcxx/include/__iterator/back_insert_iterator.h +++ b/libcxx/include/__iterator/back_insert_iterator.h @@ -18,7 +18,7 @@ #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -55,6 +55,8 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*() {return *this;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++() {return *this;} _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator operator++(int) {return *this;} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17 _Container* __get_container() const { return container; } }; template <class _Container> diff --git a/libcxx/include/__iterator/bounded_iter.h b/libcxx/include/__iterator/bounded_iter.h new file mode 100644 index 000000000000..a395e2b638eb --- /dev/null +++ b/libcxx/include/__iterator/bounded_iter.h @@ -0,0 +1,229 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_BOUNDED_ITER_H +#define _LIBCPP___ITERATOR_BOUNDED_ITER_H + +#include <__assert> +#include <__config> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__utility/move.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Iterator wrapper that carries the valid range it is allowed to access. +// +// This is a simple iterator wrapper for contiguous iterators that points +// within a [begin, end) range and carries these bounds with it. The iterator +// ensures that it is pointing within that [begin, end) range when it is +// dereferenced. +// +// Arithmetic operations are allowed and the bounds of the resulting iterator +// are not checked. Hence, it is possible to create an iterator pointing outside +// its range, but it is not possible to dereference it. +template <class _Iterator, class = __enable_if_t< __is_cpp17_contiguous_iterator<_Iterator>::value > > +struct __bounded_iter { + using value_type = typename iterator_traits<_Iterator>::value_type; + using difference_type = typename iterator_traits<_Iterator>::difference_type; + using pointer = typename iterator_traits<_Iterator>::pointer; + using reference = typename iterator_traits<_Iterator>::reference; + using iterator_category = typename iterator_traits<_Iterator>::iterator_category; +#if _LIBCPP_STD_VER > 17 + using iterator_concept = contiguous_iterator_tag; +#endif + + // Create a singular iterator. + // + // Such an iterator does not point to any object and is conceptually out of bounds, so it is + // not dereferenceable. Observing operations like comparison and assignment are valid. + _LIBCPP_HIDE_FROM_ABI __bounded_iter() = default; + + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter(__bounded_iter&&) = default; + + template <class _OtherIterator, class = __enable_if_t< is_convertible<_OtherIterator, _Iterator>::value > > + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter(__bounded_iter<_OtherIterator> const& __other) _NOEXCEPT + : __current_(__other.__current_), + __begin_(__other.__begin_), + __end_(__other.__end_) {} + + // Assign a bounded iterator to another one, rebinding the bounds of the iterator as well. + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter const&) = default; + _LIBCPP_HIDE_FROM_ABI __bounded_iter& operator=(__bounded_iter&&) = default; + +private: + // Create an iterator wrapping the given iterator, and whose bounds are described + // by the provided [begin, end) range. + // + // This constructor does not check whether the resulting iterator is within its bounds. + // However, it does check that the provided [begin, end) range is a valid range (that + // is, begin <= end). + // + // Since it is non-standard for iterators to have this constructor, __bounded_iter must + // be created via `std::__make_bounded_iter`. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit __bounded_iter( + _Iterator __current, _Iterator __begin, _Iterator __end) + : __current_(__current), __begin_(__begin), __end_(__end) { + _LIBCPP_ASSERT(__begin <= __end, "__bounded_iter(current, begin, end): [begin, end) is not a valid range"); + } + + template <class _It> + friend _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It, _It, _It); + +public: + // Dereference and indexing operations. + // + // These operations check that the iterator is dereferenceable, that is within [begin, end). + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator*() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator*: Attempt to dereference an out-of-range iterator"); + return *__current_; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 pointer operator->() const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_), "__bounded_iter::operator->: Attempt to dereference an out-of-range iterator"); + return std::__to_address(__current_); + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 reference operator[](difference_type __n) const _NOEXCEPT { + _LIBCPP_ASSERT( + __in_bounds(__current_ + __n), "__bounded_iter::operator[]: Attempt to index an iterator out-of-range"); + return __current_[__n]; + } + + // Arithmetic operations. + // + // These operations do not check that the resulting iterator is within the bounds, since that + // would make it impossible to create a past-the-end iterator. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator++() _NOEXCEPT { + ++__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter operator++(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator--() _NOEXCEPT { + --__current_; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter operator--(int) _NOEXCEPT { + __bounded_iter __tmp(*this); + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator+=(difference_type __n) _NOEXCEPT { + __current_ += __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter + operator+(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter + operator+(difference_type __n, __bounded_iter const& __self) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp += __n; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __bounded_iter& operator-=(difference_type __n) _NOEXCEPT { + __current_ -= __n; + return *this; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend __bounded_iter + operator-(__bounded_iter const& __self, difference_type __n) _NOEXCEPT { + __bounded_iter __tmp(__self); + __tmp -= __n; + return __tmp; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 friend difference_type + operator-(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ - __y.__current_; + } + + // Comparison operations. + // + // These operations do not check whether the iterators are within their bounds. + // The valid range for each iterator is also not considered as part of the comparison, + // i.e. two iterators pointing to the same location will be considered equal even + // if they have different validity ranges. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator==(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ == __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator!=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ != __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ < __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ > __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator<=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ <= __y.__current_; + } + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR friend bool + operator>=(__bounded_iter const& __x, __bounded_iter const& __y) _NOEXCEPT { + return __x.__current_ >= __y.__current_; + } + +private: + // Return whether the given iterator is in the bounds of this __bounded_iter. + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool __in_bounds(_Iterator const& __iter) const { + return __iter >= __begin_ && __iter < __end_; + } + + template <class> + friend struct pointer_traits; + _Iterator __current_; // current iterator + _Iterator __begin_, __end_; // valid range represented as [begin, end) +}; + +template <class _It> +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __bounded_iter<_It> __make_bounded_iter(_It __it, _It __begin, _It __end) { + return __bounded_iter<_It>(std::move(__it), std::move(__begin), std::move(__end)); +} + +#if _LIBCPP_STD_VER <= 17 +template <class _Iterator> +struct __is_cpp17_contiguous_iterator<__bounded_iter<_Iterator> > : true_type {}; +#endif + +template <class _Iterator> +struct pointer_traits<__bounded_iter<_Iterator> > { + using pointer = __bounded_iter<_Iterator>; + using element_type = typename pointer_traits<_Iterator>::element_type; + using difference_type = typename pointer_traits<_Iterator>::difference_type; + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static element_type* to_address(pointer __it) _NOEXCEPT { + return std::__to_address(__it.__current_); + } +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H diff --git a/libcxx/include/__iterator/common_iterator.h b/libcxx/include/__iterator/common_iterator.h index 68309ee08b30..abcc0b675e63 100644 --- a/libcxx/include/__iterator/common_iterator.h +++ b/libcxx/include/__iterator/common_iterator.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H #define _LIBCPP___ITERATOR_COMMON_ITERATOR_H +#include <__assert> #include <__config> -#include <__debug> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> @@ -22,12 +22,12 @@ #include <variant> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 template<class _Iter> concept __can_use_postfix_proxy = @@ -37,31 +37,18 @@ concept __can_use_postfix_proxy = template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> requires (!same_as<_Iter, _Sent> && copyable<_Iter>) class common_iterator { - class __proxy { - friend common_iterator; - - iter_value_t<_Iter> __value; - // We can move __x because the only caller verifies that __x is not a reference. - constexpr __proxy(iter_reference_t<_Iter>&& __x) - : __value(_VSTD::move(__x)) {} - - public: + struct __proxy { constexpr const iter_value_t<_Iter>* operator->() const noexcept { - return _VSTD::addressof(__value); + return _VSTD::addressof(__value_); } + iter_value_t<_Iter> __value_; }; - class __postfix_proxy { - friend common_iterator; - - iter_value_t<_Iter> __value; - constexpr __postfix_proxy(iter_reference_t<_Iter>&& __x) - : __value(_VSTD::forward<iter_reference_t<_Iter>>(__x)) {} - - public: + struct __postfix_proxy { constexpr const iter_value_t<_Iter>& operator*() const noexcept { - return __value; + return __value_; } + iter_value_t<_Iter> __value_; }; public: @@ -133,7 +120,7 @@ public: auto&& __tmp = *_VSTD::__unchecked_get<_Iter>(__hold_); return _VSTD::addressof(__tmp); } else { - return __proxy(*_VSTD::__unchecked_get<_Iter>(__hold_)); + return __proxy{*_VSTD::__unchecked_get<_Iter>(__hold_)}; } } @@ -148,11 +135,11 @@ public: auto __tmp = *this; ++*this; return __tmp; - } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __referenceable; } || + } else if constexpr (requires (_Iter& __i) { { *__i++ } -> __can_reference; } || !__can_use_postfix_proxy<_Iter>) { return _VSTD::__unchecked_get<_Iter>(__hold_)++; } else { - __postfix_proxy __p(**this); + auto __p = __postfix_proxy{**this}; ++*this; return __p; } @@ -276,7 +263,7 @@ struct iterator_traits<common_iterator<_Iter, _Sent>> { using reference = iter_reference_t<_Iter>; }; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h index f6d092c75d48..bd68889333ce 100644 --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -21,12 +21,12 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [iterator.concept.readable] template<class _In> @@ -90,7 +90,7 @@ concept incrementable = template<class _Ip> concept input_or_output_iterator = requires(_Ip __i) { - { *__i } -> __referenceable; + { *__i } -> __can_reference; } && weakly_incrementable<_Ip>; @@ -254,10 +254,26 @@ concept indirectly_movable_storable = constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> && assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>; +template<class _In, class _Out> +concept indirectly_copyable = + indirectly_readable<_In> && + indirectly_writable<_Out, iter_reference_t<_In>>; + +template<class _In, class _Out> +concept indirectly_copyable_storable = + indirectly_copyable<_In, _Out> && + indirectly_writable<_Out, iter_value_t<_In>&> && + indirectly_writable<_Out, const iter_value_t<_In>&> && + indirectly_writable<_Out, iter_value_t<_In>&&> && + indirectly_writable<_Out, const iter_value_t<_In>&&> && + copyable<iter_value_t<_In>> && + constructible_from<iter_value_t<_In>, iter_reference_t<_In>> && + assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>; + // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle // (both iter_swap and indirectly_swappable require indirectly_readable). -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h index aaab3ac77777..b0f5c66ecf21 100644 --- a/libcxx/include/__iterator/counted_iterator.h +++ b/libcxx/include/__iterator/counted_iterator.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H #define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H +#include <__assert> #include <__config> -#include <__debug> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> #include <__iterator/incrementable_traits.h> @@ -25,12 +25,12 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 template<class> struct __counted_iterator_concept {}; @@ -65,7 +65,7 @@ class counted_iterator , public __counted_iterator_value_type<_Iter> { public: - [[no_unique_address]] _Iter __current_ = _Iter(); + _LIBCPP_NO_UNIQUE_ADDRESS _Iter __current_ = _Iter(); iter_difference_t<_Iter> __count_ = 0; using iterator_type = _Iter; @@ -296,7 +296,7 @@ struct iterator_traits<counted_iterator<_Iter>> : iterator_traits<_Iter> { add_pointer_t<iter_reference_t<_Iter>>, void>; }; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/data.h b/libcxx/include/__iterator/data.h index 5e4946cc10b4..88eb752b642e 100644 --- a/libcxx/include/__iterator/data.h +++ b/libcxx/include/__iterator/data.h @@ -15,7 +15,7 @@ #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/default_sentinel.h b/libcxx/include/__iterator/default_sentinel.h index e12a5909ccf7..669032aa9729 100644 --- a/libcxx/include/__iterator/default_sentinel.h +++ b/libcxx/include/__iterator/default_sentinel.h @@ -13,17 +13,17 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 struct default_sentinel_t { }; inline constexpr default_sentinel_t default_sentinel{}; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/distance.h b/libcxx/include/__iterator/distance.h index faab03492389..8819078958d3 100644 --- a/libcxx/include/__iterator/distance.h +++ b/libcxx/include/__iterator/distance.h @@ -20,7 +20,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -52,7 +52,7 @@ distance(_InputIter __first, _InputIter __last) return _VSTD::__distance(__first, __last, typename iterator_traits<_InputIter>::iterator_category()); } -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) // [range.iter.op.distance] @@ -100,7 +100,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/empty.h b/libcxx/include/__iterator/empty.h index 39cd560a276f..748ca9ecbd59 100644 --- a/libcxx/include/__iterator/empty.h +++ b/libcxx/include/__iterator/empty.h @@ -15,7 +15,7 @@ #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/erase_if_container.h b/libcxx/include/__iterator/erase_if_container.h index 08f6e2248239..d7c71a947a2b 100644 --- a/libcxx/include/__iterator/erase_if_container.h +++ b/libcxx/include/__iterator/erase_if_container.h @@ -13,7 +13,7 @@ #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/front_insert_iterator.h b/libcxx/include/__iterator/front_insert_iterator.h index b229a99f1104..69b2d32d077a 100644 --- a/libcxx/include/__iterator/front_insert_iterator.h +++ b/libcxx/include/__iterator/front_insert_iterator.h @@ -18,7 +18,7 @@ #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h index 3b68acc9bc51..ef5f5110a30e 100644 --- a/libcxx/include/__iterator/incrementable_traits.h +++ b/libcxx/include/__iterator/incrementable_traits.h @@ -15,12 +15,12 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [incrementable.traits] template<class> struct incrementable_traits {}; @@ -65,7 +65,7 @@ using iter_difference_t = typename conditional_t<__is_primary_template<iterator_ incrementable_traits<remove_cvref_t<_Ip> >, iterator_traits<remove_cvref_t<_Ip> > >::difference_type; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/indirectly_comparable.h b/libcxx/include/__iterator/indirectly_comparable.h index 3bafc56f926f..868190fc48da 100644 --- a/libcxx/include/__iterator/indirectly_comparable.h +++ b/libcxx/include/__iterator/indirectly_comparable.h @@ -15,15 +15,19 @@ #include <__iterator/concepts.h> #include <__iterator/projected.h> +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_HAS_NO_CONCEPTS +#if _LIBCPP_STD_VER > 17 template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity> concept indirectly_comparable = indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>; -#endif // _LIBCPP_HAS_NO_CONCEPTS +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/insert_iterator.h b/libcxx/include/__iterator/insert_iterator.h index 2f18f5f12162..8b313f2a85bb 100644 --- a/libcxx/include/__iterator/insert_iterator.h +++ b/libcxx/include/__iterator/insert_iterator.h @@ -19,12 +19,12 @@ #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) template <class _Container> using __insert_iterator_iter_t = ranges::iterator_t<_Container>; #else diff --git a/libcxx/include/__iterator/istream_iterator.h b/libcxx/include/__iterator/istream_iterator.h index 979d714edf5d..a056961c10a8 100644 --- a/libcxx/include/__iterator/istream_iterator.h +++ b/libcxx/include/__iterator/istream_iterator.h @@ -11,13 +11,15 @@ #define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H #include <__config> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include <cstddef> #include <iosfwd> // for forward declarations of char_traits and basic_istream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -45,6 +47,9 @@ private: _Tp __value_; public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istream_iterator() : __in_stream_(nullptr), __value_() {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr istream_iterator(default_sentinel_t) : istream_iterator() {} +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY istream_iterator(istream_type& __s) : __in_stream_(_VSTD::addressof(__s)) { if (!(*__in_stream_ >> __value_)) @@ -67,6 +72,12 @@ public: bool operator==(const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __x, const istream_iterator<_Up, _CharU, _TraitsU, _DistanceU>& __y); + +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istream_iterator& __i, default_sentinel_t) { + return __i.__in_stream_ == nullptr; + } +#endif // _LIBCPP_STD_VER > 17 }; template <class _Tp, class _CharT, class _Traits, class _Distance> @@ -78,6 +89,7 @@ operator==(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, return __x.__in_stream_ == __y.__in_stream_; } +#if _LIBCPP_STD_VER <= 17 template <class _Tp, class _CharT, class _Traits, class _Distance> inline _LIBCPP_INLINE_VISIBILITY bool @@ -86,6 +98,7 @@ operator!=(const istream_iterator<_Tp, _CharT, _Traits, _Distance>& __x, { return !(__x == __y); } +#endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/istreambuf_iterator.h b/libcxx/include/__iterator/istreambuf_iterator.h index 0c7676f16908..bc53a6a1c80e 100644 --- a/libcxx/include/__iterator/istreambuf_iterator.h +++ b/libcxx/include/__iterator/istreambuf_iterator.h @@ -11,12 +11,13 @@ #define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H #include <__config> +#include <__iterator/default_sentinel.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <iosfwd> // for forward declaration of basic_streambuf #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -49,7 +50,8 @@ private: { char_type __keep_; streambuf_type* __sbuf_; - _LIBCPP_INLINE_VISIBILITY __proxy(char_type __c, streambuf_type* __s) + _LIBCPP_INLINE_VISIBILITY + explicit __proxy(char_type __c, streambuf_type* __s) : __keep_(__c), __sbuf_(__s) {} friend class istreambuf_iterator; public: @@ -65,6 +67,10 @@ private: } public: _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR istreambuf_iterator() _NOEXCEPT : __sbuf_(nullptr) {} +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY constexpr istreambuf_iterator(default_sentinel_t) noexcept + : istreambuf_iterator() {} +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(istream_type& __s) _NOEXCEPT : __sbuf_(__s.rdbuf()) {} _LIBCPP_INLINE_VISIBILITY istreambuf_iterator(streambuf_type* __s) _NOEXCEPT @@ -86,6 +92,12 @@ public: _LIBCPP_INLINE_VISIBILITY bool equal(const istreambuf_iterator& __b) const {return __test_for_eof() == __b.__test_for_eof();} + +#if _LIBCPP_STD_VER > 17 + friend _LIBCPP_HIDE_FROM_ABI bool operator==(const istreambuf_iterator& __i, default_sentinel_t) { + return __i.__test_for_eof(); + } +#endif // _LIBCPP_STD_VER > 17 }; template <class _CharT, class _Traits> @@ -94,11 +106,13 @@ bool operator==(const istreambuf_iterator<_CharT,_Traits>& __a, const istreambuf_iterator<_CharT,_Traits>& __b) {return __a.equal(__b);} +#if _LIBCPP_STD_VER <= 17 template <class _CharT, class _Traits> inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const istreambuf_iterator<_CharT,_Traits>& __a, const istreambuf_iterator<_CharT,_Traits>& __b) {return !__a.equal(__b);} +#endif // _LIBCPP_STD_VER <= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h index dfcf8e6c8308..d8240ab9c2f1 100644 --- a/libcxx/include/__iterator/iter_move.h +++ b/libcxx/include/__iterator/iter_move.h @@ -10,20 +10,20 @@ #ifndef _LIBCPP___ITERATOR_ITER_MOVE_H #define _LIBCPP___ITERATOR_ITER_MOVE_H +#include <__concepts/class_or_enum.h> #include <__config> #include <__iterator/iterator_traits.h> #include <__utility/forward.h> -#include <concepts> // __class_or_enum +#include <__utility/move.h> #include <type_traits> -#include <utility> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [iterator.cust.move] @@ -36,44 +36,50 @@ template <class _Tp> concept __unqualified_iter_move = __class_or_enum<remove_cvref_t<_Tp>> && requires (_Tp&& __t) { - iter_move(_VSTD::forward<_Tp>(__t)); + iter_move(std::forward<_Tp>(__t)); }; -// [iterator.cust.move]/1 -// The name ranges::iter_move denotes a customization point object. -// The expression ranges::iter_move(E) for a subexpression E is -// expression-equivalent to: +template<class _Tp> +concept __move_deref = + !__unqualified_iter_move<_Tp> && + requires (_Tp&& __t) { + *__t; + requires is_lvalue_reference_v<decltype(*__t)>; + }; + +template<class _Tp> +concept __just_deref = + !__unqualified_iter_move<_Tp> && + !__move_deref<_Tp> && + requires (_Tp&& __t) { + *__t; + requires (!is_lvalue_reference_v<decltype(*__t)>); + }; + +// [iterator.cust.move] + struct __fn { - // [iterator.cust.move]/1.1 - // iter_move(E), if E has class or enumeration type and iter_move(E) is a - // well-formed expression when treated as an unevaluated operand, [...] template<class _Ip> - requires __class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip> + requires __unqualified_iter_move<_Ip> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(iter_move(_VSTD::forward<_Ip>(__i)))) + noexcept(noexcept(iter_move(std::forward<_Ip>(__i)))) { - return iter_move(_VSTD::forward<_Ip>(__i)); + return iter_move(std::forward<_Ip>(__i)); } - // [iterator.cust.move]/1.2 - // Otherwise, if the expression *E is well-formed: - // 1.2.1 if *E is an lvalue, std::move(*E); - // 1.2.2 otherwise, *E. template<class _Ip> - requires (!(__class_or_enum<remove_cvref_t<_Ip>> && __unqualified_iter_move<_Ip>)) && - requires(_Ip&& __i) { *_VSTD::forward<_Ip>(__i); } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const - noexcept(noexcept(*_VSTD::forward<_Ip>(__i))) - { - if constexpr (is_lvalue_reference_v<decltype(*_VSTD::forward<_Ip>(__i))>) { - return _VSTD::move(*_VSTD::forward<_Ip>(__i)); - } else { - return *_VSTD::forward<_Ip>(__i); - } - } + requires __move_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(std::move(*std::forward<_Ip>(__i)))) + -> decltype( std::move(*std::forward<_Ip>(__i))) + { return std::move(*std::forward<_Ip>(__i)); } - // [iterator.cust.move]/1.3 - // Otherwise, ranges::iter_move(E) is ill-formed. + template<class _Ip> + requires __just_deref<_Ip> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const + noexcept(noexcept(*std::forward<_Ip>(__i))) + -> decltype( *std::forward<_Ip>(__i)) + { return *std::forward<_Ip>(__i); } }; } // namespace __iter_move @@ -83,10 +89,10 @@ inline namespace __cpo { } // namespace ranges template<__dereferenceable _Tp> - requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; } + requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __can_reference; } using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>())); -#endif // !_LIBCPP_HAS_NO_CONCEPTS +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iter_swap.h b/libcxx/include/__iterator/iter_swap.h index 0179546667b7..9e06464c3690 100644 --- a/libcxx/include/__iterator/iter_swap.h +++ b/libcxx/include/__iterator/iter_swap.h @@ -14,19 +14,18 @@ #include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> #include <__iterator/readable_traits.h> -#include <__ranges/access.h> #include <__utility/forward.h> #include <__utility/move.h> #include <concepts> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [iter.cust.swap] @@ -100,7 +99,7 @@ concept indirectly_swappable = ranges::iter_swap(__i2, __i1); }; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iterator.h b/libcxx/include/__iterator/iterator.h index be298ee5228e..b417eeab79bf 100644 --- a/libcxx/include/__iterator/iterator.h +++ b/libcxx/include/__iterator/iterator.h @@ -14,7 +14,7 @@ #include <cstddef> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h index f2dbb7c700ec..c3a5b7e0dd22 100644 --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -17,31 +17,31 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 template <class _Tp> using __with_reference = _Tp&; template <class _Tp> -concept __referenceable = requires { +concept __can_reference = requires { typename __with_reference<_Tp>; }; template <class _Tp> concept __dereferenceable = requires(_Tp& __t) { - { *__t } -> __referenceable; // not required to be equality-preserving + { *__t } -> __can_reference; // not required to be equality-preserving }; // [iterator.traits] template<__dereferenceable _Tp> using iter_reference_t = decltype(*declval<_Tp&>()); -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 template <class _Iter> struct _LIBCPP_TEMPLATE_VIS iterator_traits; @@ -105,15 +105,14 @@ template <class _Tp> struct __has_iterator_typedefs { private: - struct __two {char __lx; char __lxx;}; - template <class _Up> static __two __test(...); - template <class _Up> static char __test(typename __void_t<typename _Up::iterator_category>::type* = 0, - typename __void_t<typename _Up::difference_type>::type* = 0, - typename __void_t<typename _Up::value_type>::type* = 0, - typename __void_t<typename _Up::reference>::type* = 0, - typename __void_t<typename _Up::pointer>::type* = 0); + template <class _Up> static false_type __test(...); + template <class _Up> static true_type __test(typename __void_t<typename _Up::iterator_category>::type* = 0, + typename __void_t<typename _Up::difference_type>::type* = 0, + typename __void_t<typename _Up::value_type>::type* = 0, + typename __void_t<typename _Up::reference>::type* = 0, + typename __void_t<typename _Up::pointer>::type* = 0); public: - static const bool value = sizeof(__test<_Tp>(0,0,0,0,0)) == 1; + static const bool value = decltype(__test<_Tp>(0,0,0,0,0))::value; }; @@ -121,35 +120,34 @@ template <class _Tp> struct __has_iterator_category { private: - struct __two {char __lx; char __lxx;}; - template <class _Up> static __two __test(...); - template <class _Up> static char __test(typename _Up::iterator_category* = nullptr); + template <class _Up> static false_type __test(...); + template <class _Up> static true_type __test(typename _Up::iterator_category* = nullptr); public: - static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; template <class _Tp> struct __has_iterator_concept { private: - struct __two {char __lx; char __lxx;}; - template <class _Up> static __two __test(...); - template <class _Up> static char __test(typename _Up::iterator_concept* = nullptr); + template <class _Up> static false_type __test(...); + template <class _Up> static true_type __test(typename _Up::iterator_concept* = nullptr); public: - static const bool value = sizeof(__test<_Tp>(nullptr)) == 1; + static const bool value = decltype(__test<_Tp>(nullptr))::value; }; -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 -// The `cpp17-*-iterator` exposition-only concepts are easily confused with the Cpp17*Iterator tables, -// so they've been banished to a namespace that makes it obvious they have a niche use-case. +// The `cpp17-*-iterator` exposition-only concepts have very similar names to the `Cpp17*Iterator` named requirements +// from `[iterator.cpp17]`. To avoid confusion between the two, the exposition-only concepts have been banished to +// a "detail" namespace indicating they have a niche use-case. namespace __iterator_traits_detail { template<class _Ip> concept __cpp17_iterator = requires(_Ip __i) { - { *__i } -> __referenceable; + { *__i } -> __can_reference; { ++__i } -> same_as<_Ip&>; - { *__i++ } -> __referenceable; + { *__i++ } -> __can_reference; } && copyable<_Ip>; @@ -198,7 +196,7 @@ concept __cpp17_random_access_iterator = { __i + __n } -> same_as<_Ip>; { __n + __i } -> same_as<_Ip>; { __i - __n } -> same_as<_Ip>; - { __i - __i } -> same_as<decltype(__n)>; + { __i - __i } -> same_as<decltype(__n)>; // NOLINT(misc-redundant-expression) ; This is llvm.org/PR54114 { __i[__n] } -> convertible_to<iter_reference_t<_Ip>>; }; } // namespace __iterator_traits_detail @@ -362,7 +360,7 @@ struct iterator_traits : __iterator_traits<_Ip> { using __primary_template = iterator_traits; }; -#else // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#else // _LIBCPP_STD_VER > 17 template <class _Iter, bool> struct __iterator_traits {}; @@ -399,10 +397,10 @@ struct _LIBCPP_TEMPLATE_VIS iterator_traits using __primary_template = iterator_traits; }; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 template<class _Tp> -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 requires is_object_v<_Tp> #endif struct _LIBCPP_TEMPLATE_VIS iterator_traits<_Tp*> @@ -468,27 +466,28 @@ template <class _Up> struct __is_cpp17_contiguous_iterator<_Up*> : true_type {}; +template <class _Iter> +class __wrap_iter; + template <class _Tp> struct __is_exactly_cpp17_input_iterator : public integral_constant<bool, __has_iterator_category_convertible_to<_Tp, input_iterator_tag>::value && !__has_iterator_category_convertible_to<_Tp, forward_iterator_tag>::value> {}; -#if _LIBCPP_STD_VER >= 17 template<class _InputIterator> using __iter_value_type = typename iterator_traits<_InputIterator>::value_type; template<class _InputIterator> -using __iter_key_type = remove_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>; +using __iter_key_type = typename remove_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type; template<class _InputIterator> using __iter_mapped_type = typename iterator_traits<_InputIterator>::value_type::second_type; template<class _InputIterator> using __iter_to_alloc_type = pair< - add_const_t<typename iterator_traits<_InputIterator>::value_type::first_type>, + typename add_const<typename iterator_traits<_InputIterator>::value_type::first_type>::type, typename iterator_traits<_InputIterator>::value_type::second_type>; -#endif // _LIBCPP_STD_VER >= 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/mergeable.h b/libcxx/include/__iterator/mergeable.h new file mode 100644 index 000000000000..b9f2d081dc7e --- /dev/null +++ b/libcxx/include/__iterator/mergeable.h @@ -0,0 +1,41 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_MERGEABLE_H +#define _LIBCPP___ITERATOR_MERGEABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <class _Input1, class _Input2, class _Output, + class _Comp = ranges::less, class _Proj1 = identity, class _Proj2 = identity> +concept mergeable = + input_iterator<_Input1> && + input_iterator<_Input2> && + weakly_incrementable<_Output> && + indirectly_copyable<_Input1, _Output> && + indirectly_copyable<_Input2, _Output> && + indirect_strict_weak_order<_Comp, projected<_Input1, _Proj1>, projected<_Input2, _Proj2>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MERGEABLE_H diff --git a/libcxx/include/__iterator/move_iterator.h b/libcxx/include/__iterator/move_iterator.h index 29bac864c275..6be9f216dbb4 100644 --- a/libcxx/include/__iterator/move_iterator.h +++ b/libcxx/include/__iterator/move_iterator.h @@ -10,51 +10,131 @@ #ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H #define _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#include <__compare/compare_three_way_result.h> +#include <__compare/three_way_comparable.h> +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__concepts/same_as.h> #include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> +#include <__iterator/move_sentinel.h> +#include <__iterator/readable_traits.h> #include <__utility/move.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD +#if _LIBCPP_STD_VER > 17 +template<class _Iter, class = void> +struct __move_iter_category_base {}; + +template<class _Iter> + requires requires { typename iterator_traits<_Iter>::iterator_category; } +struct __move_iter_category_base<_Iter> { + using iterator_category = _If< + derived_from<typename iterator_traits<_Iter>::iterator_category, random_access_iterator_tag>, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category + >; +}; + +template<class _Iter, class _Sent> +concept __move_iter_comparable = requires { + { declval<const _Iter&>() == declval<_Sent>() } -> convertible_to<bool>; +}; +#endif // _LIBCPP_STD_VER > 17 + template <class _Iter> class _LIBCPP_TEMPLATE_VIS move_iterator +#if _LIBCPP_STD_VER > 17 + : public __move_iter_category_base<_Iter> +#endif { public: #if _LIBCPP_STD_VER > 17 - typedef input_iterator_tag iterator_concept; -#endif - + using iterator_type = _Iter; + using iterator_concept = input_iterator_tag; + // iterator_category is inherited and not always present + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using pointer = _Iter; + using reference = iter_rvalue_reference_t<_Iter>; +#else typedef _Iter iterator_type; typedef _If< __is_cpp17_random_access_iterator<_Iter>::value, random_access_iterator_tag, typename iterator_traits<_Iter>::iterator_category - > iterator_category; + > iterator_category; typedef typename iterator_traits<iterator_type>::value_type value_type; typedef typename iterator_traits<iterator_type>::difference_type difference_type; typedef iterator_type pointer; -#ifndef _LIBCPP_CXX03_LANG typedef typename iterator_traits<iterator_type>::reference __reference; typedef typename conditional< is_reference<__reference>::value, typename remove_reference<__reference>::type&&, __reference >::type reference; -#else - typedef typename iterator_traits<iterator_type>::reference reference; -#endif +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator() : __current_() {} + explicit move_iterator(_Iter __i) : __current_(std::move(__i)) {} + + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + move_iterator& operator++() { ++__current_; return *this; } + + _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 + pointer operator->() const { return __current_; } + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator() requires is_constructible_v<_Iter> : __current_() {} + + template <class _Up> + requires (!_IsSame<_Up, _Iter>::value) && convertible_to<const _Up&, _Iter> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator(const move_iterator<_Up>& __u) : __current_(__u.base()) {} + + template <class _Up> + requires (!_IsSame<_Up, _Iter>::value) && + convertible_to<const _Up&, _Iter> && + assignable_from<_Iter&, const _Up&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_iterator& operator=(const move_iterator<_Up>& __u) { + __current_ = __u.base(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr const _Iter& base() const & noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Iter base() && { return std::move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator*() const { return ranges::iter_move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr + reference operator[](difference_type __n) const { return ranges::iter_move(__current_ + __n); } + + _LIBCPP_HIDE_FROM_ABI constexpr + auto operator++(int) + requires forward_iterator<_Iter> + { + move_iterator __tmp(*this); ++__current_; return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr + void operator++(int) { ++__current_; } +#else _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {} + move_iterator() : __current_() {} template <class _Up, class = __enable_if_t< !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value @@ -79,14 +159,12 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator*() const { return static_cast<reference>(*__current_); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const { return __current_; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 - move_iterator& operator++() { ++__current_; return *this; } - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator operator++(int) { move_iterator __tmp(*this); ++__current_; return __tmp; } +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator--() { --__current_; return *this; } _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -100,7 +178,48 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator& operator-=(difference_type __n) { __current_ -= __n; return *this; } +#if _LIBCPP_STD_VER > 17 + template<sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + bool operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y) + requires __move_iter_comparable<_Iter, _Sent> + { + return __x.base() == __y.base(); + } + + template<sized_sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y) + { + return __x.base() - __y.base(); + } + + template<sized_sentinel_for<_Iter> _Sent> + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_difference_t<_Iter> operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y) + { + return __x.base() - __y.base(); + } + + friend _LIBCPP_HIDE_FROM_ABI constexpr + iter_rvalue_reference_t<_Iter> iter_move(const move_iterator& __i) + noexcept(noexcept(ranges::iter_move(__i.__current_))) + { + return ranges::iter_move(__i.__current_); + } + + template<indirectly_swappable<_Iter> _It2> + friend _LIBCPP_HIDE_FROM_ABI constexpr + void iter_swap(const move_iterator& __x, const move_iterator<_It2>& __y) + noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } +#endif // _LIBCPP_STD_VER > 17 + private: + template<class _It2> friend class move_iterator; + _Iter __current_; }; @@ -111,12 +230,14 @@ bool operator==(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _ return __x.base() == __y.base(); } +#if _LIBCPP_STD_VER <= 17 template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() != __y.base(); } +#endif // _LIBCPP_STD_VER <= 17 template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -146,6 +267,16 @@ bool operator>=(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& _ return __x.base() >= __y.base(); } +#if _LIBCPP_STD_VER > 17 +template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> +inline _LIBCPP_HIDE_FROM_ABI constexpr +auto operator<=>(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) + -> compare_three_way_result_t<_Iter1, _Iter2> +{ + return __x.base() <=> __y.base(); +} +#endif // _LIBCPP_STD_VER > 17 + #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -162,8 +293,17 @@ operator-(const move_iterator<_Iter1>& __x, const move_iterator<_Iter2>& __y) { return __x.base() - __y.base(); } -#endif +#endif // !_LIBCPP_CXX03_LANG +#if _LIBCPP_STD_VER > 17 +template <class _Iter> +inline _LIBCPP_HIDE_FROM_ABI constexpr +move_iterator<_Iter> operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x) + requires requires { { __x.base() + __n } -> same_as<_Iter>; } +{ + return __x + __n; +} +#else template <class _Iter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> @@ -171,13 +311,14 @@ operator+(typename move_iterator<_Iter>::difference_type __n, const move_iterato { return move_iterator<_Iter>(__x.base() + __n); } +#endif // _LIBCPP_STD_VER > 17 template <class _Iter> inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14 move_iterator<_Iter> make_move_iterator(_Iter __i) { - return move_iterator<_Iter>(_VSTD::move(__i)); + return move_iterator<_Iter>(std::move(__i)); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/move_sentinel.h b/libcxx/include/__iterator/move_sentinel.h new file mode 100644 index 000000000000..5adf877b3490 --- /dev/null +++ b/libcxx/include/__iterator/move_sentinel.h @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_MOVE_SENTINEL_H +#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H + +#include <__concepts/assignable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/semiregular.h> +#include <__config> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <semiregular _Sent> +class _LIBCPP_TEMPLATE_VIS move_sentinel +{ +public: + _LIBCPP_HIDE_FROM_ABI + move_sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr + explicit move_sentinel(_Sent __s) : __last_(std::move(__s)) {} + + template <class _S2> + requires convertible_to<const _S2&, _Sent> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel(const move_sentinel<_S2>& __s) : __last_(__s.base()) {} + + template <class _S2> + requires assignable_from<_Sent&, const _S2&> + _LIBCPP_HIDE_FROM_ABI constexpr + move_sentinel& operator=(const move_sentinel<_S2>& __s) + { __last_ = __s.base(); return *this; } + + constexpr _Sent base() const { return __last_; } + +private: + _Sent __last_ = _Sent(); +}; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H diff --git a/libcxx/include/__iterator/next.h b/libcxx/include/__iterator/next.h index 8683e2210e95..5363d6d58ecf 100644 --- a/libcxx/include/__iterator/next.h +++ b/libcxx/include/__iterator/next.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ITERATOR_NEXT_H #define _LIBCPP___ITERATOR_NEXT_H +#include <__assert> #include <__config> -#include <__debug> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -19,7 +19,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -35,7 +35,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 return __x; } -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) // [range.iter.op.next] @@ -58,16 +58,14 @@ struct __fn { } template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, _Sp __bound) const { - ranges::advance(__x, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, _Sp __bound_sentinel) const { + ranges::advance(__x, __bound_sentinel); return __x; } template <input_or_output_iterator _Ip, sentinel_for<_Ip> _Sp> - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound) const { - ranges::advance(__x, __n, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Sp __bound_sentinel) const { + ranges::advance(__x, __n, __bound_sentinel); return __x; } }; @@ -79,7 +77,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/ostream_iterator.h b/libcxx/include/__iterator/ostream_iterator.h index 20a36742ccab..76ae4614939f 100644 --- a/libcxx/include/__iterator/ostream_iterator.h +++ b/libcxx/include/__iterator/ostream_iterator.h @@ -14,10 +14,11 @@ #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> #include <__memory/addressof.h> +#include <cstddef> #include <iosfwd> // for forward declarations of char_traits and basic_ostream #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/ostreambuf_iterator.h b/libcxx/include/__iterator/ostreambuf_iterator.h index 3272f6c99d74..6da7598ed272 100644 --- a/libcxx/include/__iterator/ostreambuf_iterator.h +++ b/libcxx/include/__iterator/ostreambuf_iterator.h @@ -13,10 +13,11 @@ #include <__config> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> +#include <cstddef> #include <iosfwd> // for forward declaration of basic_streambuf #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/__iterator/permutable.h b/libcxx/include/__iterator/permutable.h new file mode 100644 index 000000000000..28d193eaae2c --- /dev/null +++ b/libcxx/include/__iterator/permutable.h @@ -0,0 +1,35 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_PERMUTABLE_H +#define _LIBCPP___ITERATOR_PERMUTABLE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <class _Iterator> +concept permutable = + forward_iterator<_Iterator> && + indirectly_movable_storable<_Iterator, _Iterator> && + indirectly_swappable<_Iterator, _Iterator>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PERMUTABLE_H diff --git a/libcxx/include/__iterator/prev.h b/libcxx/include/__iterator/prev.h index 5a58dc0e4b43..eb997b91ba20 100644 --- a/libcxx/include/__iterator/prev.h +++ b/libcxx/include/__iterator/prev.h @@ -10,8 +10,8 @@ #ifndef _LIBCPP___ITERATOR_PREV_H #define _LIBCPP___ITERATOR_PREV_H +#include <__assert> #include <__config> -#include <__debug> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/incrementable_traits.h> @@ -19,7 +19,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -34,7 +34,7 @@ inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 return __x; } -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) // [range.iter.op.prev] @@ -57,9 +57,8 @@ struct __fn { } template <bidirectional_iterator _Ip> - _LIBCPP_HIDE_FROM_ABI - constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound) const { - ranges::advance(__x, -__n, __bound); + _LIBCPP_HIDE_FROM_ABI constexpr _Ip operator()(_Ip __x, iter_difference_t<_Ip> __n, _Ip __bound_iter) const { + ranges::advance(__x, -__n, __bound_iter); return __x; } }; @@ -71,7 +70,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/projected.h b/libcxx/include/__iterator/projected.h index 30ea3a124b2c..53526bd8e712 100644 --- a/libcxx/include/__iterator/projected.h +++ b/libcxx/include/__iterator/projected.h @@ -15,12 +15,12 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 template<indirectly_readable _It, indirectly_regular_unary_invocable<_It> _Proj> struct projected { @@ -33,7 +33,7 @@ struct incrementable_traits<projected<_It, _Proj>> { using difference_type = iter_difference_t<_It>; }; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/readable_traits.h b/libcxx/include/__iterator/readable_traits.h index c0b16bafd784..500b46ac145f 100644 --- a/libcxx/include/__iterator/readable_traits.h +++ b/libcxx/include/__iterator/readable_traits.h @@ -15,12 +15,12 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 // [readable.traits] template<class> struct __cond_value_type {}; @@ -79,7 +79,7 @@ using iter_value_t = typename conditional_t<__is_primary_template<iterator_trait indirectly_readable_traits<remove_cvref_t<_Ip> >, iterator_traits<remove_cvref_t<_Ip> > >::value_type; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/reverse_access.h b/libcxx/include/__iterator/reverse_access.h index 643aede01c72..40c266378d36 100644 --- a/libcxx/include/__iterator/reverse_access.h +++ b/libcxx/include/__iterator/reverse_access.h @@ -16,13 +16,11 @@ #include <initializer_list> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_CXX03_LANG) - #if _LIBCPP_STD_VER > 11 template <class _Tp, size_t _Np> @@ -95,9 +93,7 @@ auto crend(const _Cp& __c) -> decltype(_VSTD::rend(__c)) return _VSTD::rend(__c); } -#endif - -#endif // !defined(_LIBCPP_CXX03_LANG) +#endif // _LIBCPP_STD_VER > 11 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/reverse_iterator.h b/libcxx/include/__iterator/reverse_iterator.h index 449eb529aa98..89bda19effef 100644 --- a/libcxx/include/__iterator/reverse_iterator.h +++ b/libcxx/include/__iterator/reverse_iterator.h @@ -10,16 +10,25 @@ #ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H #define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H +#include <__algorithm/unwrap_iter.h> #include <__compare/compare_three_way_result.h> #include <__compare/three_way_comparable.h> +#include <__concepts/convertible_to.h> #include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> #include <__iterator/iterator.h> #include <__iterator/iterator_traits.h> +#include <__iterator/prev.h> +#include <__iterator/readable_traits.h> #include <__memory/addressof.h> +#include <__utility/move.h> #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,22 +50,31 @@ private: _Iter __t; // no longer used as of LWG #2360, not removed due to ABI break #endif +#if _LIBCPP_STD_VER > 17 + static_assert(__is_cpp17_bidirectional_iterator<_Iter>::value || bidirectional_iterator<_Iter>, + "reverse_iterator<It> requires It to be a bidirectional iterator."); +#endif // _LIBCPP_STD_VER > 17 + protected: _Iter current; public: - typedef _Iter iterator_type; - typedef typename iterator_traits<_Iter>::difference_type difference_type; - typedef typename iterator_traits<_Iter>::reference reference; - typedef typename iterator_traits<_Iter>::pointer pointer; - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - typename iterator_traits<_Iter>::iterator_category> iterator_category; - typedef typename iterator_traits<_Iter>::value_type value_type; + using iterator_type = _Iter; + using iterator_category = _If<__is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + typename iterator_traits<_Iter>::iterator_category>; + using pointer = typename iterator_traits<_Iter>::pointer; #if _LIBCPP_STD_VER > 17 - typedef _If<__is_cpp17_random_access_iterator<_Iter>::value, - random_access_iterator_tag, - bidirectional_iterator_tag> iterator_concept; + using iterator_concept = _If<__is_cpp17_random_access_iterator<_Iter>::value, + random_access_iterator_tag, + bidirectional_iterator_tag>; + using value_type = iter_value_t<_Iter>; + using difference_type = iter_difference_t<_Iter>; + using reference = iter_reference_t<_Iter>; +#else + using value_type = typename iterator_traits<_Iter>::value_type; + using difference_type = typename iterator_traits<_Iter>::difference_type; + using reference = typename iterator_traits<_Iter>::reference; #endif #ifndef _LIBCPP_ABI_NO_ITERATOR_BASES @@ -114,32 +132,75 @@ public: _Iter base() const {return current;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference operator*() const {_Iter __tmp = current; return *--__tmp;} + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY + constexpr pointer operator->() const + requires is_pointer_v<_Iter> || requires(const _Iter i) { i.operator->(); } + { + if constexpr (is_pointer_v<_Iter>) { + return std::prev(current); + } else { + return std::prev(current).operator->(); + } + } +#else _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - pointer operator->() const {return _VSTD::addressof(operator*());} + pointer operator->() const { + return std::addressof(operator*()); + } +#endif // _LIBCPP_STD_VER > 17 + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator++() {--current; return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} + reverse_iterator operator++(int) {reverse_iterator __tmp(*this); --current; return __tmp;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator--() {++current; return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} + reverse_iterator operator--(int) {reverse_iterator __tmp(*this); ++current; return __tmp;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator+ (difference_type __n) const {return reverse_iterator(current - __n);} + reverse_iterator operator+(difference_type __n) const {return reverse_iterator(current - __n);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator+=(difference_type __n) {current -= __n; return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reverse_iterator operator- (difference_type __n) const {return reverse_iterator(current + __n);} + reverse_iterator operator-(difference_type __n) const {return reverse_iterator(current + __n);} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reverse_iterator& operator-=(difference_type __n) {current += __n; return *this;} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 - reference operator[](difference_type __n) const {return *(*this + __n);} + reference operator[](difference_type __n) const {return *(*this + __n);} + +#if _LIBCPP_STD_VER > 17 + _LIBCPP_HIDE_FROM_ABI friend constexpr + iter_rvalue_reference_t<_Iter> iter_move(const reverse_iterator& __i) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + noexcept(ranges::iter_move(--declval<_Iter&>()))) { + auto __tmp = __i.base(); + return ranges::iter_move(--__tmp); + } + + template <indirectly_swappable<_Iter> _Iter2> + _LIBCPP_HIDE_FROM_ABI friend constexpr + void iter_swap(const reverse_iterator& __x, const reverse_iterator<_Iter2>& __y) + noexcept(is_nothrow_copy_constructible_v<_Iter> && + is_nothrow_copy_constructible_v<_Iter2> && + noexcept(ranges::iter_swap(--declval<_Iter&>(), --declval<_Iter2&>()))) { + auto __xtmp = __x.base(); + auto __ytmp = __y.base(); + ranges::iter_swap(--__xtmp, --__ytmp); + } +#endif // _LIBCPP_STD_VER > 17 }; template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator==(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() == __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() == __y.base(); } @@ -148,6 +209,11 @@ template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() > __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() > __y.base(); } @@ -156,6 +222,11 @@ template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator!=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() != __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() != __y.base(); } @@ -164,6 +235,11 @@ template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() < __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() < __y.base(); } @@ -172,6 +248,11 @@ template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator>=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() <= __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() <= __y.base(); } @@ -180,11 +261,16 @@ template <class _Iter1, class _Iter2> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 bool operator<=(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& __y) +#if _LIBCPP_STD_VER > 17 + requires requires { + { __x.base() >= __y.base() } -> convertible_to<bool>; + } +#endif // _LIBCPP_STD_VER > 17 { return __x.base() >= __y.base(); } -#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 template <class _Iter1, three_way_comparable_with<_Iter1> _Iter2> _LIBCPP_HIDE_FROM_ABI constexpr compare_three_way_result_t<_Iter1, _Iter2> @@ -192,7 +278,7 @@ operator<=>(const reverse_iterator<_Iter1>& __x, const reverse_iterator<_Iter2>& { return __y.base() <=> __x.base(); } -#endif +#endif // _LIBCPP_STD_VER > 17 #ifndef _LIBCPP_CXX03_LANG template <class _Iter1, class _Iter2> @@ -221,6 +307,12 @@ operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_i return reverse_iterator<_Iter>(__x.base() - __n); } +#if _LIBCPP_STD_VER > 17 +template <class _Iter1, class _Iter2> + requires (!sized_sentinel_for<_Iter1, _Iter2>) +inline constexpr bool disable_sized_sentinel_for<reverse_iterator<_Iter1>, reverse_iterator<_Iter2>> = true; +#endif // _LIBCPP_STD_VER > 17 + #if _LIBCPP_STD_VER > 11 template <class _Iter> inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 @@ -230,6 +322,49 @@ reverse_iterator<_Iter> make_reverse_iterator(_Iter __i) } #endif +template <class _Iter> +using _ReverseWrapper = reverse_iterator<reverse_iterator<_Iter> >; + +template <class _Iter, bool __b> +struct __unwrap_iter_impl<_ReverseWrapper<_Iter>, __b> { + static _LIBCPP_CONSTEXPR decltype(std::__unwrap_iter(std::declval<_Iter>())) + __apply(_ReverseWrapper<_Iter> __i) _NOEXCEPT { + return std::__unwrap_iter(__i.base().base()); + } +}; + +template <class _OrigIter, class _UnwrappedIter> +struct __rewrap_iter_impl<_ReverseWrapper<_OrigIter>, _UnwrappedIter> { + template <class _Iter> + struct _ReverseWrapperCount { + static _LIBCPP_CONSTEXPR const size_t value = 1; + }; + + template <class _Iter> + struct _ReverseWrapperCount<_ReverseWrapper<_Iter> > { + static _LIBCPP_CONSTEXPR const size_t value = 1 + _ReverseWrapperCount<_Iter>::value; + }; + + template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount != 0, int> = 0> + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OIter> __rewrap(_ReverseWrapper<_OIter> __iter1, + _UIter __iter2) { + return _ReverseWrapper<_OIter>( + reverse_iterator<_OIter>(__rewrap<_RewrapCount - 1>(__iter1.base().base(), __iter2))); + } + + template <size_t _RewrapCount, class _OIter, class _UIter, __enable_if_t<_RewrapCount == 0, int> = 0> + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR decltype(std::__rewrap_iter(std::declval<_OIter>(), + std::declval<_UIter>())) + __rewrap(_OIter __iter1, _UIter __iter2) { + return std::__rewrap_iter(__iter1, __iter2); + } + + _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR _ReverseWrapper<_OrigIter> __apply(_ReverseWrapper<_OrigIter> __iter1, + _UnwrappedIter __iter2) { + return __rewrap<_ReverseWrapperCount<_OrigIter>::value>(__iter1, __iter2); + } +}; + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H diff --git a/libcxx/include/__iterator/size.h b/libcxx/include/__iterator/size.h index 2e6a7d386cb1..e06013496668 100644 --- a/libcxx/include/__iterator/size.h +++ b/libcxx/include/__iterator/size.h @@ -15,7 +15,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -41,9 +41,14 @@ _NOEXCEPT_(noexcept(static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype( -> common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>> { return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(__c.size())>>>(__c.size()); } +// GCC complains about the implicit conversion from ptrdiff_t to size_t in +// the array bound. +_LIBCPP_DIAGNOSTIC_PUSH +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wsign-conversion") template <class _Tp, ptrdiff_t _Sz> _LIBCPP_INLINE_VISIBILITY constexpr ptrdiff_t ssize(const _Tp (&)[_Sz]) noexcept { return _Sz; } +_LIBCPP_DIAGNOSTIC_POP #endif #endif // _LIBCPP_STD_VER > 14 diff --git a/libcxx/include/__iterator/sortable.h b/libcxx/include/__iterator/sortable.h new file mode 100644 index 000000000000..bcf934f87be0 --- /dev/null +++ b/libcxx/include/__iterator/sortable.h @@ -0,0 +1,37 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_SORTABLE_H +#define _LIBCPP___ITERATOR_SORTABLE_H + +#include <__config> +#include <__functional/identity.h> +#include <__functional/ranges_operations.h> +#include <__iterator/concepts.h> +#include <__iterator/permutable.h> +#include <__iterator/projected.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 + +template <class _Iter, class _Comp = ranges::less, class _Proj = identity> +concept sortable = + permutable<_Iter> && + indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>; + +#endif // _LIBCPP_STD_VER > 17 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_SORTABLE_H diff --git a/libcxx/include/__iterator/unreachable_sentinel.h b/libcxx/include/__iterator/unreachable_sentinel.h index b200236d8b9d..d77cc99f02f7 100644 --- a/libcxx/include/__iterator/unreachable_sentinel.h +++ b/libcxx/include/__iterator/unreachable_sentinel.h @@ -14,12 +14,12 @@ #include <__iterator/concepts.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) +#if _LIBCPP_STD_VER > 17 struct unreachable_sentinel_t { template<weakly_incrementable _Iter> @@ -31,7 +31,7 @@ struct unreachable_sentinel_t { inline constexpr unreachable_sentinel_t unreachable_sentinel{}; -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) +#endif // _LIBCPP_STD_VER > 17 _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h index d9dbee588896..f780048754c9 100644 --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -18,7 +18,7 @@ #include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD @@ -50,12 +50,12 @@ public: typename enable_if<is_convertible<_Up, iterator_type>::value>::type* = nullptr) _NOEXCEPT : __i(__u.base()) { -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE if (!__libcpp_is_constant_evaluated()) __get_db()->__iterator_copy(this, _VSTD::addressof(__u)); #endif } -#if _LIBCPP_DEBUG_LEVEL == 2 +#ifdef _LIBCPP_ENABLE_DEBUG_MODE _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const __wrap_iter& __x) : __i(__x.base()) @@ -135,15 +135,15 @@ public: _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 iterator_type base() const _NOEXCEPT {return __i;} private: -#if _LIBCPP_DEBUG_LEVEL == 2 - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit __wrap_iter(const void* __p, iterator_type __x) _NOEXCEPT : __i(__x) { + (void)__p; +#ifdef _LIBCPP_ENABLE_DEBUG_MODE if (!__libcpp_is_constant_evaluated()) __get_db()->__insert_ic(this, __p); - } -#else - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} #endif + } template <class _Up> friend class __wrap_iter; template <class _CharT, class _Traits, class _Alloc> friend class basic_string; |
