13 #ifndef RANGES_V3_VIEW_INTERFACE_HPP
14 #define RANGES_V3_VIEW_INTERFACE_HPP
31 #include <range/v3/detail/prologue.hpp>
33 #if defined(RANGES_WORKAROUND_GCC_91525)
34 #define CPP_template_gcc_workaround CPP_template_sfinae
36 #define CPP_template_gcc_workaround template
44 template<
typename From,
typename To = From>
49 template(
typename F,
typename T)(
50 requires convertible_to<F, From> AND convertible_to<T, To>)
51 constexpr slice_bounds(F f, T t)
52 : from(static_cast<From>(f))
53 , to(static_cast<To>(t))
57 template<
typename Int>
62 constexpr
explicit from_end_(Int dist)
66 template(
typename Other)(
67 requires integer_like_<Other> AND explicitly_convertible_to<Other, Int>)
68 constexpr
operator from_end_<Other>()
const
70 return from_end_<Other>{
static_cast<Other
>(dist_)};
74 template<
typename Rng>
75 using from_end_of_t = from_end_<range_difference_t<Rng>>;
80 template<
typename Rng>
81 CPP_requires(_can_empty_,
88 template<
typename Rng>
89 CPP_concept can_empty_ =
90 CPP_requires_ref(detail::_can_empty_, Rng);
93 template<cardinality C>
94 RANGES_INLINE_VAR constexpr
bool has_fixed_size_ = (C >= 0 || C == infinite);
103 template<
typename Stream,
typename Rng>
104 Stream & print_rng_(Stream & sout, Rng & rng)
107 auto it = ranges::begin(rng);
108 auto const e = ranges::end(rng);
127 template<
typename Derived, cardinality Cardinality >
134 constexpr Derived & derived() noexcept
136 CPP_assert(derived_from<Derived, view_interface>);
137 return static_cast<Derived &
>(*this);
140 constexpr Derived
const &
derived() const noexcept
142 CPP_assert(derived_from<Derived, view_interface>);
143 return static_cast<Derived
const &
>(*this);
154 constexpr
auto empty() const noexcept
156 requires (detail::has_fixed_size_<Cardinality>))
158 return Cardinality == 0;
161 template(
bool True =
true)(
162 requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
164 constexpr
bool empty()
165 noexcept(noexcept(
bool(ranges::
size(std::declval<D<True> &>()) == 0)))
170 template(
bool True =
true)(
171 requires True AND (Cardinality < 0) AND (Cardinality != infinite) AND
173 constexpr
bool empty() const
174 noexcept(noexcept(
bool(ranges::
size(std::declval<D<True> const &>()) == 0)))
179 template(
bool True =
true)(
180 requires True AND (!detail::has_fixed_size_<Cardinality>) AND
181 forward_range<D<True>>)
182 constexpr
bool empty() noexcept(
183 noexcept(
bool(ranges::begin(std::declval<D<True> &>()) ==
184 ranges::end(std::declval<D<True> &>()))))
186 return bool(ranges::begin(derived()) == ranges::end(derived()));
189 template(
bool True =
true)(
190 requires True AND (!detail::has_fixed_size_<Cardinality>) AND
191 forward_range<D<True>
const>)
192 constexpr
bool empty()
const
193 noexcept(noexcept(
bool(ranges::begin(std::declval<D<True>
const &>()) ==
194 ranges::end(std::declval<D<True>
const &>()))))
196 return bool(ranges::begin(derived()) == ranges::end(derived()));
198 CPP_template_gcc_workaround(
bool True =
true)(
199 requires True && detail::can_empty_<D<True>>)
200 constexpr
explicit operator bool()
207 CPP_template_gcc_workaround(
bool True =
true)(
208 requires True && detail::can_empty_<D<True>
const>)
209 constexpr
explicit operator bool()
const
210 noexcept(noexcept(
ranges::empty(std::declval<D<True>
const &>())))
217 template(
bool True =
true,
int = 42)(
218 requires True AND (Cardinality >= 0))
226 template(
bool True =
true)(
227 requires True AND (Cardinality < 0) AND
228 sized_sentinel_for<sentinel_t<D<True>>, iterator_t<D<True>>> AND
229 forward_range<D<True>>)
232 using size_type = detail::iter_size_t<iterator_t<D<True>>>;
233 return static_cast<size_type
>(derived().end() - derived().begin());
236 template(
bool True =
true)(
237 requires True AND (Cardinality < 0) AND
238 sized_sentinel_for<sentinel_t<D<True>
const>,
239 iterator_t<D<True>
const>> AND
240 forward_range<D<True>
const>)
243 using size_type = detail::iter_size_t<iterator_t<D<True>>>;
244 return static_cast<size_type
>(derived().end() - derived().begin());
247 template(
bool True =
true)(
249 constexpr range_reference_t<D<True>>
front()
251 return *derived().begin();
254 template(
bool True =
true)(
256 constexpr range_reference_t<D<True>
const>
front()
const
258 return *derived().begin();
261 template(
bool True =
true)(
263 constexpr range_reference_t<D<True>>
back()
265 return *prev(derived().end());
268 template(
bool True =
true)(
271 constexpr range_reference_t<D<True>
const>
back()
const
273 return *prev(derived().end());
276 template(
bool True =
true)(
278 constexpr range_reference_t<D<True>> operator[](range_difference_t<D<True>> n)
280 return derived().begin()[n];
283 template(
bool True =
true)(
285 constexpr range_reference_t<D<True>
const>
286 operator[](range_difference_t<D<True>> n)
const
288 return derived().begin()[n];
292 template(
bool True =
true)(
294 constexpr std::add_pointer_t<range_reference_t<D<True>>> data()
296 return std::addressof(*ranges::begin(derived()));
299 template(
bool True =
true)(
301 constexpr std::add_pointer_t<range_reference_t<D<True>
const>> data() const
303 return std::addressof(*ranges::begin(derived()));
307 template(
bool True =
true)(
309 constexpr range_reference_t<D<True>>
at(range_difference_t<D<True>> n)
311 using size_type = range_size_t<Derived>;
314 throw std::out_of_range(
"view_interface::at");
316 return derived().begin()[n];
319 template(
bool True =
true)(
322 constexpr range_reference_t<D<True>
const>
at(range_difference_t<D<True>> n)
const
324 using size_type = range_size_t<Derived const>;
327 throw std::out_of_range(
"view_interface::at");
329 return derived().begin()[n];
333 template(
bool True =
true,
typename Slice = views::slice_fn)(
336 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &
338 return Slice{}(derived(), offs.from, offs.to);
341 template(
bool True =
true,
typename Slice = views::slice_fn)(
344 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs)
const &
346 return Slice{}(derived(), offs.from, offs.to);
349 template(
bool True =
true,
typename Slice = views::slice_fn)(
352 operator[](detail::slice_bounds<range_difference_t<D<True>>> offs) &&
354 return Slice{}(detail::move(derived()), offs.from, offs.to);
358 template(
bool True =
true,
typename Slice = views::slice_fn)(
361 operator[](detail::slice_bounds<range_difference_t<D<True>>,
362 detail::from_end_of_t<D<True>>> offs) &
364 return Slice{}(derived(), offs.from, offs.to);
367 template(
bool True =
true,
typename Slice = views::slice_fn)(
371 operator[](detail::slice_bounds<range_difference_t<D<True>>,
372 detail::from_end_of_t<D<True>>> offs)
const &
374 return Slice{}(derived(), offs.from, offs.to);
377 template(
bool True =
true,
typename Slice = views::slice_fn)(
380 operator[](detail::slice_bounds<range_difference_t<D<True>>,
381 detail::from_end_of_t<D<True>>> offs) &&
383 return Slice{}(detail::move(derived()), offs.from, offs.to);
387 template(
bool True =
true,
typename Slice = views::slice_fn)(
391 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
392 detail::from_end_of_t<D<True>>> offs) &
394 return Slice{}(derived(), offs.from, offs.to);
397 template(
bool True =
true,
typename Slice = views::slice_fn)(
402 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
403 detail::from_end_of_t<D<True>>> offs)
const &
405 return Slice{}(derived(), offs.from, offs.to);
408 template(
bool True =
true,
typename Slice = views::slice_fn)(
413 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>,
414 detail::from_end_of_t<D<True>>> offs) &&
416 return Slice{}(detail::move(derived()), offs.from, offs.to);
420 template(
bool True =
true,
typename Slice = views::slice_fn)(
423 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &
425 return Slice{}(derived(), offs.from, offs.to);
428 template(
bool True =
true,
typename Slice = views::slice_fn)(
431 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs)
const &
433 return Slice{}(derived(), offs.from, offs.to);
436 template(
bool True =
true,
typename Slice = views::slice_fn)(
439 operator[](detail::slice_bounds<range_difference_t<D<True>>, end_fn> offs) &&
441 return Slice{}(detail::move(derived()), offs.from, offs.to);
445 template(
bool True =
true,
typename Slice = views::slice_fn)(
450 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &
452 return Slice{}(derived(), offs.from, offs.to);
455 template(
bool True =
true,
typename Slice = views::slice_fn)(
461 detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs)
const &
463 return Slice{}(derived(), offs.from, offs.to);
466 template(
bool True =
true,
typename Slice = views::slice_fn)(
471 operator[](detail::slice_bounds<detail::from_end_of_t<D<True>>, end_fn> offs) &&
473 return Slice{}(detail::move(derived()), offs.from, offs.to);
476 #ifndef RANGES_V3_DISABLE_IO
478 template<
bool True = true>
479 friend auto operator<<(std::ostream & sout, Derived
const & rng)
480 -> CPP_broken_friend_ret(std::ostream &)(
481 requires True && input_range<D<True>
const>)
483 return detail::print_rng_(sout, rng);
486 template<
bool True = true>
487 friend auto operator<<(std::ostream & sout, Derived & rng)
488 -> CPP_broken_friend_ret(std::ostream &)(
489 requires True && (!range<D<True>
const>) &&
input_range<D<True>>)
491 return detail::print_rng_(sout, rng);
494 template<
bool True = true>
495 friend auto operator<<(std::ostream & sout, Derived && rng)
496 -> CPP_broken_friend_ret(std::ostream &)(
497 requires True && (!range<D<True>
const>) &&
input_range<D<True>>)
499 return detail::print_rng_(sout, rng);
505 template(
typename Derived)(
506 requires std::is_class<Derived>::value AND
507 same_as<Derived,
meta::_t<std::remove_cv<Derived>>>)
513 #include <range/v3/detail/epilogue.hpp>
CPP_concept contiguous_iterator
\concept contiguous_iterator
Definition: concepts.hpp:435
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 random_access_range
\concept random_access_range
Definition: concepts.hpp:140
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition: meta.hpp:163
typename T::type _t
Type alias for T::type.
Definition: meta.hpp:141
typename Fn::template invoke< Args... > invoke
Evaluate the invocable Fn with the arguments Args.
Definition: meta.hpp:541
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition: meta.hpp:1696
_t< detail::back_< L > > back
Return the last element in meta::list L.
Definition: meta.hpp:2103
at_c< L, N::type::value > at
Return the N th element in the meta::list L.
Definition: meta.hpp:1969
_t< detail::front_< L > > front
Return the first element in meta::list L.
Definition: meta.hpp:2070
bool_< 0==size< L >::type::value > empty
An Boolean integral constant wrapper around true if L is an empty type list; false,...
Definition: meta.hpp:2231
Definition: range_fwd.hpp:549
Definition: interface.hpp:129
constexpr Derived const & derived() const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: interface.hpp:140
constexpr CPP_member auto empty() const noexcept -> CPP_ret(bool)(requires(detail::has_fixed_size_< Cardinality >))
Test whether a range can be empty:
Definition: interface.hpp:154