xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/bits/ranges_util.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg // Utilities for representing and manipulating ranges -*- C++ -*-
2*b1e83836Smrg 
3*b1e83836Smrg // Copyright (C) 2019-2022 Free Software Foundation, Inc.
4*b1e83836Smrg //
5*b1e83836Smrg // This file is part of the GNU ISO C++ Library.  This library is free
6*b1e83836Smrg // software; you can redistribute it and/or modify it under the
7*b1e83836Smrg // terms of the GNU General Public License as published by the
8*b1e83836Smrg // Free Software Foundation; either version 3, or (at your option)
9*b1e83836Smrg // any later version.
10*b1e83836Smrg 
11*b1e83836Smrg // This library is distributed in the hope that it will be useful,
12*b1e83836Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*b1e83836Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*b1e83836Smrg // GNU General Public License for more details.
15*b1e83836Smrg 
16*b1e83836Smrg // Under Section 7 of GPL version 3, you are granted additional
17*b1e83836Smrg // permissions described in the GCC Runtime Library Exception, version
18*b1e83836Smrg // 3.1, as published by the Free Software Foundation.
19*b1e83836Smrg 
20*b1e83836Smrg // You should have received a copy of the GNU General Public License and
21*b1e83836Smrg // a copy of the GCC Runtime Library Exception along with this program;
22*b1e83836Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*b1e83836Smrg // <http://www.gnu.org/licenses/>.
24*b1e83836Smrg 
25*b1e83836Smrg /** @file bits/ranges_util.h
26*b1e83836Smrg  *  This is an internal header file, included by other library headers.
27*b1e83836Smrg  *  Do not attempt to use it directly. @headername{ranges}
28*b1e83836Smrg  */
29*b1e83836Smrg 
30*b1e83836Smrg #ifndef _RANGES_UTIL_H
31*b1e83836Smrg #define _RANGES_UTIL_H 1
32*b1e83836Smrg 
33*b1e83836Smrg #if __cplusplus > 201703L
34*b1e83836Smrg # include <bits/ranges_base.h>
35*b1e83836Smrg # include <bits/utility.h>
36*b1e83836Smrg 
37*b1e83836Smrg #ifdef __cpp_lib_ranges
_GLIBCXX_VISIBILITY(default)38*b1e83836Smrg namespace std _GLIBCXX_VISIBILITY(default)
39*b1e83836Smrg {
40*b1e83836Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
41*b1e83836Smrg namespace ranges
42*b1e83836Smrg {
43*b1e83836Smrg   // C++20 24.5 [range.utility] Range utilities
44*b1e83836Smrg 
45*b1e83836Smrg   namespace __detail
46*b1e83836Smrg   {
47*b1e83836Smrg     template<typename _Range>
48*b1e83836Smrg       concept __simple_view = view<_Range> && range<const _Range>
49*b1e83836Smrg 	&& same_as<iterator_t<_Range>, iterator_t<const _Range>>
50*b1e83836Smrg 	&& same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
51*b1e83836Smrg 
52*b1e83836Smrg     template<typename _It>
53*b1e83836Smrg       concept __has_arrow = input_iterator<_It>
54*b1e83836Smrg 	&& (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
55*b1e83836Smrg 
56*b1e83836Smrg     template<typename _Tp, typename _Up>
57*b1e83836Smrg       concept __different_from
58*b1e83836Smrg 	= !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
59*b1e83836Smrg   } // namespace __detail
60*b1e83836Smrg 
61*b1e83836Smrg   /// The ranges::view_interface class template
62*b1e83836Smrg   template<typename _Derived>
63*b1e83836Smrg     requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
64*b1e83836Smrg     class view_interface
65*b1e83836Smrg     {
66*b1e83836Smrg     private:
67*b1e83836Smrg       constexpr _Derived& _M_derived() noexcept
68*b1e83836Smrg       {
69*b1e83836Smrg 	static_assert(derived_from<_Derived, view_interface<_Derived>>);
70*b1e83836Smrg 	static_assert(view<_Derived>);
71*b1e83836Smrg 	return static_cast<_Derived&>(*this);
72*b1e83836Smrg       }
73*b1e83836Smrg 
74*b1e83836Smrg       constexpr const _Derived& _M_derived() const noexcept
75*b1e83836Smrg       {
76*b1e83836Smrg 	static_assert(derived_from<_Derived, view_interface<_Derived>>);
77*b1e83836Smrg 	static_assert(view<_Derived>);
78*b1e83836Smrg 	return static_cast<const _Derived&>(*this);
79*b1e83836Smrg       }
80*b1e83836Smrg 
81*b1e83836Smrg       static constexpr bool
82*b1e83836Smrg       _S_bool(bool) noexcept; // not defined
83*b1e83836Smrg 
84*b1e83836Smrg       template<typename _Tp>
85*b1e83836Smrg 	static constexpr bool
86*b1e83836Smrg 	_S_empty(_Tp& __t)
87*b1e83836Smrg 	noexcept(noexcept(_S_bool(ranges::begin(__t) == ranges::end(__t))))
88*b1e83836Smrg 	{ return ranges::begin(__t) == ranges::end(__t); }
89*b1e83836Smrg 
90*b1e83836Smrg       template<typename _Tp>
91*b1e83836Smrg 	static constexpr auto
92*b1e83836Smrg 	_S_size(_Tp& __t)
93*b1e83836Smrg 	noexcept(noexcept(ranges::end(__t) - ranges::begin(__t)))
94*b1e83836Smrg 	{ return ranges::end(__t) - ranges::begin(__t); }
95*b1e83836Smrg 
96*b1e83836Smrg     public:
97*b1e83836Smrg       constexpr bool
98*b1e83836Smrg       empty()
99*b1e83836Smrg       noexcept(noexcept(_S_empty(_M_derived())))
100*b1e83836Smrg       requires forward_range<_Derived>
101*b1e83836Smrg       { return _S_empty(_M_derived()); }
102*b1e83836Smrg 
103*b1e83836Smrg       constexpr bool
104*b1e83836Smrg       empty() const
105*b1e83836Smrg       noexcept(noexcept(_S_empty(_M_derived())))
106*b1e83836Smrg       requires forward_range<const _Derived>
107*b1e83836Smrg       { return _S_empty(_M_derived()); }
108*b1e83836Smrg 
109*b1e83836Smrg       constexpr explicit
110*b1e83836Smrg       operator bool() noexcept(noexcept(ranges::empty(_M_derived())))
111*b1e83836Smrg       requires requires { ranges::empty(_M_derived()); }
112*b1e83836Smrg       { return !ranges::empty(_M_derived()); }
113*b1e83836Smrg 
114*b1e83836Smrg       constexpr explicit
115*b1e83836Smrg       operator bool() const noexcept(noexcept(ranges::empty(_M_derived())))
116*b1e83836Smrg       requires requires { ranges::empty(_M_derived()); }
117*b1e83836Smrg       { return !ranges::empty(_M_derived()); }
118*b1e83836Smrg 
119*b1e83836Smrg       constexpr auto
120*b1e83836Smrg       data() noexcept(noexcept(ranges::begin(_M_derived())))
121*b1e83836Smrg       requires contiguous_iterator<iterator_t<_Derived>>
122*b1e83836Smrg       { return std::to_address(ranges::begin(_M_derived())); }
123*b1e83836Smrg 
124*b1e83836Smrg       constexpr auto
125*b1e83836Smrg       data() const noexcept(noexcept(ranges::begin(_M_derived())))
126*b1e83836Smrg       requires range<const _Derived>
127*b1e83836Smrg 	&& contiguous_iterator<iterator_t<const _Derived>>
128*b1e83836Smrg       { return std::to_address(ranges::begin(_M_derived())); }
129*b1e83836Smrg 
130*b1e83836Smrg       constexpr auto
131*b1e83836Smrg       size() noexcept(noexcept(_S_size(_M_derived())))
132*b1e83836Smrg       requires forward_range<_Derived>
133*b1e83836Smrg 	&& sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
134*b1e83836Smrg       { return _S_size(_M_derived()); }
135*b1e83836Smrg 
136*b1e83836Smrg       constexpr auto
137*b1e83836Smrg       size() const noexcept(noexcept(_S_size(_M_derived())))
138*b1e83836Smrg       requires forward_range<const _Derived>
139*b1e83836Smrg 	&& sized_sentinel_for<sentinel_t<const _Derived>,
140*b1e83836Smrg 			      iterator_t<const _Derived>>
141*b1e83836Smrg       { return _S_size(_M_derived()); }
142*b1e83836Smrg 
143*b1e83836Smrg       constexpr decltype(auto)
144*b1e83836Smrg       front() requires forward_range<_Derived>
145*b1e83836Smrg       {
146*b1e83836Smrg 	__glibcxx_assert(!empty());
147*b1e83836Smrg 	return *ranges::begin(_M_derived());
148*b1e83836Smrg       }
149*b1e83836Smrg 
150*b1e83836Smrg       constexpr decltype(auto)
151*b1e83836Smrg       front() const requires forward_range<const _Derived>
152*b1e83836Smrg       {
153*b1e83836Smrg 	__glibcxx_assert(!empty());
154*b1e83836Smrg 	return *ranges::begin(_M_derived());
155*b1e83836Smrg       }
156*b1e83836Smrg 
157*b1e83836Smrg       constexpr decltype(auto)
158*b1e83836Smrg       back()
159*b1e83836Smrg       requires bidirectional_range<_Derived> && common_range<_Derived>
160*b1e83836Smrg       {
161*b1e83836Smrg 	__glibcxx_assert(!empty());
162*b1e83836Smrg 	return *ranges::prev(ranges::end(_M_derived()));
163*b1e83836Smrg       }
164*b1e83836Smrg 
165*b1e83836Smrg       constexpr decltype(auto)
166*b1e83836Smrg       back() const
167*b1e83836Smrg       requires bidirectional_range<const _Derived>
168*b1e83836Smrg 	&& common_range<const _Derived>
169*b1e83836Smrg       {
170*b1e83836Smrg 	__glibcxx_assert(!empty());
171*b1e83836Smrg 	return *ranges::prev(ranges::end(_M_derived()));
172*b1e83836Smrg       }
173*b1e83836Smrg 
174*b1e83836Smrg       template<random_access_range _Range = _Derived>
175*b1e83836Smrg 	constexpr decltype(auto)
176*b1e83836Smrg 	operator[](range_difference_t<_Range> __n)
177*b1e83836Smrg 	{ return ranges::begin(_M_derived())[__n]; }
178*b1e83836Smrg 
179*b1e83836Smrg       template<random_access_range _Range = const _Derived>
180*b1e83836Smrg 	constexpr decltype(auto)
181*b1e83836Smrg 	operator[](range_difference_t<_Range> __n) const
182*b1e83836Smrg 	{ return ranges::begin(_M_derived())[__n]; }
183*b1e83836Smrg     };
184*b1e83836Smrg 
185*b1e83836Smrg   namespace __detail
186*b1e83836Smrg   {
187*b1e83836Smrg     template<typename _From, typename _To>
188*b1e83836Smrg       concept __uses_nonqualification_pointer_conversion
189*b1e83836Smrg 	= is_pointer_v<_From> && is_pointer_v<_To>
190*b1e83836Smrg 	  && !convertible_to<remove_pointer_t<_From>(*)[],
191*b1e83836Smrg 			     remove_pointer_t<_To>(*)[]>;
192*b1e83836Smrg 
193*b1e83836Smrg     template<typename _From, typename _To>
194*b1e83836Smrg       concept __convertible_to_non_slicing = convertible_to<_From, _To>
195*b1e83836Smrg 	&& !__uses_nonqualification_pointer_conversion<decay_t<_From>,
196*b1e83836Smrg 						       decay_t<_To>>;
197*b1e83836Smrg 
198*b1e83836Smrg     template<typename _Tp>
199*b1e83836Smrg       concept __pair_like
200*b1e83836Smrg 	= !is_reference_v<_Tp> && requires(_Tp __t)
201*b1e83836Smrg 	{
202*b1e83836Smrg 	  typename tuple_size<_Tp>::type;
203*b1e83836Smrg 	  requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
204*b1e83836Smrg 	  typename tuple_element_t<0, remove_const_t<_Tp>>;
205*b1e83836Smrg 	  typename tuple_element_t<1, remove_const_t<_Tp>>;
206*b1e83836Smrg 	  { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
207*b1e83836Smrg 	  { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
208*b1e83836Smrg 	};
209*b1e83836Smrg 
210*b1e83836Smrg     template<typename _Tp, typename _Up, typename _Vp>
211*b1e83836Smrg       concept __pair_like_convertible_from
212*b1e83836Smrg 	= !range<_Tp> && __pair_like<_Tp>
213*b1e83836Smrg 	&& constructible_from<_Tp, _Up, _Vp>
214*b1e83836Smrg 	&& __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
215*b1e83836Smrg 	&& convertible_to<_Vp, tuple_element_t<1, _Tp>>;
216*b1e83836Smrg 
217*b1e83836Smrg   } // namespace __detail
218*b1e83836Smrg 
219*b1e83836Smrg   namespace views { struct _Drop; } // defined in <ranges>
220*b1e83836Smrg 
221*b1e83836Smrg   enum class subrange_kind : bool { unsized, sized };
222*b1e83836Smrg 
223*b1e83836Smrg   /// The ranges::subrange class template
224*b1e83836Smrg   template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
225*b1e83836Smrg 	   subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
226*b1e83836Smrg 	     ? subrange_kind::sized : subrange_kind::unsized>
227*b1e83836Smrg     requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
228*b1e83836Smrg     class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
229*b1e83836Smrg     {
230*b1e83836Smrg     private:
231*b1e83836Smrg       static constexpr bool _S_store_size
232*b1e83836Smrg 	= _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
233*b1e83836Smrg 
234*b1e83836Smrg       friend struct views::_Drop; // Needs to inspect _S_store_size.
235*b1e83836Smrg 
236*b1e83836Smrg       _It _M_begin = _It();
237*b1e83836Smrg       [[no_unique_address]] _Sent _M_end = _Sent();
238*b1e83836Smrg 
239*b1e83836Smrg       using __size_type
240*b1e83836Smrg 	= __detail::__make_unsigned_like_t<iter_difference_t<_It>>;
241*b1e83836Smrg 
242*b1e83836Smrg       template<typename, bool = _S_store_size>
243*b1e83836Smrg 	struct _Size
244*b1e83836Smrg 	{ };
245*b1e83836Smrg 
246*b1e83836Smrg       template<typename _Tp>
247*b1e83836Smrg 	struct _Size<_Tp, true>
248*b1e83836Smrg 	{ _Tp _M_size; };
249*b1e83836Smrg 
250*b1e83836Smrg       [[no_unique_address]] _Size<__size_type> _M_size = {};
251*b1e83836Smrg 
252*b1e83836Smrg     public:
253*b1e83836Smrg       subrange() requires default_initializable<_It> = default;
254*b1e83836Smrg 
255*b1e83836Smrg       constexpr
256*b1e83836Smrg       subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
257*b1e83836Smrg       noexcept(is_nothrow_constructible_v<_It, decltype(__i)>
258*b1e83836Smrg 	       && is_nothrow_constructible_v<_Sent, _Sent&>)
259*b1e83836Smrg 	requires (!_S_store_size)
260*b1e83836Smrg       : _M_begin(std::move(__i)), _M_end(__s)
261*b1e83836Smrg       { }
262*b1e83836Smrg 
263*b1e83836Smrg       constexpr
264*b1e83836Smrg       subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
265*b1e83836Smrg 	       __size_type __n)
266*b1e83836Smrg       noexcept(is_nothrow_constructible_v<_It, decltype(__i)>
267*b1e83836Smrg 	       && is_nothrow_constructible_v<_Sent, _Sent&>)
268*b1e83836Smrg 	requires (_Kind == subrange_kind::sized)
269*b1e83836Smrg       : _M_begin(std::move(__i)), _M_end(__s)
270*b1e83836Smrg       {
271*b1e83836Smrg 	if constexpr (_S_store_size)
272*b1e83836Smrg 	  _M_size._M_size = __n;
273*b1e83836Smrg       }
274*b1e83836Smrg 
275*b1e83836Smrg       template<__detail::__different_from<subrange> _Rng>
276*b1e83836Smrg 	requires borrowed_range<_Rng>
277*b1e83836Smrg 	  && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
278*b1e83836Smrg 	  && convertible_to<sentinel_t<_Rng>, _Sent>
279*b1e83836Smrg 	constexpr
280*b1e83836Smrg 	subrange(_Rng&& __r)
281*b1e83836Smrg 	noexcept(noexcept(subrange(__r, ranges::size(__r))))
282*b1e83836Smrg 	requires _S_store_size && sized_range<_Rng>
283*b1e83836Smrg 	: subrange(__r, ranges::size(__r))
284*b1e83836Smrg 	{ }
285*b1e83836Smrg 
286*b1e83836Smrg       template<__detail::__different_from<subrange> _Rng>
287*b1e83836Smrg 	requires borrowed_range<_Rng>
288*b1e83836Smrg 	  && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
289*b1e83836Smrg 	  && convertible_to<sentinel_t<_Rng>, _Sent>
290*b1e83836Smrg 	constexpr
291*b1e83836Smrg 	subrange(_Rng&& __r)
292*b1e83836Smrg 	noexcept(noexcept(subrange(ranges::begin(__r), ranges::end(__r))))
293*b1e83836Smrg 	requires (!_S_store_size)
294*b1e83836Smrg 	: subrange(ranges::begin(__r), ranges::end(__r))
295*b1e83836Smrg 	{ }
296*b1e83836Smrg 
297*b1e83836Smrg       template<borrowed_range _Rng>
298*b1e83836Smrg 	requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
299*b1e83836Smrg 	  && convertible_to<sentinel_t<_Rng>, _Sent>
300*b1e83836Smrg 	constexpr
301*b1e83836Smrg 	subrange(_Rng&& __r, __size_type __n)
302*b1e83836Smrg 	noexcept(noexcept(subrange(ranges::begin(__r), ranges::end(__r), __n)))
303*b1e83836Smrg 	requires (_Kind == subrange_kind::sized)
304*b1e83836Smrg 	: subrange{ranges::begin(__r), ranges::end(__r), __n}
305*b1e83836Smrg 	{ }
306*b1e83836Smrg 
307*b1e83836Smrg       template<__detail::__different_from<subrange> _PairLike>
308*b1e83836Smrg 	requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
309*b1e83836Smrg 							const _Sent&>
310*b1e83836Smrg 	constexpr
311*b1e83836Smrg 	operator _PairLike() const
312*b1e83836Smrg 	{ return _PairLike(_M_begin, _M_end); }
313*b1e83836Smrg 
314*b1e83836Smrg       constexpr _It
315*b1e83836Smrg       begin() const requires copyable<_It>
316*b1e83836Smrg       { return _M_begin; }
317*b1e83836Smrg 
318*b1e83836Smrg       [[nodiscard]] constexpr _It
319*b1e83836Smrg       begin() requires (!copyable<_It>)
320*b1e83836Smrg       { return std::move(_M_begin); }
321*b1e83836Smrg 
322*b1e83836Smrg       constexpr _Sent end() const { return _M_end; }
323*b1e83836Smrg 
324*b1e83836Smrg       constexpr bool empty() const { return _M_begin == _M_end; }
325*b1e83836Smrg 
326*b1e83836Smrg       constexpr __size_type
327*b1e83836Smrg       size() const requires (_Kind == subrange_kind::sized)
328*b1e83836Smrg       {
329*b1e83836Smrg 	if constexpr (_S_store_size)
330*b1e83836Smrg 	  return _M_size._M_size;
331*b1e83836Smrg 	else
332*b1e83836Smrg 	  return __detail::__to_unsigned_like(_M_end - _M_begin);
333*b1e83836Smrg       }
334*b1e83836Smrg 
335*b1e83836Smrg       [[nodiscard]] constexpr subrange
336*b1e83836Smrg       next(iter_difference_t<_It> __n = 1) const &
337*b1e83836Smrg 	requires forward_iterator<_It>
338*b1e83836Smrg       {
339*b1e83836Smrg 	auto __tmp = *this;
340*b1e83836Smrg 	__tmp.advance(__n);
341*b1e83836Smrg 	return __tmp;
342*b1e83836Smrg       }
343*b1e83836Smrg 
344*b1e83836Smrg       [[nodiscard]] constexpr subrange
345*b1e83836Smrg       next(iter_difference_t<_It> __n = 1) &&
346*b1e83836Smrg       {
347*b1e83836Smrg 	advance(__n);
348*b1e83836Smrg 	return std::move(*this);
349*b1e83836Smrg       }
350*b1e83836Smrg 
351*b1e83836Smrg       [[nodiscard]] constexpr subrange
352*b1e83836Smrg       prev(iter_difference_t<_It> __n = 1) const
353*b1e83836Smrg 	requires bidirectional_iterator<_It>
354*b1e83836Smrg       {
355*b1e83836Smrg 	auto __tmp = *this;
356*b1e83836Smrg 	__tmp.advance(-__n);
357*b1e83836Smrg 	return __tmp;
358*b1e83836Smrg       }
359*b1e83836Smrg 
360*b1e83836Smrg       constexpr subrange&
361*b1e83836Smrg       advance(iter_difference_t<_It> __n)
362*b1e83836Smrg       {
363*b1e83836Smrg 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
364*b1e83836Smrg 	// 3433. subrange::advance(n) has UB when n < 0
365*b1e83836Smrg 	if constexpr (bidirectional_iterator<_It>)
366*b1e83836Smrg 	  if (__n < 0)
367*b1e83836Smrg 	    {
368*b1e83836Smrg 	      ranges::advance(_M_begin, __n);
369*b1e83836Smrg 	      if constexpr (_S_store_size)
370*b1e83836Smrg 		_M_size._M_size += __detail::__to_unsigned_like(-__n);
371*b1e83836Smrg 	      return *this;
372*b1e83836Smrg 	    }
373*b1e83836Smrg 
374*b1e83836Smrg 	__glibcxx_assert(__n >= 0);
375*b1e83836Smrg 	auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
376*b1e83836Smrg 	if constexpr (_S_store_size)
377*b1e83836Smrg 	  _M_size._M_size -= __detail::__to_unsigned_like(__d);
378*b1e83836Smrg 	return *this;
379*b1e83836Smrg       }
380*b1e83836Smrg     };
381*b1e83836Smrg 
382*b1e83836Smrg   template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
383*b1e83836Smrg     subrange(_It, _Sent) -> subrange<_It, _Sent>;
384*b1e83836Smrg 
385*b1e83836Smrg   template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
386*b1e83836Smrg     subrange(_It, _Sent,
387*b1e83836Smrg 	     __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
388*b1e83836Smrg       -> subrange<_It, _Sent, subrange_kind::sized>;
389*b1e83836Smrg 
390*b1e83836Smrg   template<borrowed_range _Rng>
391*b1e83836Smrg     subrange(_Rng&&)
392*b1e83836Smrg       -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
393*b1e83836Smrg 		 (sized_range<_Rng>
394*b1e83836Smrg 		  || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
395*b1e83836Smrg 		 ? subrange_kind::sized : subrange_kind::unsized>;
396*b1e83836Smrg 
397*b1e83836Smrg   template<borrowed_range _Rng>
398*b1e83836Smrg     subrange(_Rng&&,
399*b1e83836Smrg 	     __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
400*b1e83836Smrg       -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
401*b1e83836Smrg 
402*b1e83836Smrg   template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
403*b1e83836Smrg     requires (_Num < 2)
404*b1e83836Smrg     constexpr auto
405*b1e83836Smrg     get(const subrange<_It, _Sent, _Kind>& __r)
406*b1e83836Smrg     {
407*b1e83836Smrg       if constexpr (_Num == 0)
408*b1e83836Smrg 	return __r.begin();
409*b1e83836Smrg       else
410*b1e83836Smrg 	return __r.end();
411*b1e83836Smrg     }
412*b1e83836Smrg 
413*b1e83836Smrg   template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
414*b1e83836Smrg     requires (_Num < 2)
415*b1e83836Smrg     constexpr auto
416*b1e83836Smrg     get(subrange<_It, _Sent, _Kind>&& __r)
417*b1e83836Smrg     {
418*b1e83836Smrg       if constexpr (_Num == 0)
419*b1e83836Smrg 	return __r.begin();
420*b1e83836Smrg       else
421*b1e83836Smrg 	return __r.end();
422*b1e83836Smrg     }
423*b1e83836Smrg 
424*b1e83836Smrg   template<typename _It, typename _Sent, subrange_kind _Kind>
425*b1e83836Smrg     inline constexpr bool
426*b1e83836Smrg       enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
427*b1e83836Smrg 
428*b1e83836Smrg   template<range _Range>
429*b1e83836Smrg     using borrowed_subrange_t = __conditional_t<borrowed_range<_Range>,
430*b1e83836Smrg 						subrange<iterator_t<_Range>>,
431*b1e83836Smrg 						dangling>;
432*b1e83836Smrg } // namespace ranges
433*b1e83836Smrg 
434*b1e83836Smrg // The following ranges algorithms are used by <ranges>, and are defined here
435*b1e83836Smrg // so that <ranges> can avoid including all of <bits/ranges_algo.h>.
436*b1e83836Smrg namespace ranges
437*b1e83836Smrg {
438*b1e83836Smrg   struct __find_fn
439*b1e83836Smrg   {
440*b1e83836Smrg     template<input_iterator _Iter, sentinel_for<_Iter> _Sent, typename _Tp,
441*b1e83836Smrg 	     typename _Proj = identity>
442*b1e83836Smrg       requires indirect_binary_predicate<ranges::equal_to,
443*b1e83836Smrg 					 projected<_Iter, _Proj>, const _Tp*>
444*b1e83836Smrg       constexpr _Iter
445*b1e83836Smrg       operator()(_Iter __first, _Sent __last,
446*b1e83836Smrg 		 const _Tp& __value, _Proj __proj = {}) const
447*b1e83836Smrg       {
448*b1e83836Smrg 	while (__first != __last
449*b1e83836Smrg 	    && !(std::__invoke(__proj, *__first) == __value))
450*b1e83836Smrg 	  ++__first;
451*b1e83836Smrg 	return __first;
452*b1e83836Smrg       }
453*b1e83836Smrg 
454*b1e83836Smrg     template<input_range _Range, typename _Tp, typename _Proj = identity>
455*b1e83836Smrg       requires indirect_binary_predicate<ranges::equal_to,
456*b1e83836Smrg 					 projected<iterator_t<_Range>, _Proj>,
457*b1e83836Smrg 					 const _Tp*>
458*b1e83836Smrg       constexpr borrowed_iterator_t<_Range>
459*b1e83836Smrg       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
460*b1e83836Smrg       {
461*b1e83836Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r),
462*b1e83836Smrg 		       __value, std::move(__proj));
463*b1e83836Smrg       }
464*b1e83836Smrg   };
465*b1e83836Smrg 
466*b1e83836Smrg   inline constexpr __find_fn find{};
467*b1e83836Smrg 
468*b1e83836Smrg   struct __find_if_fn
469*b1e83836Smrg   {
470*b1e83836Smrg     template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
471*b1e83836Smrg 	     typename _Proj = identity,
472*b1e83836Smrg 	     indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
473*b1e83836Smrg       constexpr _Iter
474*b1e83836Smrg       operator()(_Iter __first, _Sent __last,
475*b1e83836Smrg 		 _Pred __pred, _Proj __proj = {}) const
476*b1e83836Smrg       {
477*b1e83836Smrg 	while (__first != __last
478*b1e83836Smrg 	    && !(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
479*b1e83836Smrg 	  ++__first;
480*b1e83836Smrg 	return __first;
481*b1e83836Smrg       }
482*b1e83836Smrg 
483*b1e83836Smrg     template<input_range _Range, typename _Proj = identity,
484*b1e83836Smrg 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
485*b1e83836Smrg 	       _Pred>
486*b1e83836Smrg       constexpr borrowed_iterator_t<_Range>
487*b1e83836Smrg       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
488*b1e83836Smrg       {
489*b1e83836Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r),
490*b1e83836Smrg 		       std::move(__pred), std::move(__proj));
491*b1e83836Smrg       }
492*b1e83836Smrg   };
493*b1e83836Smrg 
494*b1e83836Smrg   inline constexpr __find_if_fn find_if{};
495*b1e83836Smrg 
496*b1e83836Smrg   struct __find_if_not_fn
497*b1e83836Smrg   {
498*b1e83836Smrg     template<input_iterator _Iter, sentinel_for<_Iter> _Sent,
499*b1e83836Smrg 	     typename _Proj = identity,
500*b1e83836Smrg 	     indirect_unary_predicate<projected<_Iter, _Proj>> _Pred>
501*b1e83836Smrg       constexpr _Iter
502*b1e83836Smrg       operator()(_Iter __first, _Sent __last,
503*b1e83836Smrg 		 _Pred __pred, _Proj __proj = {}) const
504*b1e83836Smrg       {
505*b1e83836Smrg 	while (__first != __last
506*b1e83836Smrg 	    && (bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
507*b1e83836Smrg 	  ++__first;
508*b1e83836Smrg 	return __first;
509*b1e83836Smrg       }
510*b1e83836Smrg 
511*b1e83836Smrg     template<input_range _Range, typename _Proj = identity,
512*b1e83836Smrg 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
513*b1e83836Smrg 	       _Pred>
514*b1e83836Smrg       constexpr borrowed_iterator_t<_Range>
515*b1e83836Smrg       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
516*b1e83836Smrg       {
517*b1e83836Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r),
518*b1e83836Smrg 		       std::move(__pred), std::move(__proj));
519*b1e83836Smrg       }
520*b1e83836Smrg   };
521*b1e83836Smrg 
522*b1e83836Smrg   inline constexpr __find_if_not_fn find_if_not{};
523*b1e83836Smrg 
524*b1e83836Smrg   template<typename _Iter1, typename _Iter2>
525*b1e83836Smrg     struct in_in_result
526*b1e83836Smrg     {
527*b1e83836Smrg       [[no_unique_address]] _Iter1 in1;
528*b1e83836Smrg       [[no_unique_address]] _Iter2 in2;
529*b1e83836Smrg 
530*b1e83836Smrg       template<typename _IIter1, typename _IIter2>
531*b1e83836Smrg 	requires convertible_to<const _Iter1&, _IIter1>
532*b1e83836Smrg 	  && convertible_to<const _Iter2&, _IIter2>
533*b1e83836Smrg 	constexpr
534*b1e83836Smrg 	operator in_in_result<_IIter1, _IIter2>() const &
535*b1e83836Smrg 	{ return {in1, in2}; }
536*b1e83836Smrg 
537*b1e83836Smrg       template<typename _IIter1, typename _IIter2>
538*b1e83836Smrg 	requires convertible_to<_Iter1, _IIter1>
539*b1e83836Smrg 	  && convertible_to<_Iter2, _IIter2>
540*b1e83836Smrg 	constexpr
541*b1e83836Smrg 	operator in_in_result<_IIter1, _IIter2>() &&
542*b1e83836Smrg 	{ return {std::move(in1), std::move(in2)}; }
543*b1e83836Smrg     };
544*b1e83836Smrg 
545*b1e83836Smrg   template<typename _Iter1, typename _Iter2>
546*b1e83836Smrg     using mismatch_result = in_in_result<_Iter1, _Iter2>;
547*b1e83836Smrg 
548*b1e83836Smrg   struct __mismatch_fn
549*b1e83836Smrg   {
550*b1e83836Smrg     template<input_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
551*b1e83836Smrg 	     input_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
552*b1e83836Smrg 	     typename _Pred = ranges::equal_to,
553*b1e83836Smrg 	     typename _Proj1 = identity, typename _Proj2 = identity>
554*b1e83836Smrg       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
555*b1e83836Smrg       constexpr mismatch_result<_Iter1, _Iter2>
556*b1e83836Smrg       operator()(_Iter1 __first1, _Sent1 __last1,
557*b1e83836Smrg 		 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
558*b1e83836Smrg 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
559*b1e83836Smrg       {
560*b1e83836Smrg 	while (__first1 != __last1 && __first2 != __last2
561*b1e83836Smrg 	       && (bool)std::__invoke(__pred,
562*b1e83836Smrg 				      std::__invoke(__proj1, *__first1),
563*b1e83836Smrg 				      std::__invoke(__proj2, *__first2)))
564*b1e83836Smrg 	{
565*b1e83836Smrg 	  ++__first1;
566*b1e83836Smrg 	  ++__first2;
567*b1e83836Smrg 	}
568*b1e83836Smrg 	return { std::move(__first1), std::move(__first2) };
569*b1e83836Smrg       }
570*b1e83836Smrg 
571*b1e83836Smrg     template<input_range _Range1, input_range _Range2,
572*b1e83836Smrg 	     typename _Pred = ranges::equal_to,
573*b1e83836Smrg 	     typename _Proj1 = identity, typename _Proj2 = identity>
574*b1e83836Smrg       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
575*b1e83836Smrg 				     _Pred, _Proj1, _Proj2>
576*b1e83836Smrg       constexpr mismatch_result<iterator_t<_Range1>, iterator_t<_Range2>>
577*b1e83836Smrg       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
578*b1e83836Smrg 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
579*b1e83836Smrg       {
580*b1e83836Smrg 	return (*this)(ranges::begin(__r1), ranges::end(__r1),
581*b1e83836Smrg 		       ranges::begin(__r2), ranges::end(__r2),
582*b1e83836Smrg 		       std::move(__pred),
583*b1e83836Smrg 		       std::move(__proj1), std::move(__proj2));
584*b1e83836Smrg       }
585*b1e83836Smrg   };
586*b1e83836Smrg 
587*b1e83836Smrg   inline constexpr __mismatch_fn mismatch{};
588*b1e83836Smrg 
589*b1e83836Smrg   struct __search_fn
590*b1e83836Smrg   {
591*b1e83836Smrg     template<forward_iterator _Iter1, sentinel_for<_Iter1> _Sent1,
592*b1e83836Smrg 	     forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2,
593*b1e83836Smrg 	     typename _Pred = ranges::equal_to,
594*b1e83836Smrg 	     typename _Proj1 = identity, typename _Proj2 = identity>
595*b1e83836Smrg       requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2>
596*b1e83836Smrg       constexpr subrange<_Iter1>
597*b1e83836Smrg       operator()(_Iter1 __first1, _Sent1 __last1,
598*b1e83836Smrg 		 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {},
599*b1e83836Smrg 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
600*b1e83836Smrg       {
601*b1e83836Smrg 	if (__first1 == __last1 || __first2 == __last2)
602*b1e83836Smrg 	  return {__first1, __first1};
603*b1e83836Smrg 
604*b1e83836Smrg 	for (;;)
605*b1e83836Smrg 	  {
606*b1e83836Smrg 	    for (;;)
607*b1e83836Smrg 	      {
608*b1e83836Smrg 		if (__first1 == __last1)
609*b1e83836Smrg 		  return {__first1, __first1};
610*b1e83836Smrg 		if (std::__invoke(__pred,
611*b1e83836Smrg 				  std::__invoke(__proj1, *__first1),
612*b1e83836Smrg 				  std::__invoke(__proj2, *__first2)))
613*b1e83836Smrg 		  break;
614*b1e83836Smrg 		++__first1;
615*b1e83836Smrg 	      }
616*b1e83836Smrg 	    auto __cur1 = __first1;
617*b1e83836Smrg 	    auto __cur2 = __first2;
618*b1e83836Smrg 	    for (;;)
619*b1e83836Smrg 	      {
620*b1e83836Smrg 		if (++__cur2 == __last2)
621*b1e83836Smrg 		  return {__first1, ++__cur1};
622*b1e83836Smrg 		if (++__cur1 == __last1)
623*b1e83836Smrg 		  return {__cur1, __cur1};
624*b1e83836Smrg 		if (!(bool)std::__invoke(__pred,
625*b1e83836Smrg 					 std::__invoke(__proj1, *__cur1),
626*b1e83836Smrg 					 std::__invoke(__proj2, *__cur2)))
627*b1e83836Smrg 		  {
628*b1e83836Smrg 		    ++__first1;
629*b1e83836Smrg 		    break;
630*b1e83836Smrg 		  }
631*b1e83836Smrg 	      }
632*b1e83836Smrg 	  }
633*b1e83836Smrg       }
634*b1e83836Smrg 
635*b1e83836Smrg     template<forward_range _Range1, forward_range _Range2,
636*b1e83836Smrg 	     typename _Pred = ranges::equal_to,
637*b1e83836Smrg 	     typename _Proj1 = identity, typename _Proj2 = identity>
638*b1e83836Smrg       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
639*b1e83836Smrg 				     _Pred, _Proj1, _Proj2>
640*b1e83836Smrg       constexpr borrowed_subrange_t<_Range1>
641*b1e83836Smrg       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
642*b1e83836Smrg 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
643*b1e83836Smrg       {
644*b1e83836Smrg 	return (*this)(ranges::begin(__r1), ranges::end(__r1),
645*b1e83836Smrg 		       ranges::begin(__r2), ranges::end(__r2),
646*b1e83836Smrg 		       std::move(__pred),
647*b1e83836Smrg 		       std::move(__proj1), std::move(__proj2));
648*b1e83836Smrg       }
649*b1e83836Smrg   };
650*b1e83836Smrg 
651*b1e83836Smrg   inline constexpr __search_fn search{};
652*b1e83836Smrg } // namespace ranges
653*b1e83836Smrg 
654*b1e83836Smrg   using ranges::get;
655*b1e83836Smrg 
656*b1e83836Smrg   template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
657*b1e83836Smrg     struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
658*b1e83836Smrg     : integral_constant<size_t, 2>
659*b1e83836Smrg     { };
660*b1e83836Smrg 
661*b1e83836Smrg   template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
662*b1e83836Smrg     struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
663*b1e83836Smrg     { using type = _Iter; };
664*b1e83836Smrg 
665*b1e83836Smrg   template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
666*b1e83836Smrg     struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
667*b1e83836Smrg     { using type = _Sent; };
668*b1e83836Smrg 
669*b1e83836Smrg   template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
670*b1e83836Smrg     struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
671*b1e83836Smrg     { using type = _Iter; };
672*b1e83836Smrg 
673*b1e83836Smrg   template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
674*b1e83836Smrg     struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
675*b1e83836Smrg     { using type = _Sent; };
676*b1e83836Smrg 
677*b1e83836Smrg _GLIBCXX_END_NAMESPACE_VERSION
678*b1e83836Smrg } // namespace std
679*b1e83836Smrg #endif // library concepts
680*b1e83836Smrg #endif // C++20
681*b1e83836Smrg #endif // _RANGES_UTIL_H
682