2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___RANGES_CONCEPTS_H
11 #define _LIBCPP___RANGES_CONCEPTS_H
13 #include <__concepts/constructible.h>
14 #include <__concepts/movable.h>
15 #include <__concepts/same_as.h>
17 #include <__iterator/concepts.h>
18 #include <__iterator/incrementable_traits.h>
19 #include <__iterator/iter_move.h>
20 #include <__iterator/iterator_traits.h>
21 #include <__iterator/readable_traits.h>
22 #include <__ranges/access.h>
23 #include <__ranges/data.h>
24 #include <__ranges/enable_borrowed_range.h>
25 #include <__ranges/enable_view.h>
26 #include <__ranges/size.h>
27 #include <__type_traits/add_pointer.h>
28 #include <__type_traits/is_reference.h>
29 #include <__type_traits/remove_cvref.h>
30 #include <__type_traits/remove_reference.h>
31 #include <__utility/declval.h>
32 #include <initializer_list>
34 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
35 # pragma GCC system_header
38 _LIBCPP_BEGIN_NAMESPACE_STD
40 #if _LIBCPP_STD_VER >= 20
47 concept range
= requires(_Tp
& __t
) {
48 ranges::begin(__t
); // sometimes equality-preserving
53 concept input_range
= range
<_Tp
> && input_iterator
<iterator_t
<_Tp
>>;
55 template<class _Range
>
56 concept borrowed_range
= range
<_Range
> &&
57 (is_lvalue_reference_v
<_Range
> || enable_borrowed_range
<remove_cvref_t
<_Range
>>);
59 // `iterator_t` defined in <__ranges/access.h>
62 using sentinel_t
= decltype(ranges::end(std::declval
<_Rp
&>()));
65 using range_difference_t
= iter_difference_t
<iterator_t
<_Rp
>>;
68 using range_value_t
= iter_value_t
<iterator_t
<_Rp
>>;
71 using range_reference_t
= iter_reference_t
<iterator_t
<_Rp
>>;
74 using range_rvalue_reference_t
= iter_rvalue_reference_t
<iterator_t
<_Rp
>>;
77 using range_common_reference_t
= iter_common_reference_t
<iterator_t
<_Rp
>>;
81 concept sized_range
= range
<_Tp
> && requires(_Tp
& __t
) { ranges::size(__t
); };
83 template<sized_range _Rp
>
84 using range_size_t
= decltype(ranges::size(std::declval
<_Rp
&>()));
86 // `disable_sized_range` defined in `<__ranges/size.h>`
88 // [range.view], views
90 // `enable_view` defined in <__ranges/enable_view.h>
91 // `view_base` defined in <__ranges/enable_view.h>
99 template <class _Range
>
100 concept __simple_view
=
101 view
<_Range
> && range
<const _Range
> &&
102 same_as
<iterator_t
<_Range
>, iterator_t
<const _Range
>> &&
103 same_as
<sentinel_t
<_Range
>, sentinel_t
<const _Range
>>;
105 // [range.refinements], other range refinements
106 template <class _Rp
, class _Tp
>
107 concept output_range
= range
<_Rp
> && output_iterator
<iterator_t
<_Rp
>, _Tp
>;
110 concept forward_range
= input_range
<_Tp
> && forward_iterator
<iterator_t
<_Tp
>>;
113 concept bidirectional_range
= forward_range
<_Tp
> && bidirectional_iterator
<iterator_t
<_Tp
>>;
116 concept random_access_range
=
117 bidirectional_range
<_Tp
> && random_access_iterator
<iterator_t
<_Tp
>>;
120 concept contiguous_range
=
121 random_access_range
<_Tp
> &&
122 contiguous_iterator
<iterator_t
<_Tp
>> &&
124 { ranges::data(__t
) } -> same_as
<add_pointer_t
<range_reference_t
<_Tp
>>>;
128 concept common_range
= range
<_Tp
> && same_as
<iterator_t
<_Tp
>, sentinel_t
<_Tp
>>;
131 inline constexpr bool __is_std_initializer_list
= false;
134 inline constexpr bool __is_std_initializer_list
<initializer_list
<_Ep
>> = true;
137 concept viewable_range
=
139 ((view
<remove_cvref_t
<_Tp
>> && constructible_from
<remove_cvref_t
<_Tp
>, _Tp
>) ||
140 (!view
<remove_cvref_t
<_Tp
>> &&
141 (is_lvalue_reference_v
<_Tp
> ||
142 (movable
<remove_reference_t
<_Tp
>> && !__is_std_initializer_list
<remove_cvref_t
<_Tp
>>))));
144 } // namespace ranges
146 #endif // _LIBCPP_STD_VER >= 20
148 _LIBCPP_END_NAMESPACE_STD
150 #endif // _LIBCPP___RANGES_CONCEPTS_H