File indexing completed on 2026-05-03 08:13:53
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
0010 #define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H
0011
0012 #include <__concepts/boolean_testable.h>
0013 #include <__concepts/convertible_to.h>
0014 #include <__concepts/same_as.h>
0015 #include <__config>
0016 #include <__iterator/iterator_traits.h>
0017 #include <__type_traits/is_constructible.h>
0018 #include <__type_traits/is_convertible.h>
0019 #include <__type_traits/is_signed.h>
0020 #include <__type_traits/is_void.h>
0021 #include <__utility/as_const.h>
0022 #include <__utility/forward.h>
0023 #include <__utility/move.h>
0024 #include <__utility/swap.h>
0025
0026 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0027 # pragma GCC system_header
0028 #endif
0029
0030 _LIBCPP_PUSH_MACROS
0031 #include <__undef_macros>
0032
0033 #if _LIBCPP_STD_VER >= 20
0034
0035 _LIBCPP_BEGIN_NAMESPACE_STD
0036
0037 template <class _Tp>
0038 concept __cpp17_move_constructible = is_move_constructible_v<_Tp>;
0039
0040 template <class _Tp>
0041 concept __cpp17_copy_constructible = __cpp17_move_constructible<_Tp> && is_copy_constructible_v<_Tp>;
0042
0043 template <class _Tp>
0044 concept __cpp17_move_assignable = requires(_Tp __lhs, _Tp __rhs) {
0045 { __lhs = std::move(__rhs) } -> same_as<_Tp&>;
0046 };
0047
0048 template <class _Tp>
0049 concept __cpp17_copy_assignable = __cpp17_move_assignable<_Tp> && requires(_Tp __lhs, _Tp __rhs) {
0050 { __lhs = __rhs } -> same_as<_Tp&>;
0051 { __lhs = std::as_const(__rhs) } -> same_as<_Tp&>;
0052 };
0053
0054 template <class _Tp>
0055 concept __cpp17_destructible = requires(_Tp __v) { __v.~_Tp(); };
0056
0057 template <class _Tp>
0058 concept __cpp17_equality_comparable = requires(_Tp __lhs, _Tp __rhs) {
0059 { __lhs == __rhs } -> __boolean_testable;
0060 { std::as_const(__lhs) == __rhs } -> __boolean_testable;
0061 { __lhs == std::as_const(__rhs) } -> __boolean_testable;
0062 { std::as_const(__lhs) == std::as_const(__rhs) } -> __boolean_testable;
0063 };
0064
0065 template <class _Tp>
0066 concept __cpp17_default_constructible = is_default_constructible_v<_Tp>;
0067
0068 template <class _Iter>
0069 concept __cpp17_iterator =
0070 __cpp17_copy_constructible<_Iter> && __cpp17_copy_assignable<_Iter> && __cpp17_destructible<_Iter> &&
0071 (is_signed_v<__iter_diff_t<_Iter>> || is_void_v<__iter_diff_t<_Iter>>) && requires(_Iter __iter) {
0072 { *__iter };
0073 { ++__iter } -> same_as<_Iter&>;
0074 };
0075
0076 template <class _Iter>
0077 concept __cpp17_input_iterator =
0078 __cpp17_iterator<_Iter> && __cpp17_equality_comparable<_Iter> && requires(_Iter __lhs, _Iter __rhs) {
0079 { __lhs != __rhs } -> __boolean_testable;
0080 { std::as_const(__lhs) != __rhs } -> __boolean_testable;
0081 { __lhs != std::as_const(__rhs) } -> __boolean_testable;
0082 { std::as_const(__lhs) != std::as_const(__rhs) } -> __boolean_testable;
0083
0084 { *__lhs } -> same_as<__iter_reference<_Iter>>;
0085 { *std::as_const(__lhs) } -> same_as<__iter_reference<_Iter>>;
0086
0087 { ++__lhs } -> same_as<_Iter&>;
0088 { (void)__lhs++ };
0089 { *__lhs++ };
0090 };
0091
0092 template <class _Iter, class _WriteTo>
0093 concept __cpp17_output_iterator = __cpp17_iterator<_Iter> && requires(_Iter __iter, _WriteTo __write) {
0094 { *__iter = std::forward<_WriteTo>(__write) };
0095 { ++__iter } -> same_as<_Iter&>;
0096 { __iter++ } -> convertible_to<const _Iter&>;
0097 { *__iter++ = std::forward<_WriteTo>(__write) };
0098 };
0099
0100 template <class _Iter>
0101 concept __cpp17_forward_iterator =
0102 __cpp17_input_iterator<_Iter> && __cpp17_default_constructible<_Iter> && requires(_Iter __iter) {
0103 { __iter++ } -> convertible_to<const _Iter&>;
0104 { *__iter++ } -> same_as<__iter_reference<_Iter>>;
0105 };
0106
0107 template <class _Iter>
0108 concept __cpp17_bidirectional_iterator = __cpp17_forward_iterator<_Iter> && requires(_Iter __iter) {
0109 { --__iter } -> same_as<_Iter&>;
0110 { __iter-- } -> convertible_to<const _Iter&>;
0111 { *__iter-- } -> same_as<__iter_reference<_Iter>>;
0112 };
0113
0114 template <class _Iter>
0115 concept __cpp17_random_access_iterator =
0116 __cpp17_bidirectional_iterator<_Iter> && requires(_Iter __iter, __iter_diff_t<_Iter> __n) {
0117 { __iter += __n } -> same_as<_Iter&>;
0118
0119 { __iter + __n } -> same_as<_Iter>;
0120 { __n + __iter } -> same_as<_Iter>;
0121 { std::as_const(__iter) + __n } -> same_as<_Iter>;
0122 { __n + std::as_const(__iter) } -> same_as<_Iter>;
0123
0124 { __iter -= __n } -> same_as<_Iter&>;
0125 { __iter - __n } -> same_as<_Iter>;
0126 { std::as_const(__iter) - __n } -> same_as<_Iter>;
0127
0128 { __iter - __iter } -> same_as<__iter_diff_t<_Iter>>;
0129 { std::as_const(__iter) - __iter } -> same_as<__iter_diff_t<_Iter>>;
0130 { __iter - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
0131 { std::as_const(__iter) - std::as_const(__iter) } -> same_as<__iter_diff_t<_Iter>>;
0132
0133 { __iter[__n] } -> convertible_to<__iter_reference<_Iter>>;
0134 { std::as_const(__iter)[__n] } -> convertible_to<__iter_reference<_Iter>>;
0135
0136 { __iter < __iter } -> __boolean_testable;
0137 { std::as_const(__iter) < __iter } -> __boolean_testable;
0138 { __iter < std::as_const(__iter) } -> __boolean_testable;
0139 { std::as_const(__iter) < std::as_const(__iter) } -> __boolean_testable;
0140
0141 { __iter > __iter } -> __boolean_testable;
0142 { std::as_const(__iter) > __iter } -> __boolean_testable;
0143 { __iter > std::as_const(__iter) } -> __boolean_testable;
0144 { std::as_const(__iter) > std::as_const(__iter) } -> __boolean_testable;
0145
0146 { __iter >= __iter } -> __boolean_testable;
0147 { std::as_const(__iter) >= __iter } -> __boolean_testable;
0148 { __iter >= std::as_const(__iter) } -> __boolean_testable;
0149 { std::as_const(__iter) >= std::as_const(__iter) } -> __boolean_testable;
0150
0151 { __iter <= __iter } -> __boolean_testable;
0152 { std::as_const(__iter) <= __iter } -> __boolean_testable;
0153 { __iter <= std::as_const(__iter) } -> __boolean_testable;
0154 { std::as_const(__iter) <= std::as_const(__iter) } -> __boolean_testable;
0155 };
0156
0157 _LIBCPP_END_NAMESPACE_STD
0158
0159 # ifndef _LIBCPP_DISABLE_ITERATOR_CHECKS
0160 # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) \
0161 static_assert(::std::__cpp17_input_iterator<iter_t>, message)
0162 # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) \
0163 static_assert(::std::__cpp17_output_iterator<iter_t, write_t>, message)
0164 # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) \
0165 static_assert(::std::__cpp17_forward_iterator<iter_t>, message)
0166 # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) \
0167 static_assert(::std::__cpp17_bidirectional_iterator<iter_t>, message)
0168 # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) \
0169 static_assert(::std::__cpp17_random_access_iterator<iter_t>, message)
0170 # else
0171 # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true)
0172 # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true)
0173 # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true)
0174 # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true)
0175 # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true)
0176 # endif
0177
0178 #else
0179
0180 # define _LIBCPP_REQUIRE_CPP17_INPUT_ITERATOR(iter_t, message) static_assert(true)
0181 # define _LIBCPP_REQUIRE_CPP17_OUTPUT_ITERATOR(iter_t, write_t, message) static_assert(true)
0182 # define _LIBCPP_REQUIRE_CPP17_FORWARD_ITERATOR(iter_t, message) static_assert(true)
0183 # define _LIBCPP_REQUIRE_CPP17_BIDIRECTIONAL_ITERATOR(iter_t, message) static_assert(true)
0184 # define _LIBCPP_REQUIRE_CPP17_RANDOM_ACCESS_ITERATOR(iter_t, message) static_assert(true)
0185
0186 #endif
0187
0188 _LIBCPP_POP_MACROS
0189
0190 #endif