Horizon
Loading...
Searching...
No Matches
concepts.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2013-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13
14#ifndef RANGES_V3_RANGE_CONCEPTS_HPP
15#define RANGES_V3_RANGE_CONCEPTS_HPP
16
17#include <range/v3/detail/config.hpp>
18
19#include <initializer_list>
20#include <type_traits>
21#include <utility>
22
23#ifdef __has_include
24#if __has_include(<span>) && !defined(RANGES_WORKAROUND_MSVC_UNUSABLE_SPAN)
25#include <span>
26#endif
27#if __has_include(<string_view>)
28#include <string_view>
29#endif
30#endif
31
32#include <meta/meta.hpp>
33
34#include <concepts/concepts.hpp>
35
37
44
45#include <range/v3/detail/prologue.hpp>
46
47namespace ranges
48{
51
52 //
53 // Range concepts below
54 //
55
56 // clang-format off
59 template<typename T>
60 CPP_requires(_range_,
61 requires(T & t) //
62 (
63 ranges::begin(t), // not necessarily equality-preserving
64 ranges::end(t)
65 ));
68 template<typename T>
69 CPP_concept range =
70 CPP_requires_ref(ranges::_range_, T);
71
74 template<typename T>
75 CPP_concept borrowed_range =
76 range<T> && detail::_borrowed_range<T>;
77
78 template <typename R>
79 RANGES_DEPRECATED("Please use ranges::borrowed_range instead.")
80 RANGES_INLINE_VAR constexpr bool safe_range = borrowed_range<R>;
81
84 template(typename T, typename V)(
85 concept (output_range_)(T, V),
86 output_iterator<iterator_t<T>, V>
87 );
90 template<typename T, typename V>
91 CPP_concept output_range =
92 range<T> && CPP_concept_ref(ranges::output_range_, T, V);
93
96 template(typename T)(
97 concept (input_range_)(T),
98 input_iterator<iterator_t<T>>
99 );
102 template<typename T>
103 CPP_concept input_range =
104 range<T> && CPP_concept_ref(ranges::input_range_, T);
105
108 template(typename T)(
109 concept (forward_range_)(T),
110 forward_iterator<iterator_t<T>>
111 );
114 template<typename T>
115 CPP_concept forward_range =
116 input_range<T> && CPP_concept_ref(ranges::forward_range_, T);
117
120 template(typename T)(
121 concept (bidirectional_range_)(T),
122 bidirectional_iterator<iterator_t<T>>
123 );
126 template<typename T>
127 CPP_concept bidirectional_range =
128 forward_range<T> && CPP_concept_ref(ranges::bidirectional_range_, T);
129
132 template(typename T)(
133 concept (random_access_range_)(T),
134 random_access_iterator<iterator_t<T>>
135 );
136
139 template<typename T>
140 CPP_concept random_access_range =
141 bidirectional_range<T> && CPP_concept_ref(ranges::random_access_range_, T);
142 // clang-format on
143
145 namespace detail
146 {
147 template<typename Rng>
148 using data_t = decltype(ranges::data(std::declval<Rng &>()));
149
150 template<typename Rng>
152 } // namespace detail
154
155 // clang-format off
158 template(typename T)(
159 concept (contiguous_range_)(T),
160 contiguous_iterator<iterator_t<T>> AND
161 same_as<detail::data_t<T>, std::add_pointer_t<iter_reference_t<iterator_t<T>>>>
162 );
163
166 template<typename T>
167 CPP_concept contiguous_range =
168 random_access_range<T> && CPP_concept_ref(ranges::contiguous_range_, T);
169
172 template(typename T)(
173 concept (common_range_)(T),
174 same_as<iterator_t<T>, sentinel_t<T>>
175 );
176
179 template<typename T>
180 CPP_concept common_range =
181 range<T> && CPP_concept_ref(ranges::common_range_, T);
182
186 template<typename T>
187 CPP_concept bounded_range =
188 common_range<T>;
190
193 template<typename T>
194 CPP_requires(sized_range_,
195 requires(T & t) //
196 (
197 ranges::size(t)
198 ));
201 template(typename T)(
202 concept (sized_range_)(T),
203 detail::integer_like_<range_size_t<T>>);
204
207 template<typename T>
208 CPP_concept sized_range =
209 range<T> &&
210 !disable_sized_range<uncvref_t<T>> &&
211 CPP_requires_ref(ranges::sized_range_, T) &&
212 CPP_concept_ref(ranges::sized_range_, T);
213 // clang-format on
214
216 namespace ext
217 {
218 template<typename T>
219 struct enable_view
220 : std::is_base_of<view_base, T>
221 {};
222 } // namespace detail
224
225 // Specialize this if the default is wrong.
226 template<typename T>
227 RANGES_INLINE_VAR constexpr bool enable_view =
228 ext::enable_view<T>::value;
229
230#if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201603L
231 template<typename Char, typename Traits>
232 RANGES_INLINE_VAR constexpr bool enable_view<std::basic_string_view<Char, Traits>> =
233 true;
234#endif
235
236// libstdc++'s <span> header only defines std::span when concepts
237// are also enabled. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97869
238#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L && \
239 (!defined(__GLIBCXX__) || defined(__cpp_lib_concepts))
240 template<typename T, std::size_t N>
241 RANGES_INLINE_VAR constexpr bool enable_view<std::span<T, N>> = N + 1 < 2;
242#endif
243
244 //
245 // View concepts below
246 //
247
248 // clang-format off
251 template<typename T>
252 CPP_concept view_ =
253 range<T> &&
254 semiregular<T> &&
255 enable_view<T>;
256
259 template<typename T>
260 CPP_concept viewable_range =
261 range<T> &&
262 (borrowed_range<T> || view_<uncvref_t<T>>);
263 // clang-format on
264
266 // range_tag
268 {};
269
271 {};
280
281 template<typename Rng>
282 using range_tag_of = //
283 std::enable_if_t< //
284 range<Rng>, //
300 range_tag>>>>>>;
301
303 // common_range_tag_of
305 {};
306
307 template<typename Rng>
308 using common_range_tag_of = //
309 std::enable_if_t< //
310 range<Rng>, //
312
314 // sized_range_concept
316 {};
317
318 template<typename Rng>
319 using sized_range_tag_of = //
320 std::enable_if_t< //
321 range<Rng>, //
323
325 namespace view_detail_
326 {
327 // clang-format off
330 template<typename T>
331 CPP_concept view =
333 // clang-format on
334 } // namespace view_detail_
336
337 namespace cpp20
338 {
343 using ranges::enable_view;
348 using ranges::range;
351 using ranges::view_detail_::view;
352 using ranges::view_base;
353 } // namespace cpp20
355} // namespace ranges
356
357#include <range/v3/detail/epilogue.hpp>
358
359#endif
The _range_ concept.
The bidirectional_range concept.
The borrowed_range concept.
The common_range_ concept.
The common_range concept.
The contiguous_range_ concept.
The contiguous_range concept.
The forward_range concept.
The input_range concept.
The output_range concept.
The random_access_range concept.
The range concept.
The sized_range_ concept.
The sized_range concept.
The view_ concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
typename T::type _t
Type alias for T::type.
Definition meta.hpp:141
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition meta.hpp:1148
Tiny meta-programming library.
Definition concepts.hpp:275
Definition concepts.hpp:305
Definition concepts.hpp:279
Definition concepts.hpp:273
Definition concepts.hpp:271
Definition concepts.hpp:277
Definition concepts.hpp:268
Definition concepts.hpp:316
Definition range_fwd.hpp:182