31#define _RANGES_UTIL_H 1
33#if __cplusplus > 201703L
37#ifdef __cpp_lib_ranges
38namespace std _GLIBCXX_VISIBILITY(default)
40_GLIBCXX_BEGIN_NAMESPACE_VERSION
47 template<
typename _Range>
48 concept __simple_view = view<_Range> && range<const _Range>
49 && same_as<iterator_t<_Range>, iterator_t<const _Range>>
50 && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
52 template<
typename _It>
53 concept __has_arrow = input_iterator<_It>
54 && (is_pointer_v<_It> ||
requires(_It __it) { __it.operator->(); });
56 template<
typename _Tp,
typename _Up>
57 concept __different_from
58 = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
62 template<
typename _Derived>
63 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
67 constexpr _Derived& _M_derived()
noexcept
71 return static_cast<_Derived&
>(*this);
74 constexpr const _Derived& _M_derived()
const noexcept
78 return static_cast<const _Derived&
>(*this);
82 _S_bool(
bool)
noexcept;
84 template<
typename _Tp>
87 noexcept(
noexcept(_S_bool(ranges::begin(__t) == ranges::end(__t))))
88 {
return ranges::begin(__t) == ranges::end(__t); }
90 template<
typename _Tp>
93 noexcept(
noexcept(ranges::end(__t) - ranges::begin(__t)))
94 {
return ranges::end(__t) - ranges::begin(__t); }
99 noexcept(
noexcept(_S_empty(_M_derived())))
101 {
return _S_empty(_M_derived()); }
105 noexcept(
noexcept(_S_empty(_M_derived())))
107 {
return _S_empty(_M_derived()); }
110 operator bool()
noexcept(
noexcept(ranges::empty(_M_derived())))
111 requires requires { ranges::empty(_M_derived()); }
112 {
return !ranges::empty(_M_derived()); }
115 operator bool()
const noexcept(
noexcept(ranges::empty(_M_derived())))
116 requires requires { ranges::empty(_M_derived()); }
117 {
return !ranges::empty(_M_derived()); }
120 data()
noexcept(
noexcept(ranges::begin(_M_derived())))
121 requires contiguous_iterator<iterator_t<_Derived>>
125 data()
const noexcept(
noexcept(ranges::begin(_M_derived())))
127 && contiguous_iterator<iterator_t<const _Derived>>
131 size()
noexcept(
noexcept(_S_size(_M_derived())))
133 && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
134 {
return _S_size(_M_derived()); }
137 size()
const noexcept(
noexcept(_S_size(_M_derived())))
139 && sized_sentinel_for<sentinel_t<const _Derived>,
140 iterator_t<const _Derived>>
141 {
return _S_size(_M_derived()); }
143 constexpr decltype(
auto)
146 __glibcxx_assert(!empty());
147 return *ranges::begin(_M_derived());
150 constexpr decltype(
auto)
153 __glibcxx_assert(!empty());
154 return *ranges::begin(_M_derived());
157 constexpr decltype(
auto)
161 __glibcxx_assert(!empty());
162 return *ranges::prev(ranges::end(_M_derived()));
165 constexpr decltype(
auto)
170 __glibcxx_assert(!empty());
171 return *ranges::prev(ranges::end(_M_derived()));
174 template<random_access_range _Range = _Derived>
175 constexpr decltype(
auto)
176 operator[](range_difference_t<_Range> __n)
177 {
return ranges::begin(_M_derived())[__n]; }
179 template<random_access_range _Range = const _Derived>
180 constexpr decltype(
auto)
181 operator[](range_difference_t<_Range> __n)
const
182 {
return ranges::begin(_M_derived())[__n]; }
187 template<
typename _From,
typename _To>
188 concept __uses_nonqualification_pointer_conversion
189 = is_pointer_v<_From> && is_pointer_v<_To>
193 template<
typename _From,
typename _To>
195 && !__uses_nonqualification_pointer_conversion<decay_t<_From>,
198 template<
typename _Tp>
200 = !is_reference_v<_Tp> &&
requires(_Tp __t)
204 typename tuple_element_t<0, remove_const_t<_Tp>>;
205 typename tuple_element_t<1, remove_const_t<_Tp>>;
207 { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
210 template<
typename _Tp,
typename _Up,
typename _Vp>
211 concept __pair_like_convertible_from
212 = !range<_Tp> && __pair_like<_Tp>
213 && constructible_from<_Tp, _Up, _Vp>
214 && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
215 && convertible_to<_Vp, tuple_element_t<1, _Tp>>;
219 namespace views {
struct _Drop; }
221 enum class subrange_kind :
bool { unsized, sized };
224 template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
225 subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
226 ? subrange_kind::sized : subrange_kind::unsized>
227 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
231 static constexpr bool _S_store_size
232 = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
234 friend struct views::_Drop;
236 _It _M_begin = _It();
237 [[no_unique_address]] _Sent _M_end = _Sent();
240 = __detail::__make_unsigned_like_t<iter_difference_t<_It>>;
242 template<
typename,
bool = _S_store_size>
246 template<
typename _Tp>
247 struct _Size<_Tp, true>
250 [[no_unique_address]] _Size<__size_type> _M_size = {};
256 subrange(__detail::__convertible_to_non_slicing<_It>
auto __i, _Sent __s)
257 noexcept(is_nothrow_constructible_v<_It,
decltype(__i)>
258 && is_nothrow_constructible_v<_Sent, _Sent&>)
259 requires (!_S_store_size)
264 subrange(__detail::__convertible_to_non_slicing<_It>
auto __i, _Sent __s,
266 noexcept(is_nothrow_constructible_v<_It,
decltype(__i)>
267 && is_nothrow_constructible_v<_Sent, _Sent&>)
268 requires (_Kind == subrange_kind::sized)
271 if constexpr (_S_store_size)
272 _M_size._M_size = __n;
275 template<__detail::__different_from<subrange> _Rng>
277 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
281 noexcept(
noexcept(
subrange(__r, ranges::size(__r))))
286 template<__detail::__different_from<subrange> _Rng>
288 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
292 noexcept(
noexcept(
subrange(ranges::begin(__r), ranges::end(__r))))
293 requires (!_S_store_size)
294 :
subrange(ranges::begin(__r), ranges::end(__r))
297 template<borrowed_range _Rng>
298 requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
301 subrange(_Rng&& __r, __size_type __n)
302 noexcept(
noexcept(
subrange(ranges::begin(__r), ranges::end(__r), __n)))
303 requires (_Kind == subrange_kind::sized)
304 :
subrange{ranges::begin(__r), ranges::end(__r), __n}
307 template<__detail::__different_from<subrange> _PairLike>
308 requires __detail::__pair_like_convertible_from<_PairLike,
const _It&,
311 operator _PairLike()
const
312 {
return _PairLike(_M_begin, _M_end); }
315 begin()
const requires copyable<_It>
318 [[nodiscard]]
constexpr _It
319 begin()
requires (!copyable<_It>)
322 constexpr _Sent
end()
const {
return _M_end; }
324 constexpr bool empty()
const {
return _M_begin == _M_end; }
326 constexpr __size_type
327 size()
const requires (_Kind == subrange_kind::sized)
329 if constexpr (_S_store_size)
330 return _M_size._M_size;
332 return __detail::__to_unsigned_like(_M_end - _M_begin);
336 next(iter_difference_t<_It> __n = 1)
const &
337 requires forward_iterator<_It>
345 next(iter_difference_t<_It> __n = 1) &&
352 prev(iter_difference_t<_It> __n = 1)
const
353 requires bidirectional_iterator<_It>
361 advance(iter_difference_t<_It> __n)
365 if constexpr (bidirectional_iterator<_It>)
368 ranges::advance(_M_begin, __n);
369 if constexpr (_S_store_size)
370 _M_size._M_size += __detail::__to_unsigned_like(-__n);
374 __glibcxx_assert(__n >= 0);
375 auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
376 if constexpr (_S_store_size)
377 _M_size._M_size -= __detail::__to_unsigned_like(__d);
382 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
385 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
387 __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
390 template<borrowed_range _Rng>
394 || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
395 ? subrange_kind::sized : subrange_kind::unsized>;
397 template<borrowed_range _Rng>
399 __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
402 template<
size_t _Num,
class _It,
class _Sent, subrange_kind _Kind>
407 if constexpr (_Num == 0)
413 template<
size_t _Num,
class _It,
class _Sent, subrange_kind _Kind>
416 get(subrange<_It, _Sent, _Kind>&& __r)
418 if constexpr (_Num == 0)
424 template<
typename _It,
typename _Sent, subrange_kind _Kind>
425 inline constexpr bool
426 enable_borrowed_range<subrange<_It, _Sent, _Kind>> =
true;
428 template<range _Range>
429 using borrowed_subrange_t = __conditional_t<borrowed_range<_Range>,
430 subrange<iterator_t<_Range>>,
440 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Tp,
441 typename _Proj =
identity>
442 requires indirect_binary_predicate<ranges::equal_to,
443 projected<_Iter, _Proj>,
const _Tp*>
445 operator()(_Iter __first, _Sent __last,
446 const _Tp& __value, _Proj __proj = {})
const
448 while (__first != __last
454 template<input_range _Range,
typename _Tp,
typename _Proj =
identity>
455 requires indirect_binary_predicate<ranges::equal_to,
456 projected<iterator_t<_Range>, _Proj>,
458 constexpr borrowed_iterator_t<_Range>
459 operator()(_Range&& __r,
const _Tp& __value, _Proj __proj = {})
const
461 return (*
this)(ranges::begin(__r), ranges::end(__r),
466 inline constexpr __find_fn find{};
470 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
471 typename _Proj =
identity,
472 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
474 operator()(_Iter __first, _Sent __last,
475 _Pred __pred, _Proj __proj = {})
const
477 while (__first != __last
483 template<input_range _Range,
typename _Proj = identity,
484 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
486 constexpr borrowed_iterator_t<_Range>
487 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {})
const
489 return (*
this)(ranges::begin(__r), ranges::end(__r),
494 inline constexpr __find_if_fn find_if{};
496 struct __find_if_not_fn
498 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
499 typename _Proj =
identity,
500 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
502 operator()(_Iter __first, _Sent __last,
503 _Pred __pred, _Proj __proj = {})
const
505 while (__first != __last
511 template<input_range _Range,
typename _Proj = identity,
512 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
514 constexpr borrowed_iterator_t<_Range>
515 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {})
const
517 return (*
this)(ranges::begin(__r), ranges::end(__r),
522 inline constexpr __find_if_not_fn find_if_not{};
524 template<
typename _Iter1,
typename _Iter2>
527 [[no_unique_address]] _Iter1 in1;
528 [[no_unique_address]] _Iter2 in2;
530 template<
typename _IIter1,
typename _IIter2>
531 requires convertible_to<const _Iter1&, _IIter1>
532 && convertible_to<const _Iter2&, _IIter2>
534 operator in_in_result<_IIter1, _IIter2>() const &
535 {
return {in1, in2}; }
537 template<
typename _IIter1,
typename _IIter2>
538 requires convertible_to<_Iter1, _IIter1>
539 && convertible_to<_Iter2, _IIter2>
541 operator in_in_result<_IIter1, _IIter2>() &&
545 template<
typename _Iter1,
typename _Iter2>
546 using mismatch_result = in_in_result<_Iter1, _Iter2>;
550 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
551 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
552 typename _Pred = ranges::equal_to,
553 typename _Proj1 =
identity,
typename _Proj2 =
identity>
554 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
555 constexpr mismatch_result<_Iter1, _Iter2>
556 operator()(_Iter1 __first1, _Sent1 __last1,
557 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
558 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
560 while (__first1 != __last1 && __first2 != __last2
571 template<input_range _Range1, input_range _Range2,
572 typename _Pred = ranges::equal_to,
573 typename _Proj1 = identity,
typename _Proj2 = identity>
574 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
575 _Pred, _Proj1, _Proj2>
576 constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
577 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
578 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
580 return (*
this)(ranges::begin(__r1), ranges::end(__r1),
581 ranges::begin(__r2), ranges::end(__r2),
587 inline constexpr __mismatch_fn mismatch{};
591 template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
592 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
593 typename _Pred = ranges::equal_to,
594 typename _Proj1 =
identity,
typename _Proj2 =
identity>
595 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
596 constexpr subrange<_Iter1>
597 operator()(_Iter1 __first1, _Sent1 __last1,
598 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
599 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
601 if (__first1 == __last1 || __first2 == __last2)
602 return {__first1, __first1};
608 if (__first1 == __last1)
609 return {__first1, __first1};
616 auto __cur1 = __first1;
617 auto __cur2 = __first2;
620 if (++__cur2 == __last2)
621 return {__first1, ++__cur1};
622 if (++__cur1 == __last1)
623 return {__cur1, __cur1};
635 template<forward_range _Range1, forward_range _Range2,
636 typename _Pred = ranges::equal_to,
637 typename _Proj1 = identity,
typename _Proj2 = identity>
638 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
639 _Pred, _Proj1, _Proj2>
640 constexpr borrowed_subrange_t<_Range1>
641 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
642 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
644 return (*
this)(ranges::begin(__r1), ranges::end(__r1),
645 ranges::begin(__r2), ranges::end(__r2),
651 inline constexpr __search_fn search{};
656 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
657 struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
658 : integral_constant<size_t, 2>
661 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
662 struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
663 {
using type = _Iter; };
665 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
666 struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
667 {
using type = _Sent; };
669 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
670 struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
671 {
using type = _Iter; };
673 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
674 struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
675 {
using type = _Sent; };
677_GLIBCXX_END_NAMESPACE_VERSION
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
typename remove_pointer< _Tp >::type remove_pointer_t
Alias template for remove_pointer.
typename decay< _Tp >::type decay_t
Alias template for decay.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
ISO C++ entities toplevel namespace is std.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
The ranges::view_interface class template.
The ranges::subrange class template.
Finds the size of a given tuple type.
[concept.derived], concept derived_from
[concept.convertible], concept convertible_to
[concept.defaultinitializable], concept default_initializable
[range.range] The range concept.
[range.range] The borrowed_range concept.
[range.sized] The sized_range concept.
[range.view] The ranges::view concept.
A range for which ranges::begin returns a forward iterator.
A range for which ranges::begin returns a bidirectional iterator.
A range for which ranges::begin and ranges::end return the same type.