Horizon
concepts.hpp
Go to the documentation of this file.
1 // 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 
36 #include <range/v3/range_fwd.hpp>
37 
44 
45 #include <range/v3/detail/prologue.hpp>
46 
47 namespace 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),
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),
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),
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),
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),
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>
151  using element_t = meta::_t<std::remove_pointer<data_t<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
267  struct range_tag
268  {};
269 
271  {};
273  {};
275  {};
277  {};
279  {};
280 
281  template<typename Rng>
282  using range_tag_of = //
283  std::enable_if_t< //
284  range<Rng>, //
286  contiguous_range<Rng>, //
289  random_access_range<Rng>, //
292  bidirectional_range<Rng>, //
295  forward_range<Rng>, //
298  input_range<Rng>, //
299  input_range_tag, //
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 =
332  ranges::view_<T>;
333  // clang-format on
334  } // namespace view_detail_
336 
337  namespace cpp20
338  {
341  using ranges::common_range;
343  using ranges::enable_view;
344  using ranges::forward_range;
345  using ranges::input_range;
346  using ranges::output_range;
348  using ranges::range;
349  using ranges::sized_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
CPP_concept output_iterator
\concept output_iterator
Definition: concepts.hpp:347
CPP_concept input_iterator
\concept input_iterator
Definition: concepts.hpp:362
CPP_concept bidirectional_iterator
\concept bidirectional_iterator
Definition: concepts.hpp:390
CPP_concept contiguous_iterator
\concept contiguous_iterator
Definition: concepts.hpp:435
CPP_concept forward_iterator
\concept forward_iterator
Definition: concepts.hpp:370
CPP_concept random_access_iterator
\concept random_access_iterator
Definition: concepts.hpp:416
template(typename T, typename V)(concept(output_range_)(T
\concept output_range_
CPP_requires(sized_range_, requires(T &t)(ranges::size(t)))
\concept sized_range_
CPP_concept sized_range
\concept sized_range
Definition: concepts.hpp:208
CPP_concept bidirectional_range
\concept bidirectional_range
Definition: concepts.hpp:127
CPP_concept common_range
\concept common_range
Definition: concepts.hpp:180
CPP_concept forward_range
\concept forward_range
Definition: concepts.hpp:115
CPP_concept input_range
\concept input_range
Definition: concepts.hpp:103
CPP_concept viewable_range
\concept viewable_range
Definition: concepts.hpp:260
CPP_concept borrowed_range
\concept borrowed_range
Definition: concepts.hpp:75
CPP_concept output_range
\concept output_range
Definition: concepts.hpp:91
CPP_concept contiguous_range
\concept contiguous_range
Definition: concepts.hpp:167
CPP_concept random_access_range
\concept random_access_range
Definition: concepts.hpp:140
CPP_concept view_
\concept view_
Definition: concepts.hpp:252
CPP_concept range
\concept range
Definition: concepts.hpp:69
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
typename T::type _t
Type alias for T::type.
Definition: meta.hpp:141
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition: meta.hpp:1696
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