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