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