aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__iterator
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/__iterator')
-rw-r--r--libcxx/include/__iterator/access.h2
-rw-r--r--libcxx/include/__iterator/advance.h54
-rw-r--r--libcxx/include/__iterator/back_insert_iterator.h4
-rw-r--r--libcxx/include/__iterator/bounded_iter.h229
-rw-r--r--libcxx/include/__iterator/common_iterator.h39
-rw-r--r--libcxx/include/__iterator/concepts.h24
-rw-r--r--libcxx/include/__iterator/counted_iterator.h10
-rw-r--r--libcxx/include/__iterator/data.h2
-rw-r--r--libcxx/include/__iterator/default_sentinel.h6
-rw-r--r--libcxx/include/__iterator/distance.h6
-rw-r--r--libcxx/include/__iterator/empty.h2
-rw-r--r--libcxx/include/__iterator/erase_if_container.h2
-rw-r--r--libcxx/include/__iterator/front_insert_iterator.h2
-rw-r--r--libcxx/include/__iterator/incrementable_traits.h6
-rw-r--r--libcxx/include/__iterator/indirectly_comparable.h8
-rw-r--r--libcxx/include/__iterator/insert_iterator.h4
-rw-r--r--libcxx/include/__iterator/istream_iterator.h15
-rw-r--r--libcxx/include/__iterator/istreambuf_iterator.h18
-rw-r--r--libcxx/include/__iterator/iter_move.h74
-rw-r--r--libcxx/include/__iterator/iter_swap.h7
-rw-r--r--libcxx/include/__iterator/iterator.h2
-rw-r--r--libcxx/include/__iterator/iterator_traits.h67
-rw-r--r--libcxx/include/__iterator/mergeable.h41
-rw-r--r--libcxx/include/__iterator/move_iterator.h175
-rw-r--r--libcxx/include/__iterator/move_sentinel.h57
-rw-r--r--libcxx/include/__iterator/next.h18
-rw-r--r--libcxx/include/__iterator/ostream_iterator.h3
-rw-r--r--libcxx/include/__iterator/ostreambuf_iterator.h3
-rw-r--r--libcxx/include/__iterator/permutable.h35
-rw-r--r--libcxx/include/__iterator/prev.h13
-rw-r--r--libcxx/include/__iterator/projected.h6
-rw-r--r--libcxx/include/__iterator/readable_traits.h6
-rw-r--r--libcxx/include/__iterator/reverse_access.h8
-rw-r--r--libcxx/include/__iterator/reverse_iterator.h175
-rw-r--r--libcxx/include/__iterator/size.h7
-rw-r--r--libcxx/include/__iterator/sortable.h37
-rw-r--r--libcxx/include/__iterator/unreachable_sentinel.h6
-rw-r--r--libcxx/include/__iterator/wrap_iter.h16
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;