31#define _RANGES_UTIL_H 1
33#if __cplusplus > 201703L
36#ifdef __cpp_lib_ranges
37namespace std _GLIBCXX_VISIBILITY(default)
39_GLIBCXX_BEGIN_NAMESPACE_VERSION
46 template<
typename _Range>
47 concept __simple_view = view<_Range> && range<const _Range>
48 && same_as<iterator_t<_Range>, iterator_t<const _Range>>
49 && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
51 template<
typename _It>
52 concept __has_arrow = input_iterator<_It>
53 && (is_pointer_v<_It> ||
requires(_It __it) { __it.operator->(); });
55 template<
typename _Tp,
typename _Up>
57 = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
61 template<
typename _Derived>
62 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
63 class view_interface :
public view_base
66 constexpr _Derived& _M_derived() noexcept
68 static_assert(derived_from<_Derived, view_interface<_Derived>>);
69 static_assert(view<_Derived>);
70 return static_cast<_Derived&
>(*this);
73 constexpr const _Derived& _M_derived() const noexcept
75 static_assert(derived_from<_Derived, view_interface<_Derived>>);
76 static_assert(view<_Derived>);
77 return static_cast<const _Derived&
>(*this);
82 empty()
requires forward_range<_Derived>
83 {
return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
86 empty() const requires forward_range<const _Derived>
87 {
return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
90 operator bool()
requires requires { ranges::empty(_M_derived()); }
91 {
return !ranges::empty(_M_derived()); }
94 operator bool() const requires requires { ranges::empty(_M_derived()); }
95 {
return !ranges::empty(_M_derived()); }
98 data()
requires contiguous_iterator<iterator_t<_Derived>>
99 {
return to_address(ranges::begin(_M_derived())); }
103 requires range<const _Derived>
104 && contiguous_iterator<iterator_t<const _Derived>>
105 {
return to_address(ranges::begin(_M_derived())); }
109 requires forward_range<_Derived>
110 && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
111 {
return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
115 requires forward_range<const _Derived>
116 && sized_sentinel_for<sentinel_t<const _Derived>,
117 iterator_t<const _Derived>>
118 {
return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
120 constexpr decltype(
auto)
121 front()
requires forward_range<_Derived>
123 __glibcxx_assert(!
empty());
124 return *ranges::begin(_M_derived());
127 constexpr decltype(
auto)
128 front()
const requires forward_range<const _Derived>
130 __glibcxx_assert(!
empty());
131 return *ranges::begin(_M_derived());
134 constexpr decltype(
auto)
136 requires bidirectional_range<_Derived> && common_range<_Derived>
138 __glibcxx_assert(!
empty());
139 return *ranges::prev(ranges::end(_M_derived()));
142 constexpr decltype(
auto)
144 requires bidirectional_range<const _Derived>
145 && common_range<const _Derived>
147 __glibcxx_assert(!
empty());
148 return *ranges::prev(ranges::end(_M_derived()));
151 template<random_access_range _Range = _Derived>
152 constexpr decltype(
auto)
153 operator[](range_difference_t<_Range> __n)
154 {
return ranges::begin(_M_derived())[__n]; }
156 template<random_access_range _Range = const _Derived>
157 constexpr decltype(
auto)
158 operator[](range_difference_t<_Range> __n)
const
159 {
return ranges::begin(_M_derived())[__n]; }
164 template<
typename _From,
typename _To>
165 concept __uses_nonqualification_pointer_conversion
166 = is_pointer_v<_From> && is_pointer_v<_To>
167 && !convertible_to<remove_pointer_t<_From>(*)[],
168 remove_pointer_t<_To>(*)[]>;
170 template<
typename _From,
typename _To>
171 concept __convertible_to_non_slicing = convertible_to<_From, _To>
172 && !__uses_nonqualification_pointer_conversion<decay_t<_From>,
175 template<
typename _Tp>
177 = !is_reference_v<_Tp> &&
requires(_Tp __t)
179 typename tuple_size<_Tp>::type;
180 requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
181 typename tuple_element_t<0, remove_const_t<_Tp>>;
182 typename tuple_element_t<1, remove_const_t<_Tp>>;
183 { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
184 { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
187 template<
typename _Tp,
typename _Up,
typename _Vp>
188 concept __pair_like_convertible_from
189 = !range<_Tp> && __pair_like<_Tp>
190 && constructible_from<_Tp, _Up, _Vp>
191 && __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
192 && convertible_to<_Vp, tuple_element_t<1, _Tp>>;
196 enum class subrange_kind :
bool { unsized, sized };
199 template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
200 subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
201 ? subrange_kind::sized : subrange_kind::unsized>
202 requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
203 class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
207 static const bool _S_store_size
208 = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
210 _It _M_begin = _It();
211 [[no_unique_address]] _Sent _M_end = _Sent();
214 = __detail::__make_unsigned_like_t<iter_difference_t<_It>>;
216 template<
typename,
bool = _S_store_size>
220 template<
typename _Tp>
221 struct _Size<_Tp, true>
224 [[no_unique_address]] _Size<__size_type> _M_size = {};
227 subrange()
requires default_initializable<_It> = default;
230 subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
231 requires (!_S_store_size)
232 : _M_begin(
std::move(__i)), _M_end(__s)
236 subrange(__detail::__convertible_to_non_slicing<_It>
auto __i, _Sent __s,
238 requires (_Kind == subrange_kind::sized)
239 : _M_begin(
std::
move(__i)), _M_end(__s)
241 if constexpr (_S_store_size)
242 _M_size._M_size = __n;
245 template<__detail::__not_same_as<subrange> _Rng>
246 requires borrowed_range<_Rng>
247 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
248 && convertible_to<sentinel_t<_Rng>, _Sent>
250 subrange(_Rng&& __r)
requires _S_store_size && sized_range<_Rng>
251 : subrange(__r, ranges::size(__r))
254 template<__detail::__not_same_as<subrange> _Rng>
255 requires borrowed_range<_Rng>
256 && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
257 && convertible_to<sentinel_t<_Rng>, _Sent>
259 subrange(_Rng&& __r)
requires (!_S_store_size)
260 : subrange(ranges::
begin(__r), ranges::
end(__r))
263 template<borrowed_range _Rng>
264 requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
265 && convertible_to<sentinel_t<_Rng>, _Sent>
267 subrange(_Rng&& __r, __size_type __n)
268 requires (_Kind == subrange_kind::sized)
269 : subrange{ranges::
begin(__r), ranges::
end(__r), __n}
272 template<__detail::__not_same_as<subrange> _PairLike>
273 requires __detail::__pair_like_convertible_from<_PairLike,
const _It&,
276 operator _PairLike()
const
277 {
return _PairLike(_M_begin, _M_end); }
280 begin() const requires copyable<_It>
283 [[nodiscard]]
constexpr _It
284 begin()
requires (!copyable<_It>)
287 constexpr _Sent
end()
const {
return _M_end; }
289 constexpr bool empty()
const {
return _M_begin == _M_end; }
291 constexpr __size_type
292 size() const requires (_Kind == subrange_kind::sized)
294 if constexpr (_S_store_size)
295 return _M_size._M_size;
297 return __detail::__to_unsigned_like(_M_end - _M_begin);
300 [[nodiscard]]
constexpr subrange
301 next(iter_difference_t<_It> __n = 1) const &
302 requires forward_iterator<_It>
309 [[nodiscard]]
constexpr subrange
310 next(iter_difference_t<_It> __n = 1) &&
316 [[nodiscard]]
constexpr subrange
317 prev(iter_difference_t<_It> __n = 1) const
318 requires bidirectional_iterator<_It>
326 advance(iter_difference_t<_It> __n)
330 if constexpr (bidirectional_iterator<_It>)
333 ranges::advance(_M_begin, __n);
334 if constexpr (_S_store_size)
335 _M_size._M_size += __detail::__to_unsigned_like(-__n);
339 __glibcxx_assert(__n >= 0);
340 auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
341 if constexpr (_S_store_size)
342 _M_size._M_size -= __detail::__to_unsigned_like(__d);
347 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
348 subrange(_It, _Sent) -> subrange<_It, _Sent>;
350 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
352 __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
353 -> subrange<_It, _Sent, subrange_kind::sized>;
355 template<borrowed_range _Rng>
357 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
359 || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
360 ? subrange_kind::sized : subrange_kind::unsized>;
362 template<borrowed_range _Rng>
364 __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
365 -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
367 template<
size_t _Num,
class _It,
class _Sent, subrange_kind _Kind>
370 get(
const subrange<_It, _Sent, _Kind>& __r)
372 if constexpr (_Num == 0)
378 template<
size_t _Num,
class _It,
class _Sent, subrange_kind _Kind>
381 get(subrange<_It, _Sent, _Kind>&& __r)
383 if constexpr (_Num == 0)
389 template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
391 inline constexpr bool
392 enable_borrowed_range<subrange<_It, _Sent, _Kind>> =
true;
394 template<range _Range>
395 using borrowed_subrange_t = conditional_t<borrowed_range<_Range>,
396 subrange<iterator_t<_Range>>,
406 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
typename _Tp,
407 typename _Proj =
identity>
408 requires indirect_binary_predicate<ranges::equal_to,
409 projected<_Iter, _Proj>,
const _Tp*>
411 operator()(_Iter __first, _Sent __last,
412 const _Tp& __value, _Proj __proj = {})
const
414 while (__first != __last
420 template<input_range _Range,
typename _Tp,
typename _Proj =
identity>
421 requires indirect_binary_predicate<ranges::equal_to,
422 projected<iterator_t<_Range>, _Proj>,
424 constexpr borrowed_iterator_t<_Range>
425 operator()(_Range&& __r,
const _Tp& __value, _Proj __proj = {})
const
427 return (*
this)(ranges::begin(__r), ranges::end(__r),
432 inline constexpr __find_fn find{};
436 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
437 typename _Proj =
identity,
438 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
440 operator()(_Iter __first, _Sent __last,
441 _Pred __pred, _Proj __proj = {})
const
443 while (__first != __last
449 template<input_range _Range,
typename _Proj = identity,
450 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
452 constexpr borrowed_iterator_t<_Range>
453 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {})
const
455 return (*
this)(ranges::begin(__r), ranges::end(__r),
460 inline constexpr __find_if_fn find_if{};
462 struct __find_if_not_fn
464 template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
465 typename _Proj =
identity,
466 indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
468 operator()(_Iter __first, _Sent __last,
469 _Pred __pred, _Proj __proj = {})
const
471 while (__first != __last
477 template<input_range _Range,
typename _Proj = identity,
478 indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
480 constexpr borrowed_iterator_t<_Range>
481 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {})
const
483 return (*
this)(ranges::begin(__r), ranges::end(__r),
488 inline constexpr __find_if_not_fn find_if_not{};
490 template<
typename _Iter1,
typename _Iter2>
493 [[no_unique_address]] _Iter1 in1;
494 [[no_unique_address]] _Iter2 in2;
496 template<
typename _IIter1,
typename _IIter2>
497 requires convertible_to<const _Iter1&, _IIter1>
498 && convertible_to<const _Iter2&, _IIter2>
500 operator in_in_result<_IIter1, _IIter2>() const &
501 {
return {in1, in2}; }
503 template<
typename _IIter1,
typename _IIter2>
504 requires convertible_to<_Iter1, _IIter1>
505 && convertible_to<_Iter2, _IIter2>
507 operator in_in_result<_IIter1, _IIter2>() &&
511 template<
typename _Iter1,
typename _Iter2>
512 using mismatch_result = in_in_result<_Iter1, _Iter2>;
516 template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
517 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
518 typename _Pred = ranges::equal_to,
519 typename _Proj1 =
identity,
typename _Proj2 =
identity>
520 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
521 constexpr mismatch_result<_Iter1, _Iter2>
522 operator()(_Iter1 __first1, _Sent1 __last1,
523 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
524 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
526 while (__first1 != __last1 && __first2 != __last2
537 template<input_range _Range1, input_range _Range2,
538 typename _Pred = ranges::equal_to,
539 typename _Proj1 = identity,
typename _Proj2 = identity>
540 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
541 _Pred, _Proj1, _Proj2>
542 constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
543 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
544 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
546 return (*
this)(ranges::begin(__r1), ranges::end(__r1),
547 ranges::begin(__r2), ranges::end(__r2),
553 inline constexpr __mismatch_fn mismatch{};
557 template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
558 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
559 typename _Pred = ranges::equal_to,
560 typename _Proj1 =
identity,
typename _Proj2 =
identity>
561 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
562 constexpr subrange<_Iter1>
563 operator()(_Iter1 __first1, _Sent1 __last1,
564 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
565 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
567 if (__first1 == __last1 || __first2 == __last2)
568 return {__first1, __first1};
574 if (__first1 == __last1)
575 return {__first1, __first1};
582 auto __cur1 = __first1;
583 auto __cur2 = __first2;
586 if (++__cur2 == __last2)
587 return {__first1, ++__cur1};
588 if (++__cur1 == __last1)
589 return {__cur1, __cur1};
601 template<forward_range _Range1, forward_range _Range2,
602 typename _Pred = ranges::equal_to,
603 typename _Proj1 = identity,
typename _Proj2 = identity>
604 requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
605 _Pred, _Proj1, _Proj2>
606 constexpr borrowed_subrange_t<_Range1>
607 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
608 _Proj1 __proj1 = {}, _Proj2 __proj2 = {})
const
610 return (*
this)(ranges::begin(__r1), ranges::end(__r1),
611 ranges::begin(__r2), ranges::end(__r2),
617 inline constexpr __search_fn search{};
622 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
623 struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
624 : integral_constant<size_t, 2>
627 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
628 struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
629 {
using type = _Iter; };
631 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
632 struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
633 {
using type = _Sent; };
635 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
636 struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
637 {
using type = _Iter; };
639 template<
typename _Iter,
typename _Sent, ranges::subrange_kind _Kind>
640 struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
641 {
using type = _Sent; };
643_GLIBCXX_END_NAMESPACE_VERSION
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.
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.