1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___ITERATOR_CONCEPTS_H 11 #define _LIBCPP___ITERATOR_CONCEPTS_H 12 13 #include <__config> 14 #include <concepts> 15 #include <__iterator/iter_move.h> 16 #include <__iterator/incrementable_traits.h> 17 #include <__iterator/iterator_traits.h> 18 #include <__iterator/readable_traits.h> 19 20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21 #pragma GCC system_header 22 #endif 23 24 _LIBCPP_PUSH_MACROS 25 #include <__undef_macros> 26 27 _LIBCPP_BEGIN_NAMESPACE_STD 28 29 #if !defined(_LIBCPP_HAS_NO_RANGES) 30 31 // clang-format off 32 33 // [iterator.concept.readable] 34 template<class _In> 35 concept __indirectly_readable_impl = 36 requires(const _In __in) { 37 typename iter_value_t<_In>; 38 typename iter_reference_t<_In>; 39 typename iter_rvalue_reference_t<_In>; 40 { *__in } -> same_as<iter_reference_t<_In> >; 41 { ranges::iter_move(__in) } -> same_as<iter_rvalue_reference_t<_In> >; 42 } && 43 common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> && 44 common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> && 45 common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>; 46 47 template<class _In> 48 concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In> >; 49 50 // [iterator.concept.writable] 51 template<class _Out, class _Tp> 52 concept indirectly_writable = 53 requires(_Out&& __o, _Tp&& __t) { 54 *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 55 *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 56 const_cast<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 57 const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 58 }; 59 60 // [iterator.concept.winc] 61 template<class _Tp> 62 concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; 63 64 template<class _Tp> 65 concept __signed_integer_like = signed_integral<_Tp>; 66 67 template<class _Ip> 68 concept weakly_incrementable = 69 default_initializable<_Ip> && 70 movable<_Ip> && 71 requires(_Ip __i) { 72 typename iter_difference_t<_Ip>; 73 requires __signed_integer_like<iter_difference_t<_Ip> >; 74 { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving 75 __i++; // not required to be equality-preserving 76 }; 77 78 // [iterator.concept.inc] 79 template<class _Ip> 80 concept incrementable = 81 regular<_Ip> && 82 weakly_incrementable<_Ip> && 83 requires(_Ip __i) { 84 { __i++ } -> same_as<_Ip>; 85 }; 86 87 // [iterator.concept.iterator] 88 template<class _Ip> 89 concept input_or_output_iterator = 90 requires(_Ip __i) { 91 { *__i } -> __referenceable; 92 } && 93 weakly_incrementable<_Ip>; 94 95 // [iterator.concept.sentinel] 96 template<class _Sp, class _Ip> 97 concept sentinel_for = 98 semiregular<_Sp> && 99 input_or_output_iterator<_Ip> && 100 __weakly_equality_comparable_with<_Sp, _Ip>; 101 102 template<class, class> 103 inline constexpr bool disable_sized_sentinel_for = false; 104 105 template<class _Sp, class _Ip> 106 concept sized_sentinel_for = 107 sentinel_for<_Sp, _Ip> && 108 !disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip> > && 109 requires(const _Ip& __i, const _Sp& __s) { 110 { __s - __i } -> same_as<iter_difference_t<_Ip> >; 111 { __i - __s } -> same_as<iter_difference_t<_Ip> >; 112 }; 113 114 // clang-format on 115 116 #endif // !defined(_LIBCPP_HAS_NO_RANGES) 117 118 _LIBCPP_END_NAMESPACE_STD 119 120 _LIBCPP_POP_MACROS 121 122 #endif // _LIBCPP___ITERATOR_CONCEPTS_H 123