176d0caaeSpatrick // -*- C++ -*- 276d0caaeSpatrick //===----------------------------------------------------------------------===// 376d0caaeSpatrick // 476d0caaeSpatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 576d0caaeSpatrick // See https://llvm.org/LICENSE.txt for license information. 676d0caaeSpatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 776d0caaeSpatrick // 876d0caaeSpatrick //===----------------------------------------------------------------------===// 976d0caaeSpatrick 1076d0caaeSpatrick #ifndef _LIBCPP___ITERATOR_CONCEPTS_H 1176d0caaeSpatrick #define _LIBCPP___ITERATOR_CONCEPTS_H 1276d0caaeSpatrick 13*4bdff4beSrobert #include <__concepts/arithmetic.h> 14*4bdff4beSrobert #include <__concepts/assignable.h> 15*4bdff4beSrobert #include <__concepts/common_reference_with.h> 16*4bdff4beSrobert #include <__concepts/constructible.h> 17*4bdff4beSrobert #include <__concepts/copyable.h> 18*4bdff4beSrobert #include <__concepts/derived_from.h> 19*4bdff4beSrobert #include <__concepts/equality_comparable.h> 20*4bdff4beSrobert #include <__concepts/invocable.h> 21*4bdff4beSrobert #include <__concepts/movable.h> 22*4bdff4beSrobert #include <__concepts/predicate.h> 23*4bdff4beSrobert #include <__concepts/regular.h> 24*4bdff4beSrobert #include <__concepts/relation.h> 25*4bdff4beSrobert #include <__concepts/same_as.h> 26*4bdff4beSrobert #include <__concepts/semiregular.h> 27*4bdff4beSrobert #include <__concepts/totally_ordered.h> 2876d0caaeSpatrick #include <__config> 29*4bdff4beSrobert #include <__functional/invoke.h> 3076d0caaeSpatrick #include <__iterator/incrementable_traits.h> 3176d0caaeSpatrick #include <__iterator/iter_move.h> 3276d0caaeSpatrick #include <__iterator/iterator_traits.h> 3376d0caaeSpatrick #include <__iterator/readable_traits.h> 3476d0caaeSpatrick #include <__memory/pointer_traits.h> 35*4bdff4beSrobert #include <__type_traits/add_pointer.h> 36*4bdff4beSrobert #include <__type_traits/common_reference.h> 37*4bdff4beSrobert #include <__type_traits/is_pointer.h> 38*4bdff4beSrobert #include <__type_traits/is_reference.h> 39*4bdff4beSrobert #include <__type_traits/remove_cv.h> 40*4bdff4beSrobert #include <__type_traits/remove_cvref.h> 4176d0caaeSpatrick #include <__utility/forward.h> 4276d0caaeSpatrick 4376d0caaeSpatrick #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 4476d0caaeSpatrick # pragma GCC system_header 4576d0caaeSpatrick #endif 4676d0caaeSpatrick 4776d0caaeSpatrick _LIBCPP_BEGIN_NAMESPACE_STD 4876d0caaeSpatrick 49*4bdff4beSrobert #if _LIBCPP_STD_VER > 17 5076d0caaeSpatrick 5176d0caaeSpatrick // [iterator.concept.readable] 5276d0caaeSpatrick template<class _In> 5376d0caaeSpatrick concept __indirectly_readable_impl = requires(const _In __i)5476d0caaeSpatrick requires(const _In __i) { 5576d0caaeSpatrick typename iter_value_t<_In>; 5676d0caaeSpatrick typename iter_reference_t<_In>; 5776d0caaeSpatrick typename iter_rvalue_reference_t<_In>; 5876d0caaeSpatrick { *__i } -> same_as<iter_reference_t<_In>>; 5976d0caaeSpatrick { ranges::iter_move(__i) } -> same_as<iter_rvalue_reference_t<_In>>; 6076d0caaeSpatrick } && 6176d0caaeSpatrick common_reference_with<iter_reference_t<_In>&&, iter_value_t<_In>&> && 6276d0caaeSpatrick common_reference_with<iter_reference_t<_In>&&, iter_rvalue_reference_t<_In>&&> && 6376d0caaeSpatrick common_reference_with<iter_rvalue_reference_t<_In>&&, const iter_value_t<_In>&>; 6476d0caaeSpatrick 6576d0caaeSpatrick template<class _In> 6676d0caaeSpatrick concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>; 6776d0caaeSpatrick 6876d0caaeSpatrick template<indirectly_readable _Tp> 6976d0caaeSpatrick using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>; 7076d0caaeSpatrick 7176d0caaeSpatrick // [iterator.concept.writable] 7276d0caaeSpatrick template<class _Out, class _Tp> 7376d0caaeSpatrick concept indirectly_writable = requires(_Out && __o,_Tp && __t)7476d0caaeSpatrick requires(_Out&& __o, _Tp&& __t) { 7576d0caaeSpatrick *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 7676d0caaeSpatrick *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 7776d0caaeSpatrick const_cast<const iter_reference_t<_Out>&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 7876d0caaeSpatrick const_cast<const iter_reference_t<_Out>&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 7976d0caaeSpatrick }; 8076d0caaeSpatrick 8176d0caaeSpatrick // [iterator.concept.winc] 8276d0caaeSpatrick template<class _Tp> 8376d0caaeSpatrick concept __integer_like = integral<_Tp> && !same_as<_Tp, bool>; 8476d0caaeSpatrick 8576d0caaeSpatrick template<class _Tp> 8676d0caaeSpatrick concept __signed_integer_like = signed_integral<_Tp>; 8776d0caaeSpatrick 8876d0caaeSpatrick template<class _Ip> 8976d0caaeSpatrick concept weakly_incrementable = 90*4bdff4beSrobert // TODO: remove this once the clang bug is fixed (bugs.llvm.org/PR48173). 91*4bdff4beSrobert !same_as<_Ip, bool> && // Currently, clang does not handle bool correctly. 9276d0caaeSpatrick movable<_Ip> && 9376d0caaeSpatrick requires(_Ip __i) { 9476d0caaeSpatrick typename iter_difference_t<_Ip>; 9576d0caaeSpatrick requires __signed_integer_like<iter_difference_t<_Ip>>; 9676d0caaeSpatrick { ++__i } -> same_as<_Ip&>; // not required to be equality-preserving 9776d0caaeSpatrick __i++; // not required to be equality-preserving 9876d0caaeSpatrick }; 9976d0caaeSpatrick 10076d0caaeSpatrick // [iterator.concept.inc] 10176d0caaeSpatrick template<class _Ip> 10276d0caaeSpatrick concept incrementable = 10376d0caaeSpatrick regular<_Ip> && 10476d0caaeSpatrick weakly_incrementable<_Ip> && requires(_Ip __i)10576d0caaeSpatrick requires(_Ip __i) { 10676d0caaeSpatrick { __i++ } -> same_as<_Ip>; 10776d0caaeSpatrick }; 10876d0caaeSpatrick 10976d0caaeSpatrick // [iterator.concept.iterator] 11076d0caaeSpatrick template<class _Ip> 11176d0caaeSpatrick concept input_or_output_iterator = requires(_Ip __i)11276d0caaeSpatrick requires(_Ip __i) { 113*4bdff4beSrobert { *__i } -> __can_reference; 11476d0caaeSpatrick } && 11576d0caaeSpatrick weakly_incrementable<_Ip>; 11676d0caaeSpatrick 11776d0caaeSpatrick // [iterator.concept.sentinel] 11876d0caaeSpatrick template<class _Sp, class _Ip> 11976d0caaeSpatrick concept sentinel_for = 12076d0caaeSpatrick semiregular<_Sp> && 12176d0caaeSpatrick input_or_output_iterator<_Ip> && 12276d0caaeSpatrick __weakly_equality_comparable_with<_Sp, _Ip>; 12376d0caaeSpatrick 12476d0caaeSpatrick template<class, class> 12576d0caaeSpatrick inline constexpr bool disable_sized_sentinel_for = false; 12676d0caaeSpatrick 12776d0caaeSpatrick template<class _Sp, class _Ip> 12876d0caaeSpatrick concept sized_sentinel_for = 12976d0caaeSpatrick sentinel_for<_Sp, _Ip> && 13076d0caaeSpatrick !disable_sized_sentinel_for<remove_cv_t<_Sp>, remove_cv_t<_Ip>> && 13176d0caaeSpatrick requires(const _Ip& __i, const _Sp& __s) { 13276d0caaeSpatrick { __s - __i } -> same_as<iter_difference_t<_Ip>>; 13376d0caaeSpatrick { __i - __s } -> same_as<iter_difference_t<_Ip>>; 13476d0caaeSpatrick }; 13576d0caaeSpatrick 13676d0caaeSpatrick // [iterator.concept.input] 13776d0caaeSpatrick template<class _Ip> 13876d0caaeSpatrick concept input_iterator = 13976d0caaeSpatrick input_or_output_iterator<_Ip> && 14076d0caaeSpatrick indirectly_readable<_Ip> && 14176d0caaeSpatrick requires { typename _ITER_CONCEPT<_Ip>; } && 14276d0caaeSpatrick derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>; 14376d0caaeSpatrick 14476d0caaeSpatrick // [iterator.concept.output] 14576d0caaeSpatrick template<class _Ip, class _Tp> 14676d0caaeSpatrick concept output_iterator = 14776d0caaeSpatrick input_or_output_iterator<_Ip> && 14876d0caaeSpatrick indirectly_writable<_Ip, _Tp> && requires(_Ip __it,_Tp && __t)14976d0caaeSpatrick requires (_Ip __it, _Tp&& __t) { 15076d0caaeSpatrick *__it++ = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving 15176d0caaeSpatrick }; 15276d0caaeSpatrick 15376d0caaeSpatrick // [iterator.concept.forward] 15476d0caaeSpatrick template<class _Ip> 15576d0caaeSpatrick concept forward_iterator = 15676d0caaeSpatrick input_iterator<_Ip> && 15776d0caaeSpatrick derived_from<_ITER_CONCEPT<_Ip>, forward_iterator_tag> && 15876d0caaeSpatrick incrementable<_Ip> && 15976d0caaeSpatrick sentinel_for<_Ip, _Ip>; 16076d0caaeSpatrick 16176d0caaeSpatrick // [iterator.concept.bidir] 16276d0caaeSpatrick template<class _Ip> 16376d0caaeSpatrick concept bidirectional_iterator = 16476d0caaeSpatrick forward_iterator<_Ip> && 16576d0caaeSpatrick derived_from<_ITER_CONCEPT<_Ip>, bidirectional_iterator_tag> && requires(_Ip __i)16676d0caaeSpatrick requires(_Ip __i) { 16776d0caaeSpatrick { --__i } -> same_as<_Ip&>; 16876d0caaeSpatrick { __i-- } -> same_as<_Ip>; 16976d0caaeSpatrick }; 17076d0caaeSpatrick 17176d0caaeSpatrick template<class _Ip> 17276d0caaeSpatrick concept random_access_iterator = 17376d0caaeSpatrick bidirectional_iterator<_Ip> && 17476d0caaeSpatrick derived_from<_ITER_CONCEPT<_Ip>, random_access_iterator_tag> && 17576d0caaeSpatrick totally_ordered<_Ip> && 17676d0caaeSpatrick sized_sentinel_for<_Ip, _Ip> && requires(_Ip __i,const _Ip __j,const iter_difference_t<_Ip> __n)17776d0caaeSpatrick requires(_Ip __i, const _Ip __j, const iter_difference_t<_Ip> __n) { 17876d0caaeSpatrick { __i += __n } -> same_as<_Ip&>; 17976d0caaeSpatrick { __j + __n } -> same_as<_Ip>; 18076d0caaeSpatrick { __n + __j } -> same_as<_Ip>; 18176d0caaeSpatrick { __i -= __n } -> same_as<_Ip&>; 18276d0caaeSpatrick { __j - __n } -> same_as<_Ip>; 18376d0caaeSpatrick { __j[__n] } -> same_as<iter_reference_t<_Ip>>; 18476d0caaeSpatrick }; 18576d0caaeSpatrick 18676d0caaeSpatrick template<class _Ip> 18776d0caaeSpatrick concept contiguous_iterator = 18876d0caaeSpatrick random_access_iterator<_Ip> && 18976d0caaeSpatrick derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && 19076d0caaeSpatrick is_lvalue_reference_v<iter_reference_t<_Ip>> && 19176d0caaeSpatrick same_as<iter_value_t<_Ip>, remove_cvref_t<iter_reference_t<_Ip>>> && requires(const _Ip & __i)19276d0caaeSpatrick requires(const _Ip& __i) { 19376d0caaeSpatrick { _VSTD::to_address(__i) } -> same_as<add_pointer_t<iter_reference_t<_Ip>>>; 19476d0caaeSpatrick }; 19576d0caaeSpatrick 19676d0caaeSpatrick template<class _Ip> 19776d0caaeSpatrick concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip __i) { __i.operator->(); }); 19876d0caaeSpatrick 19976d0caaeSpatrick // [indirectcallable.indirectinvocable] 20076d0caaeSpatrick template<class _Fp, class _It> 20176d0caaeSpatrick concept indirectly_unary_invocable = 20276d0caaeSpatrick indirectly_readable<_It> && 20376d0caaeSpatrick copy_constructible<_Fp> && 20476d0caaeSpatrick invocable<_Fp&, iter_value_t<_It>&> && 20576d0caaeSpatrick invocable<_Fp&, iter_reference_t<_It>> && 20676d0caaeSpatrick invocable<_Fp&, iter_common_reference_t<_It>> && 20776d0caaeSpatrick common_reference_with< 20876d0caaeSpatrick invoke_result_t<_Fp&, iter_value_t<_It>&>, 20976d0caaeSpatrick invoke_result_t<_Fp&, iter_reference_t<_It>>>; 21076d0caaeSpatrick 21176d0caaeSpatrick template<class _Fp, class _It> 21276d0caaeSpatrick concept indirectly_regular_unary_invocable = 21376d0caaeSpatrick indirectly_readable<_It> && 21476d0caaeSpatrick copy_constructible<_Fp> && 21576d0caaeSpatrick regular_invocable<_Fp&, iter_value_t<_It>&> && 21676d0caaeSpatrick regular_invocable<_Fp&, iter_reference_t<_It>> && 21776d0caaeSpatrick regular_invocable<_Fp&, iter_common_reference_t<_It>> && 21876d0caaeSpatrick common_reference_with< 21976d0caaeSpatrick invoke_result_t<_Fp&, iter_value_t<_It>&>, 22076d0caaeSpatrick invoke_result_t<_Fp&, iter_reference_t<_It>>>; 22176d0caaeSpatrick 22276d0caaeSpatrick template<class _Fp, class _It> 22376d0caaeSpatrick concept indirect_unary_predicate = 22476d0caaeSpatrick indirectly_readable<_It> && 22576d0caaeSpatrick copy_constructible<_Fp> && 22676d0caaeSpatrick predicate<_Fp&, iter_value_t<_It>&> && 22776d0caaeSpatrick predicate<_Fp&, iter_reference_t<_It>> && 22876d0caaeSpatrick predicate<_Fp&, iter_common_reference_t<_It>>; 22976d0caaeSpatrick 23076d0caaeSpatrick template<class _Fp, class _It1, class _It2> 23176d0caaeSpatrick concept indirect_binary_predicate = 23276d0caaeSpatrick indirectly_readable<_It1> && indirectly_readable<_It2> && 23376d0caaeSpatrick copy_constructible<_Fp> && 23476d0caaeSpatrick predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && 23576d0caaeSpatrick predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && 23676d0caaeSpatrick predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && 23776d0caaeSpatrick predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && 23876d0caaeSpatrick predicate<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; 23976d0caaeSpatrick 24076d0caaeSpatrick template<class _Fp, class _It1, class _It2 = _It1> 24176d0caaeSpatrick concept indirect_equivalence_relation = 24276d0caaeSpatrick indirectly_readable<_It1> && indirectly_readable<_It2> && 24376d0caaeSpatrick copy_constructible<_Fp> && 24476d0caaeSpatrick equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && 24576d0caaeSpatrick equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && 24676d0caaeSpatrick equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && 24776d0caaeSpatrick equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && 24876d0caaeSpatrick equivalence_relation<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; 24976d0caaeSpatrick 25076d0caaeSpatrick template<class _Fp, class _It1, class _It2 = _It1> 25176d0caaeSpatrick concept indirect_strict_weak_order = 25276d0caaeSpatrick indirectly_readable<_It1> && indirectly_readable<_It2> && 25376d0caaeSpatrick copy_constructible<_Fp> && 25476d0caaeSpatrick strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> && 25576d0caaeSpatrick strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> && 25676d0caaeSpatrick strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> && 25776d0caaeSpatrick strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>> && 25876d0caaeSpatrick strict_weak_order<_Fp&, iter_common_reference_t<_It1>, iter_common_reference_t<_It2>>; 25976d0caaeSpatrick 26076d0caaeSpatrick template<class _Fp, class... _Its> 26176d0caaeSpatrick requires (indirectly_readable<_Its> && ...) && invocable<_Fp, iter_reference_t<_Its>...> 26276d0caaeSpatrick using indirect_result_t = invoke_result_t<_Fp, iter_reference_t<_Its>...>; 26376d0caaeSpatrick 26476d0caaeSpatrick template<class _In, class _Out> 26576d0caaeSpatrick concept indirectly_movable = 26676d0caaeSpatrick indirectly_readable<_In> && 26776d0caaeSpatrick indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; 26876d0caaeSpatrick 26976d0caaeSpatrick template<class _In, class _Out> 27076d0caaeSpatrick concept indirectly_movable_storable = 27176d0caaeSpatrick indirectly_movable<_In, _Out> && 27276d0caaeSpatrick indirectly_writable<_Out, iter_value_t<_In>> && 27376d0caaeSpatrick movable<iter_value_t<_In>> && 27476d0caaeSpatrick constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> && 27576d0caaeSpatrick assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>; 27676d0caaeSpatrick 277*4bdff4beSrobert template<class _In, class _Out> 278*4bdff4beSrobert concept indirectly_copyable = 279*4bdff4beSrobert indirectly_readable<_In> && 280*4bdff4beSrobert indirectly_writable<_Out, iter_reference_t<_In>>; 281*4bdff4beSrobert 282*4bdff4beSrobert template<class _In, class _Out> 283*4bdff4beSrobert concept indirectly_copyable_storable = 284*4bdff4beSrobert indirectly_copyable<_In, _Out> && 285*4bdff4beSrobert indirectly_writable<_Out, iter_value_t<_In>&> && 286*4bdff4beSrobert indirectly_writable<_Out, const iter_value_t<_In>&> && 287*4bdff4beSrobert indirectly_writable<_Out, iter_value_t<_In>&&> && 288*4bdff4beSrobert indirectly_writable<_Out, const iter_value_t<_In>&&> && 289*4bdff4beSrobert copyable<iter_value_t<_In>> && 290*4bdff4beSrobert constructible_from<iter_value_t<_In>, iter_reference_t<_In>> && 291*4bdff4beSrobert assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>; 292*4bdff4beSrobert 29376d0caaeSpatrick // Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle 29476d0caaeSpatrick // (both iter_swap and indirectly_swappable require indirectly_readable). 29576d0caaeSpatrick 296*4bdff4beSrobert #endif // _LIBCPP_STD_VER > 17 29776d0caaeSpatrick 29876d0caaeSpatrick _LIBCPP_END_NAMESPACE_STD 29976d0caaeSpatrick 30076d0caaeSpatrick #endif // _LIBCPP___ITERATOR_CONCEPTS_H 301