1 // -*- C++ -*- 2 //===--------------------- __ranges/concepts.h ----------------------------===// 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 #ifndef _LIBCPP___RANGES_CONCEPTS_H 10 #define _LIBCPP___RANGES_CONCEPTS_H 11 12 #include <__config> 13 #include <__iterator/concepts.h> 14 #include <__iterator/incrementable_traits.h> 15 #include <__iterator/iter_move.h> 16 #include <__iterator/iterator_traits.h> 17 #include <__iterator/readable_traits.h> 18 #include <__ranges/access.h> 19 #include <__ranges/enable_borrowed_range.h> 20 #include <__ranges/data.h> 21 #include <__ranges/enable_view.h> 22 #include <__ranges/size.h> 23 #include <concepts> 24 #include <type_traits> 25 26 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 27 #pragma GCC system_header 28 #endif 29 30 _LIBCPP_PUSH_MACROS 31 #include <__undef_macros> 32 33 _LIBCPP_BEGIN_NAMESPACE_STD 34 35 // clang-format off 36 37 #if !defined(_LIBCPP_HAS_NO_RANGES) 38 39 namespace ranges { 40 // [range.range] 41 template <class _Tp> 42 concept range = requires(_Tp& __t) { 43 ranges::begin(__t); // sometimes equality-preserving 44 ranges::end(__t); 45 }; 46 47 template<class _Range> 48 concept borrowed_range = range<_Range> && 49 (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>); 50 51 // `iterator_t` defined in <__ranges/access.h> 52 53 template <range _Rp> 54 using sentinel_t = decltype(ranges::end(declval<_Rp&>())); 55 56 template <range _Rp> 57 using range_difference_t = iter_difference_t<iterator_t<_Rp>>; 58 59 template <range _Rp> 60 using range_value_t = iter_value_t<iterator_t<_Rp>>; 61 62 template <range _Rp> 63 using range_reference_t = iter_reference_t<iterator_t<_Rp>>; 64 65 template <range _Rp> 66 using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>; 67 68 // [range.sized] 69 template <class _Tp> 70 concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; 71 72 template<sized_range _Rp> 73 using range_size_t = decltype(ranges::size(declval<_Rp&>())); 74 75 // `disable_sized_range` defined in `<__ranges/size.h>` 76 77 // [range.view], views 78 79 // `enable_view` defined in <__ranges/enable_view.h> 80 // `view_base` defined in <__ranges/enable_view.h> 81 82 template <class _Tp> 83 concept view = 84 range<_Tp> && 85 movable<_Tp> && 86 enable_view<_Tp>; 87 88 template<class _Range> 89 concept __simple_view = 90 view<_Range> && range<const _Range> && 91 same_as<iterator_t<_Range>, iterator_t<const _Range>> && 92 same_as<sentinel_t<_Range>, iterator_t<const _Range>>; 93 94 // [range.refinements], other range refinements 95 template <class _Rp, class _Tp> 96 concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>; 97 98 template <class _Tp> 99 concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>; 100 101 template <class _Tp> 102 concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>; 103 104 template <class _Tp> 105 concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>; 106 107 template <class _Tp> 108 concept random_access_range = 109 bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>; 110 111 template<class _Tp> 112 concept contiguous_range = 113 random_access_range<_Tp> && 114 contiguous_iterator<iterator_t<_Tp>> && 115 requires(_Tp& __t) { 116 { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>; 117 }; 118 119 template <class _Tp> 120 concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; 121 122 template<class _Tp> 123 concept viewable_range = 124 range<_Tp> && ( 125 (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || 126 (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>) 127 ); 128 } // namespace ranges 129 130 #endif // !defined(_LIBCPP_HAS_NO_RANGES) 131 132 // clang-format on 133 134 _LIBCPP_END_NAMESPACE_STD 135 136 _LIBCPP_POP_MACROS 137 138 #endif // _LIBCPP___RANGES_CONCEPTS_H 139