14#ifndef RANGES_V3_RANGE_ACCESS_HPP
15#define RANGES_V3_RANGE_ACCESS_HPP
17#include <range/v3/detail/config.hpp>
20#include <initializer_list>
26#if __has_include(<span>) && !defined(RANGES_WORKAROUND_MSVC_UNUSABLE_SPAN)
29#if __has_include(<string_view>)
39#include <range/v3/utility/static_const.hpp>
41#include <range/v3/detail/prologue.hpp>
45#if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201603L
46 template<
class CharT,
class Traits>
47 RANGES_INLINE_VAR
constexpr bool
48 enable_borrowed_range<std::basic_string_view<CharT, Traits>> =
true;
53#if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L && \
54 (!defined(__GLIBCXX__) || defined(__cpp_lib_concepts))
55 template<
class T, std::
size_t N>
56 RANGES_INLINE_VAR
constexpr bool enable_borrowed_range<std::span<T, N>> =
true;
62 RANGES_INLINE_VAR
constexpr bool _borrowed_range =
63 enable_borrowed_range<uncvref_t<T>>;
66 RANGES_INLINE_VAR
constexpr bool _borrowed_range<T &> =
true;
69 T _decay_copy(T)
noexcept;
78 void begin(T &&) =
delete;
80#ifdef RANGES_WORKAROUND_MSVC_895622
85 void begin(std::initializer_list<T>) =
delete;
88 requires input_or_output_iterator<I>)
95 CPP_requires(has_member_begin_,
98 _begin_::is_iterator(t.begin())
103 CPP_concept has_member_begin =
104 CPP_requires_ref(_begin_::has_member_begin_, T);
109 CPP_requires(has_non_member_begin_,
112 _begin_::is_iterator(begin(t))
117 CPP_concept has_non_member_begin =
118 CPP_requires_ref(_begin_::has_non_member_begin_, T);
124 struct _member_result_
127 using invoke =
decltype(detail::_decay_copy(declval(R &).begin()));
129 struct _non_member_result_
132 using invoke =
decltype(detail::_decay_copy(begin(declval(R &))));
141 _non_member_result_>,
145 template<
typename R, std::
size_t N>
146 void operator()(R(&&)[N])
const =
delete;
148 template<
typename R, std::
size_t N>
149 constexpr R * operator()(R (&array)[N])
const noexcept
154 template(
typename R)(
155 requires detail::_borrowed_range<R> AND has_member_begin<R>)
156 constexpr _result_t<R> operator()(R && r)
const
157 noexcept(
noexcept(r.begin()))
162 template(
typename R)(
163 requires detail::_borrowed_range<R> AND (!has_member_begin<R>) AND
164 has_non_member_begin<R>)
165 constexpr _result_t<R>
operator()(R && r)
const
166 noexcept(
noexcept(begin(r)))
173 using _t =
decltype(fn{}(declval(R &&)));
182 RANGES_DEFINE_CPO(_begin_::fn, begin)
190 void end(T &&) =
delete;
192#ifdef RANGES_WORKAROUND_MSVC_895622
197 void end(std::initializer_list<T>) =
delete;
199 template(
typename I,
typename S)(
200 requires sentinel_for<S, I>)
201 void _is_sentinel(S, I);
207 CPP_requires(has_member_end_,
210 _end_::_is_sentinel(t.end(), ranges::begin(t))
215 CPP_concept has_member_end =
216 CPP_requires_ref(_end_::has_member_end_, T);
221 CPP_requires(has_non_member_end_,
224 _end_::_is_sentinel(end(t), ranges::begin(t))
229 CPP_concept has_non_member_end =
230 CPP_requires_ref(_end_::has_non_member_end_, T);
236 struct _member_result_
239 using invoke =
decltype(detail::_decay_copy(declval(R &).end()));
241 struct _non_member_result_
244 using invoke =
decltype(detail::_decay_copy(end(declval(R &))));
253 _non_member_result_>,
256 template<
typename Int>
259 std::make_signed<Int>,
263 template<
typename R, std::
size_t N>
264 void operator()(R(&&)[N])
const =
delete;
266 template<
typename R, std::
size_t N>
267 constexpr R * operator()(R (&array)[N])
const noexcept
272 template(
typename R)(
273 requires detail::_borrowed_range<R> AND has_member_end<R>)
274 constexpr _result_t<R> operator()(R && r)
const
275 noexcept(
noexcept(r.end()))
280 template(
typename R)(
281 requires detail::_borrowed_range<R> AND (!has_member_end<R>) AND
282 has_non_member_end<R>)
283 constexpr _result_t<R>
operator()(R && r)
const
284 noexcept(
noexcept(end(r)))
289 template(
typename Int)(
290 requires detail::integer_like_<Int>)
292 -> detail::from_end_<iter_diff_t<Int>>
294 using SInt = iter_diff_t<Int>;
295 RANGES_EXPECT(0 <= dist);
296 RANGES_EXPECT(dist <=
297 static_cast<Int
>((std::numeric_limits<SInt>::max)()));
298 return detail::from_end_<SInt>{-
static_cast<SInt
>(dist)};
303 using _t =
decltype(fn{}(declval(R &&)));
313 RANGES_DEFINE_CPO(_end_::fn, end)
320 template<
typename T, std::
size_t N>
321 void operator()(T(&&)[N])
const =
delete;
324 constexpr _begin_::_t<detail::as_const_t<R>> operator()(R && r)
const
325 noexcept(
noexcept(ranges::begin(detail::as_const(r))))
327 return ranges::begin(detail::as_const(r));
337 RANGES_INLINE_VARIABLE(_cbegin_::fn, cbegin)
344 template<
typename T, std::
size_t N>
345 void operator()(T(&&)[N])
const =
delete;
348 constexpr _end_::_t<detail::as_const_t<R>> operator()(R && r)
const
349 noexcept(
noexcept(ranges::end(detail::as_const(r))))
351 return ranges::end(detail::as_const(r));
361 RANGES_INLINE_VARIABLE(_cend_::fn, cend)
367 void rbegin(R &&) =
delete;
371 void rbegin(std::initializer_list<T>) =
delete;
372 template<
typename T, std::
size_t N>
373 void rbegin(T (&)[N]) =
delete;
379 CPP_requires(has_member_rbegin_,
382 _begin_::is_iterator(t.rbegin())
387 CPP_concept has_member_rbegin =
388 CPP_requires_ref(_rbegin_::has_member_rbegin_, T);
393 CPP_requires(has_non_member_rbegin_,
396 _begin_::is_iterator(rbegin(t))
401 CPP_concept has_non_member_rbegin =
402 CPP_requires_ref(_rbegin_::has_non_member_rbegin_, T);
405 void _same_type(I, I);
410 CPP_requires(can_reverse_end_,
415 ranges::make_reverse_iterator(ranges::end(t)),
416 _rbegin_::_same_type(ranges::begin(t), ranges::end(t))
421 CPP_concept can_reverse_end =
422 CPP_requires_ref(_rbegin_::can_reverse_end_, T);
428 struct _member_result_
431 using invoke =
decltype(detail::_decay_copy(declval(R &).rbegin()));
433 struct _non_member_result_
436 using invoke =
decltype(detail::_decay_copy(rbegin(declval(R &))));
438 struct _reverse_result_
442 decltype(ranges::make_reverse_iterator(ranges::end(declval(R &))));
444 struct _other_result_
450 has_non_member_rbegin<R>,
460 has_member_rbegin<R>,
466 template(
typename R)(
467 requires detail::_borrowed_range<R> AND has_member_rbegin<R>)
468 constexpr auto operator()(R && r)
const
469 noexcept(
noexcept(r.rbegin()))
474 template(
typename R)(
475 requires detail::_borrowed_range<R> AND (!has_member_rbegin<R>) AND
476 has_non_member_rbegin<R>)
477 constexpr auto operator()(R && r)
const
478 noexcept(
noexcept(rbegin(r)))
483 template(
typename R)(
484 requires detail::_borrowed_range<R> AND (!has_member_rbegin<R>) AND
485 (!has_non_member_rbegin<R>) AND can_reverse_end<R>)
486 constexpr auto operator()(R && r)
const
487 noexcept(
noexcept(ranges::make_reverse_iterator(ranges::end(r))))
489 return ranges::make_reverse_iterator(ranges::end(r));
494 using _t =
decltype(fn{}(declval(R &&)));
505 RANGES_DEFINE_CPO(_rbegin_::fn, rbegin)
511 void rend(R &&) =
delete;
515 void rend(std::initializer_list<T>) =
delete;
516 template<
typename T, std::
size_t N>
517 void rend(T (&)[N]) =
delete;
523 CPP_requires(has_member_rend_,
526 _end_::_is_sentinel(t.rend(), ranges::rbegin(t))
531 CPP_concept has_member_rend =
532 CPP_requires_ref(_rend_::has_member_rend_, T);
537 CPP_requires(has_non_member_rend_,
540 _end_::_is_sentinel(rend(t), ranges::rbegin(t))
545 CPP_concept has_non_member_rend =
546 CPP_requires_ref(_rend_::has_non_member_rend_, T);
551 CPP_requires(can_reverse_begin_,
556 ranges::make_reverse_iterator(ranges::begin(t)),
557 _rbegin_::_same_type(ranges::begin(t), ranges::end(t))
562 CPP_concept can_reverse_begin =
563 CPP_requires_ref(_rend_::can_reverse_begin_, T);
569 struct _member_result_
572 using invoke =
decltype(detail::_decay_copy(declval(R &).rend()));
574 struct _non_member_result_
577 using invoke =
decltype(detail::_decay_copy(rend(declval(R &))));
579 struct _reverse_result_
583 decltype(ranges::make_reverse_iterator(ranges::begin(declval(R &))));
585 struct _other_result_
591 has_non_member_rend<R>,
607 template(
typename R)(
608 requires detail::_borrowed_range<R> AND has_member_rend<R>)
609 constexpr auto operator()(R && r)
const
610 noexcept(
noexcept(r.rend()))
615 template(
typename R)(
616 requires detail::_borrowed_range<R> AND (!has_member_rend<R>) AND
617 has_non_member_rend<R>)
618 constexpr auto operator()(R && r)
const
619 noexcept(
noexcept(rend(r)))
624 template(
typename R)(
625 requires detail::_borrowed_range<R> AND (!has_member_rend<R>) AND
626 (!has_non_member_rend<R>) AND can_reverse_begin<R>)
627 constexpr auto operator()(R && r)
const
628 noexcept(
noexcept(ranges::make_reverse_iterator(ranges::begin(r))))
630 return ranges::make_reverse_iterator(ranges::begin(r));
635 using _t =
decltype(fn{}(declval(R &&)));
647 RANGES_DEFINE_CPO(_rend_::fn, rend)
654 template<
typename T, std::
size_t N>
655 void operator()(T(&&)[N])
const =
delete;
658 constexpr _rbegin_::_t<detail::as_const_t<R>> operator()(R && r)
const
659 noexcept(
noexcept(ranges::rbegin(detail::as_const(r))))
661 return ranges::rbegin(detail::as_const(r));
671 RANGES_INLINE_VARIABLE(_crbegin_::fn, crbegin)
678 template<
typename T, std::
size_t N>
679 void operator()(T(&&)[N])
const =
delete;
682 constexpr _rend_::_t<detail::as_const_t<R>> operator()(R && r)
const
683 noexcept(
noexcept(ranges::rend(detail::as_const(r))))
685 return ranges::rend(detail::as_const(r));
695 RANGES_INLINE_VARIABLE(_crend_::fn, crend)
697 template<
typename Rng>
700 template<
typename Rng>
701 using sentinel_t =
decltype(end(declval(Rng &)));
706 using ranges::cbegin;
708 using ranges::crbegin;
711 using ranges::rbegin;
715 using ranges::sentinel_t;
717 using ranges::enable_borrowed_range;
721#include <range/v3/detail/epilogue.hpp>
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
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
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
@ array
array (ordered collection of values)
Point operator-(const Point &a, const Point &b)
Subtract two points_ component-wise.
Definition shapes.h:244