xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/ranges_uninitialized.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1*4c3eb207Smrg // Raw memory manipulators -*- C++ -*-
2*4c3eb207Smrg 
3*4c3eb207Smrg // Copyright (C) 2020 Free Software Foundation, Inc.
4*4c3eb207Smrg //
5*4c3eb207Smrg // This file is part of the GNU ISO C++ Library.  This library is free
6*4c3eb207Smrg // software; you can redistribute it and/or modify it under the
7*4c3eb207Smrg // terms of the GNU General Public License as published by the
8*4c3eb207Smrg // Free Software Foundation; either version 3, or (at your option)
9*4c3eb207Smrg // any later version.
10*4c3eb207Smrg 
11*4c3eb207Smrg // This library is distributed in the hope that it will be useful,
12*4c3eb207Smrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
13*4c3eb207Smrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*4c3eb207Smrg // GNU General Public License for more details.
15*4c3eb207Smrg 
16*4c3eb207Smrg // Under Section 7 of GPL version 3, you are granted additional
17*4c3eb207Smrg // permissions described in the GCC Runtime Library Exception, version
18*4c3eb207Smrg // 3.1, as published by the Free Software Foundation.
19*4c3eb207Smrg 
20*4c3eb207Smrg // You should have received a copy of the GNU General Public License and
21*4c3eb207Smrg // a copy of the GCC Runtime Library Exception along with this program;
22*4c3eb207Smrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*4c3eb207Smrg // <http://www.gnu.org/licenses/>.
24*4c3eb207Smrg 
25*4c3eb207Smrg /** @file bits/ranges_uninitialized.h
26*4c3eb207Smrg  *  This is an internal header file, included by other library headers.
27*4c3eb207Smrg  *  Do not attempt to use it directly. @headername{memory}
28*4c3eb207Smrg  */
29*4c3eb207Smrg 
30*4c3eb207Smrg #ifndef _RANGES_UNINITIALIZED_H
31*4c3eb207Smrg #define _RANGES_UNINITIALIZED_H 1
32*4c3eb207Smrg 
33*4c3eb207Smrg #if __cplusplus > 201703L
34*4c3eb207Smrg #if __cpp_lib_concepts
35*4c3eb207Smrg 
36*4c3eb207Smrg #include <bits/ranges_algobase.h>
37*4c3eb207Smrg 
_GLIBCXX_VISIBILITY(default)38*4c3eb207Smrg namespace std _GLIBCXX_VISIBILITY(default)
39*4c3eb207Smrg {
40*4c3eb207Smrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
41*4c3eb207Smrg namespace ranges
42*4c3eb207Smrg {
43*4c3eb207Smrg   namespace __detail
44*4c3eb207Smrg   {
45*4c3eb207Smrg     template<typename _Tp>
46*4c3eb207Smrg       constexpr void*
47*4c3eb207Smrg       __voidify(_Tp& __obj) noexcept
48*4c3eb207Smrg       {
49*4c3eb207Smrg 	return const_cast<void*>
50*4c3eb207Smrg 		 (static_cast<const volatile void*>(std::__addressof(__obj)));
51*4c3eb207Smrg       }
52*4c3eb207Smrg 
53*4c3eb207Smrg     template<typename _Iter>
54*4c3eb207Smrg       concept __nothrow_input_iterator
55*4c3eb207Smrg 	= (input_iterator<_Iter>
56*4c3eb207Smrg 	   && is_lvalue_reference_v<iter_reference_t<_Iter>>
57*4c3eb207Smrg 	   && same_as<remove_cvref_t<iter_reference_t<_Iter>>,
58*4c3eb207Smrg 		      iter_value_t<_Iter>>);
59*4c3eb207Smrg 
60*4c3eb207Smrg     template<typename _Sent, typename _Iter>
61*4c3eb207Smrg       concept __nothrow_sentinel = sentinel_for<_Sent, _Iter>;
62*4c3eb207Smrg 
63*4c3eb207Smrg     template<typename _Range>
64*4c3eb207Smrg       concept __nothrow_input_range
65*4c3eb207Smrg 	= (range<_Range>
66*4c3eb207Smrg 	   && __nothrow_input_iterator<iterator_t<_Range>>
67*4c3eb207Smrg 	   && __nothrow_sentinel<sentinel_t<_Range>, iterator_t<_Range>>);
68*4c3eb207Smrg 
69*4c3eb207Smrg     template<typename _Iter>
70*4c3eb207Smrg       concept __nothrow_forward_iterator
71*4c3eb207Smrg 	= (__nothrow_input_iterator<_Iter>
72*4c3eb207Smrg 	   && forward_iterator<_Iter>
73*4c3eb207Smrg 	   && __nothrow_sentinel<_Iter, _Iter>);
74*4c3eb207Smrg 
75*4c3eb207Smrg     template<typename _Range>
76*4c3eb207Smrg       concept __nothrow_forward_range
77*4c3eb207Smrg 	= (__nothrow_input_range<_Range>
78*4c3eb207Smrg 	   && __nothrow_forward_iterator<iterator_t<_Range>>);
79*4c3eb207Smrg   } // namespace __detail
80*4c3eb207Smrg 
81*4c3eb207Smrg   struct __destroy_fn
82*4c3eb207Smrg   {
83*4c3eb207Smrg     template<__detail::__nothrow_input_iterator _Iter,
84*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Iter> _Sent>
85*4c3eb207Smrg       requires destructible<iter_value_t<_Iter>>
86*4c3eb207Smrg       constexpr _Iter
87*4c3eb207Smrg       operator()(_Iter __first, _Sent __last) const noexcept;
88*4c3eb207Smrg 
89*4c3eb207Smrg     template<__detail::__nothrow_input_range _Range>
90*4c3eb207Smrg       requires destructible<range_value_t<_Range>>
91*4c3eb207Smrg       constexpr borrowed_iterator_t<_Range>
92*4c3eb207Smrg       operator()(_Range&& __r) const noexcept;
93*4c3eb207Smrg   };
94*4c3eb207Smrg 
95*4c3eb207Smrg   inline constexpr __destroy_fn destroy{};
96*4c3eb207Smrg 
97*4c3eb207Smrg   namespace __detail
98*4c3eb207Smrg   {
99*4c3eb207Smrg     template<typename _Iter>
100*4c3eb207Smrg       requires destructible<iter_value_t<_Iter>>
101*4c3eb207Smrg       struct _DestroyGuard
102*4c3eb207Smrg       {
103*4c3eb207Smrg       private:
104*4c3eb207Smrg 	_Iter _M_first;
105*4c3eb207Smrg 	const _Iter* _M_cur;
106*4c3eb207Smrg 
107*4c3eb207Smrg       public:
108*4c3eb207Smrg 	explicit
109*4c3eb207Smrg 	_DestroyGuard(const _Iter& __iter)
110*4c3eb207Smrg 	  : _M_first(__iter), _M_cur(std::__addressof(__iter))
111*4c3eb207Smrg 	{ }
112*4c3eb207Smrg 
113*4c3eb207Smrg 	void
114*4c3eb207Smrg 	release() noexcept
115*4c3eb207Smrg 	{ _M_cur = nullptr; }
116*4c3eb207Smrg 
117*4c3eb207Smrg 	~_DestroyGuard()
118*4c3eb207Smrg 	{
119*4c3eb207Smrg 	  if (_M_cur != nullptr)
120*4c3eb207Smrg 	    ranges::destroy(std::move(_M_first), *_M_cur);
121*4c3eb207Smrg 	}
122*4c3eb207Smrg       };
123*4c3eb207Smrg 
124*4c3eb207Smrg     template<typename _Iter>
125*4c3eb207Smrg       requires destructible<iter_value_t<_Iter>>
126*4c3eb207Smrg 	&& is_trivially_destructible_v<iter_value_t<_Iter>>
127*4c3eb207Smrg       struct _DestroyGuard<_Iter>
128*4c3eb207Smrg       {
129*4c3eb207Smrg 	explicit
130*4c3eb207Smrg 	_DestroyGuard(const _Iter&)
131*4c3eb207Smrg 	{ }
132*4c3eb207Smrg 
133*4c3eb207Smrg 	void
134*4c3eb207Smrg 	release() noexcept
135*4c3eb207Smrg 	{ }
136*4c3eb207Smrg       };
137*4c3eb207Smrg   } // namespace __detail
138*4c3eb207Smrg 
139*4c3eb207Smrg   struct __uninitialized_default_construct_fn
140*4c3eb207Smrg   {
141*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter,
142*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Iter> _Sent>
143*4c3eb207Smrg       requires default_initializable<iter_value_t<_Iter>>
144*4c3eb207Smrg       _Iter
145*4c3eb207Smrg       operator()(_Iter __first, _Sent __last) const
146*4c3eb207Smrg       {
147*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
148*4c3eb207Smrg 	if constexpr (is_trivially_default_constructible_v<_ValueType>)
149*4c3eb207Smrg 	  return ranges::next(__first, __last);
150*4c3eb207Smrg 	else
151*4c3eb207Smrg 	  {
152*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
153*4c3eb207Smrg 	    for (; __first != __last; ++__first)
154*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType;
155*4c3eb207Smrg 	    __guard.release();
156*4c3eb207Smrg 	    return __first;
157*4c3eb207Smrg 	  }
158*4c3eb207Smrg       }
159*4c3eb207Smrg 
160*4c3eb207Smrg     template<__detail::__nothrow_forward_range _Range>
161*4c3eb207Smrg       requires default_initializable<range_value_t<_Range>>
162*4c3eb207Smrg       borrowed_iterator_t<_Range>
163*4c3eb207Smrg       operator()(_Range&& __r) const
164*4c3eb207Smrg       {
165*4c3eb207Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r));
166*4c3eb207Smrg       }
167*4c3eb207Smrg   };
168*4c3eb207Smrg 
169*4c3eb207Smrg   inline constexpr __uninitialized_default_construct_fn
170*4c3eb207Smrg     uninitialized_default_construct{};
171*4c3eb207Smrg 
172*4c3eb207Smrg   struct __uninitialized_default_construct_n_fn
173*4c3eb207Smrg   {
174*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter>
175*4c3eb207Smrg       requires default_initializable<iter_value_t<_Iter>>
176*4c3eb207Smrg       _Iter
177*4c3eb207Smrg       operator()(_Iter __first, iter_difference_t<_Iter> __n) const
178*4c3eb207Smrg       {
179*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
180*4c3eb207Smrg 	if constexpr (is_trivially_default_constructible_v<_ValueType>)
181*4c3eb207Smrg 	  return ranges::next(__first, __n);
182*4c3eb207Smrg 	else
183*4c3eb207Smrg 	  {
184*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
185*4c3eb207Smrg 	    for (; __n > 0; ++__first, (void) --__n)
186*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType;
187*4c3eb207Smrg 	    __guard.release();
188*4c3eb207Smrg 	    return __first;
189*4c3eb207Smrg 	  }
190*4c3eb207Smrg       }
191*4c3eb207Smrg   };
192*4c3eb207Smrg 
193*4c3eb207Smrg   inline constexpr __uninitialized_default_construct_n_fn
194*4c3eb207Smrg     uninitialized_default_construct_n;
195*4c3eb207Smrg 
196*4c3eb207Smrg   struct __uninitialized_value_construct_fn
197*4c3eb207Smrg   {
198*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter,
199*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Iter> _Sent>
200*4c3eb207Smrg       requires default_initializable<iter_value_t<_Iter>>
201*4c3eb207Smrg       _Iter
202*4c3eb207Smrg       operator()(_Iter __first, _Sent __last) const
203*4c3eb207Smrg       {
204*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
205*4c3eb207Smrg 	if constexpr (is_trivial_v<_ValueType>
206*4c3eb207Smrg 		      && is_copy_assignable_v<_ValueType>)
207*4c3eb207Smrg 	  return ranges::fill(__first, __last, _ValueType());
208*4c3eb207Smrg 	else
209*4c3eb207Smrg 	  {
210*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
211*4c3eb207Smrg 	    for (; __first != __last; ++__first)
212*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType();
213*4c3eb207Smrg 	    __guard.release();
214*4c3eb207Smrg 	    return __first;
215*4c3eb207Smrg 	  }
216*4c3eb207Smrg       }
217*4c3eb207Smrg 
218*4c3eb207Smrg     template<__detail::__nothrow_forward_range _Range>
219*4c3eb207Smrg       requires default_initializable<range_value_t<_Range>>
220*4c3eb207Smrg       borrowed_iterator_t<_Range>
221*4c3eb207Smrg       operator()(_Range&& __r) const
222*4c3eb207Smrg       {
223*4c3eb207Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r));
224*4c3eb207Smrg       }
225*4c3eb207Smrg   };
226*4c3eb207Smrg 
227*4c3eb207Smrg   inline constexpr __uninitialized_value_construct_fn
228*4c3eb207Smrg     uninitialized_value_construct{};
229*4c3eb207Smrg 
230*4c3eb207Smrg   struct __uninitialized_value_construct_n_fn
231*4c3eb207Smrg   {
232*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter>
233*4c3eb207Smrg       requires default_initializable<iter_value_t<_Iter>>
234*4c3eb207Smrg       _Iter
235*4c3eb207Smrg       operator()(_Iter __first, iter_difference_t<_Iter> __n) const
236*4c3eb207Smrg       {
237*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
238*4c3eb207Smrg 	if constexpr (is_trivial_v<_ValueType>
239*4c3eb207Smrg 		      && is_copy_assignable_v<_ValueType>)
240*4c3eb207Smrg 	  return ranges::fill_n(__first, __n, _ValueType());
241*4c3eb207Smrg 	else
242*4c3eb207Smrg 	  {
243*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
244*4c3eb207Smrg 	    for (; __n > 0; ++__first, (void) --__n)
245*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType();
246*4c3eb207Smrg 	    __guard.release();
247*4c3eb207Smrg 	    return __first;
248*4c3eb207Smrg 	  }
249*4c3eb207Smrg       }
250*4c3eb207Smrg   };
251*4c3eb207Smrg 
252*4c3eb207Smrg   inline constexpr __uninitialized_value_construct_n_fn
253*4c3eb207Smrg     uninitialized_value_construct_n;
254*4c3eb207Smrg 
255*4c3eb207Smrg   template<typename _Iter, typename _Out>
256*4c3eb207Smrg     using uninitialized_copy_result = in_out_result<_Iter, _Out>;
257*4c3eb207Smrg 
258*4c3eb207Smrg   struct __uninitialized_copy_fn
259*4c3eb207Smrg   {
260*4c3eb207Smrg     template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
261*4c3eb207Smrg 	     __detail::__nothrow_forward_iterator _Out,
262*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Out> _OSent>
263*4c3eb207Smrg       requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
264*4c3eb207Smrg       uninitialized_copy_result<_Iter, _Out>
265*4c3eb207Smrg       operator()(_Iter __ifirst, _ISent __ilast,
266*4c3eb207Smrg 		 _Out __ofirst, _OSent __olast) const
267*4c3eb207Smrg       {
268*4c3eb207Smrg 	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
269*4c3eb207Smrg 	if constexpr (sized_sentinel_for<_ISent, _Iter>
270*4c3eb207Smrg 		      && sized_sentinel_for<_OSent, _Out>
271*4c3eb207Smrg 		      && is_trivial_v<_OutType>
272*4c3eb207Smrg 		      && is_nothrow_assignable_v<_OutType&,
273*4c3eb207Smrg 						 iter_reference_t<_Iter>>)
274*4c3eb207Smrg 	  {
275*4c3eb207Smrg 	    auto __d1 = __ilast - __ifirst;
276*4c3eb207Smrg 	    auto __d2 = __olast - __ofirst;
277*4c3eb207Smrg 	    return ranges::copy_n(std::move(__ifirst), std::min(__d1, __d2),
278*4c3eb207Smrg 				  __ofirst);
279*4c3eb207Smrg 	  }
280*4c3eb207Smrg 	else
281*4c3eb207Smrg 	  {
282*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__ofirst);
283*4c3eb207Smrg 	    for (; __ifirst != __ilast && __ofirst != __olast;
284*4c3eb207Smrg 		 ++__ofirst, (void)++__ifirst)
285*4c3eb207Smrg 	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
286*4c3eb207Smrg 	    __guard.release();
287*4c3eb207Smrg 	    return {std::move(__ifirst), __ofirst};
288*4c3eb207Smrg 	  }
289*4c3eb207Smrg       }
290*4c3eb207Smrg 
291*4c3eb207Smrg     template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
292*4c3eb207Smrg       requires constructible_from<range_value_t<_ORange>,
293*4c3eb207Smrg 				  range_reference_t<_IRange>>
294*4c3eb207Smrg       uninitialized_copy_result<borrowed_iterator_t<_IRange>,
295*4c3eb207Smrg 				borrowed_iterator_t<_ORange>>
296*4c3eb207Smrg       operator()(_IRange&& __inr, _ORange&& __outr) const
297*4c3eb207Smrg       {
298*4c3eb207Smrg 	return (*this)(ranges::begin(__inr), ranges::end(__inr),
299*4c3eb207Smrg 		       ranges::begin(__outr), ranges::end(__outr));
300*4c3eb207Smrg       }
301*4c3eb207Smrg   };
302*4c3eb207Smrg 
303*4c3eb207Smrg   inline constexpr __uninitialized_copy_fn uninitialized_copy{};
304*4c3eb207Smrg 
305*4c3eb207Smrg   template<typename _Iter, typename _Out>
306*4c3eb207Smrg     using uninitialized_copy_n_result = in_out_result<_Iter, _Out>;
307*4c3eb207Smrg 
308*4c3eb207Smrg   struct __uninitialized_copy_n_fn
309*4c3eb207Smrg   {
310*4c3eb207Smrg     template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
311*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Out> _Sent>
312*4c3eb207Smrg       requires constructible_from<iter_value_t<_Out>, iter_reference_t<_Iter>>
313*4c3eb207Smrg       uninitialized_copy_n_result<_Iter, _Out>
314*4c3eb207Smrg       operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
315*4c3eb207Smrg 		 _Out __ofirst, _Sent __olast) const
316*4c3eb207Smrg       {
317*4c3eb207Smrg 	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
318*4c3eb207Smrg 	if constexpr (sized_sentinel_for<_Sent, _Out>
319*4c3eb207Smrg 		      && is_trivial_v<_OutType>
320*4c3eb207Smrg 		      && is_nothrow_assignable_v<_OutType&,
321*4c3eb207Smrg 						 iter_reference_t<_Iter>>)
322*4c3eb207Smrg 	  {
323*4c3eb207Smrg 	    auto __d = __olast - __ofirst;
324*4c3eb207Smrg 	    return ranges::copy_n(std::move(__ifirst), std::min(__n, __d),
325*4c3eb207Smrg 				  __ofirst);
326*4c3eb207Smrg 	  }
327*4c3eb207Smrg 	else
328*4c3eb207Smrg 	  {
329*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__ofirst);
330*4c3eb207Smrg 	    for (; __n > 0 && __ofirst != __olast;
331*4c3eb207Smrg 		 ++__ofirst, (void)++__ifirst, (void)--__n)
332*4c3eb207Smrg 	      ::new (__detail::__voidify(*__ofirst)) _OutType(*__ifirst);
333*4c3eb207Smrg 	    __guard.release();
334*4c3eb207Smrg 	    return {std::move(__ifirst), __ofirst};
335*4c3eb207Smrg 	  }
336*4c3eb207Smrg       }
337*4c3eb207Smrg   };
338*4c3eb207Smrg 
339*4c3eb207Smrg   inline constexpr __uninitialized_copy_n_fn uninitialized_copy_n{};
340*4c3eb207Smrg 
341*4c3eb207Smrg   template<typename _Iter, typename _Out>
342*4c3eb207Smrg     using uninitialized_move_result = in_out_result<_Iter, _Out>;
343*4c3eb207Smrg 
344*4c3eb207Smrg   struct __uninitialized_move_fn
345*4c3eb207Smrg   {
346*4c3eb207Smrg     template<input_iterator _Iter, sentinel_for<_Iter> _ISent,
347*4c3eb207Smrg 	     __detail::__nothrow_forward_iterator _Out,
348*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Out> _OSent>
349*4c3eb207Smrg       requires constructible_from<iter_value_t<_Out>,
350*4c3eb207Smrg 				  iter_rvalue_reference_t<_Iter>>
351*4c3eb207Smrg       uninitialized_move_result<_Iter, _Out>
352*4c3eb207Smrg       operator()(_Iter __ifirst, _ISent __ilast,
353*4c3eb207Smrg 		 _Out __ofirst, _OSent __olast) const
354*4c3eb207Smrg       {
355*4c3eb207Smrg 	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
356*4c3eb207Smrg 	if constexpr (sized_sentinel_for<_ISent, _Iter>
357*4c3eb207Smrg 		      && sized_sentinel_for<_OSent, _Out>
358*4c3eb207Smrg 		      && is_trivial_v<_OutType>
359*4c3eb207Smrg 		      && is_nothrow_assignable_v<_OutType&,
360*4c3eb207Smrg 						 iter_rvalue_reference_t<_Iter>>)
361*4c3eb207Smrg 	  {
362*4c3eb207Smrg 	    auto __d1 = __ilast - __ifirst;
363*4c3eb207Smrg 	    auto __d2 = __olast - __ofirst;
364*4c3eb207Smrg 	    auto [__in, __out]
365*4c3eb207Smrg 	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
366*4c3eb207Smrg 			       std::min(__d1, __d2), __ofirst);
367*4c3eb207Smrg 	    return {std::move(__in).base(), __out};
368*4c3eb207Smrg 	  }
369*4c3eb207Smrg 	else
370*4c3eb207Smrg 	  {
371*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__ofirst);
372*4c3eb207Smrg 	    for (; __ifirst != __ilast && __ofirst != __olast;
373*4c3eb207Smrg 		 ++__ofirst, (void)++__ifirst)
374*4c3eb207Smrg 	      ::new (__detail::__voidify(*__ofirst))
375*4c3eb207Smrg 		    _OutType(ranges::iter_move(__ifirst));
376*4c3eb207Smrg 	    __guard.release();
377*4c3eb207Smrg 	    return {std::move(__ifirst), __ofirst};
378*4c3eb207Smrg 	  }
379*4c3eb207Smrg       }
380*4c3eb207Smrg 
381*4c3eb207Smrg     template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
382*4c3eb207Smrg       requires constructible_from<range_value_t<_ORange>,
383*4c3eb207Smrg 	       range_rvalue_reference_t<_IRange>>
384*4c3eb207Smrg       uninitialized_move_result<borrowed_iterator_t<_IRange>,
385*4c3eb207Smrg 				borrowed_iterator_t<_ORange>>
386*4c3eb207Smrg       operator()(_IRange&& __inr, _ORange&& __outr) const
387*4c3eb207Smrg       {
388*4c3eb207Smrg 	return (*this)(ranges::begin(__inr), ranges::end(__inr),
389*4c3eb207Smrg 		       ranges::begin(__outr), ranges::end(__outr));
390*4c3eb207Smrg       }
391*4c3eb207Smrg   };
392*4c3eb207Smrg 
393*4c3eb207Smrg   inline constexpr __uninitialized_move_fn uninitialized_move{};
394*4c3eb207Smrg 
395*4c3eb207Smrg   template<typename _Iter, typename _Out>
396*4c3eb207Smrg     using uninitialized_move_n_result = in_out_result<_Iter, _Out>;
397*4c3eb207Smrg 
398*4c3eb207Smrg   struct __uninitialized_move_n_fn
399*4c3eb207Smrg   {
400*4c3eb207Smrg     template<input_iterator _Iter, __detail::__nothrow_forward_iterator _Out,
401*4c3eb207Smrg       __detail::__nothrow_sentinel<_Out> _Sent>
402*4c3eb207Smrg 	requires constructible_from<iter_value_t<_Out>,
403*4c3eb207Smrg 				    iter_rvalue_reference_t<_Iter>>
404*4c3eb207Smrg       uninitialized_move_n_result<_Iter, _Out>
405*4c3eb207Smrg       operator()(_Iter __ifirst, iter_difference_t<_Iter> __n,
406*4c3eb207Smrg 		 _Out __ofirst, _Sent __olast) const
407*4c3eb207Smrg       {
408*4c3eb207Smrg 	using _OutType = remove_reference_t<iter_reference_t<_Out>>;
409*4c3eb207Smrg 	if constexpr (sized_sentinel_for<_Sent, _Out>
410*4c3eb207Smrg 		      && is_trivial_v<_OutType>
411*4c3eb207Smrg 		      && is_nothrow_assignable_v<_OutType&,
412*4c3eb207Smrg 						 iter_rvalue_reference_t<_Iter>>)
413*4c3eb207Smrg 	  {
414*4c3eb207Smrg 	    auto __d = __olast - __ofirst;
415*4c3eb207Smrg 	    auto [__in, __out]
416*4c3eb207Smrg 	      = ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
417*4c3eb207Smrg 			       std::min(__n, __d), __ofirst);
418*4c3eb207Smrg 	    return {std::move(__in).base(), __out};
419*4c3eb207Smrg 	  }
420*4c3eb207Smrg 	else
421*4c3eb207Smrg 	  {
422*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__ofirst);
423*4c3eb207Smrg 	    for (; __n > 0 && __ofirst != __olast;
424*4c3eb207Smrg 		 ++__ofirst, (void)++__ifirst, (void)--__n)
425*4c3eb207Smrg 	      ::new (__detail::__voidify(*__ofirst))
426*4c3eb207Smrg 		    _OutType(ranges::iter_move(__ifirst));
427*4c3eb207Smrg 	    __guard.release();
428*4c3eb207Smrg 	    return {std::move(__ifirst), __ofirst};
429*4c3eb207Smrg 	  }
430*4c3eb207Smrg       }
431*4c3eb207Smrg   };
432*4c3eb207Smrg 
433*4c3eb207Smrg   inline constexpr __uninitialized_move_n_fn uninitialized_move_n{};
434*4c3eb207Smrg 
435*4c3eb207Smrg   struct __uninitialized_fill_fn
436*4c3eb207Smrg   {
437*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter,
438*4c3eb207Smrg 	     __detail::__nothrow_sentinel<_Iter> _Sent, typename _Tp>
439*4c3eb207Smrg       requires constructible_from<iter_value_t<_Iter>, const _Tp&>
440*4c3eb207Smrg       _Iter
441*4c3eb207Smrg       operator()(_Iter __first, _Sent __last, const _Tp& __x) const
442*4c3eb207Smrg       {
443*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
444*4c3eb207Smrg 	if constexpr (is_trivial_v<_ValueType>
445*4c3eb207Smrg 		      && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
446*4c3eb207Smrg 	  return ranges::fill(__first, __last, __x);
447*4c3eb207Smrg 	else
448*4c3eb207Smrg 	  {
449*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
450*4c3eb207Smrg 	    for (; __first != __last; ++__first)
451*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
452*4c3eb207Smrg 	    __guard.release();
453*4c3eb207Smrg 	    return __first;
454*4c3eb207Smrg 	  }
455*4c3eb207Smrg       }
456*4c3eb207Smrg 
457*4c3eb207Smrg     template<__detail::__nothrow_forward_range _Range, typename _Tp>
458*4c3eb207Smrg       requires constructible_from<range_value_t<_Range>, const _Tp&>
459*4c3eb207Smrg       borrowed_iterator_t<_Range>
460*4c3eb207Smrg       operator()(_Range&& __r, const _Tp& __x) const
461*4c3eb207Smrg       {
462*4c3eb207Smrg 	return (*this)(ranges::begin(__r), ranges::end(__r), __x);
463*4c3eb207Smrg       }
464*4c3eb207Smrg   };
465*4c3eb207Smrg 
466*4c3eb207Smrg   inline constexpr __uninitialized_fill_fn uninitialized_fill{};
467*4c3eb207Smrg 
468*4c3eb207Smrg   struct __uninitialized_fill_n_fn
469*4c3eb207Smrg   {
470*4c3eb207Smrg     template<__detail::__nothrow_forward_iterator _Iter, typename _Tp>
471*4c3eb207Smrg       requires constructible_from<iter_value_t<_Iter>, const _Tp&>
472*4c3eb207Smrg       _Iter
473*4c3eb207Smrg       operator()(_Iter __first, iter_difference_t<_Iter> __n,
474*4c3eb207Smrg 		 const _Tp& __x) const
475*4c3eb207Smrg       {
476*4c3eb207Smrg 	using _ValueType = remove_reference_t<iter_reference_t<_Iter>>;
477*4c3eb207Smrg 	if constexpr (is_trivial_v<_ValueType>
478*4c3eb207Smrg 		      && is_nothrow_assignable_v<_ValueType&, const _Tp&>)
479*4c3eb207Smrg 	  return ranges::fill_n(__first, __n, __x);
480*4c3eb207Smrg 	else
481*4c3eb207Smrg 	  {
482*4c3eb207Smrg 	    auto __guard = __detail::_DestroyGuard(__first);
483*4c3eb207Smrg 	    for (; __n > 0; ++__first, (void)--__n)
484*4c3eb207Smrg 	      ::new (__detail::__voidify(*__first)) _ValueType(__x);
485*4c3eb207Smrg 	    __guard.release();
486*4c3eb207Smrg 	    return __first;
487*4c3eb207Smrg 	  }
488*4c3eb207Smrg       }
489*4c3eb207Smrg   };
490*4c3eb207Smrg 
491*4c3eb207Smrg   inline constexpr __uninitialized_fill_n_fn uninitialized_fill_n{};
492*4c3eb207Smrg 
493*4c3eb207Smrg   struct __construct_at_fn
494*4c3eb207Smrg   {
495*4c3eb207Smrg     template<typename _Tp, typename... _Args>
496*4c3eb207Smrg       requires requires {
497*4c3eb207Smrg 	::new (std::declval<void*>()) _Tp(std::declval<_Args>()...);
498*4c3eb207Smrg       }
499*4c3eb207Smrg       constexpr _Tp*
500*4c3eb207Smrg       operator()(_Tp* __location, _Args&&... __args) const
501*4c3eb207Smrg       noexcept(noexcept(std::construct_at(__location,
502*4c3eb207Smrg 					  std::forward<_Args>(__args)...)))
503*4c3eb207Smrg       {
504*4c3eb207Smrg 	return std::construct_at(__location,
505*4c3eb207Smrg 				 std::forward<_Args>(__args)...);
506*4c3eb207Smrg       }
507*4c3eb207Smrg   };
508*4c3eb207Smrg 
509*4c3eb207Smrg   inline constexpr __construct_at_fn construct_at{};
510*4c3eb207Smrg 
511*4c3eb207Smrg   struct __destroy_at_fn
512*4c3eb207Smrg   {
513*4c3eb207Smrg     template<destructible _Tp>
514*4c3eb207Smrg       constexpr void
515*4c3eb207Smrg       operator()(_Tp* __location) const noexcept
516*4c3eb207Smrg       {
517*4c3eb207Smrg 	if constexpr (is_array_v<_Tp>)
518*4c3eb207Smrg 	  ranges::destroy(ranges::begin(*__location), ranges::end(*__location));
519*4c3eb207Smrg 	else
520*4c3eb207Smrg 	  __location->~_Tp();
521*4c3eb207Smrg       }
522*4c3eb207Smrg   };
523*4c3eb207Smrg 
524*4c3eb207Smrg   inline constexpr __destroy_at_fn destroy_at{};
525*4c3eb207Smrg 
526*4c3eb207Smrg   template<__detail::__nothrow_input_iterator _Iter,
527*4c3eb207Smrg 	   __detail::__nothrow_sentinel<_Iter> _Sent>
528*4c3eb207Smrg     requires destructible<iter_value_t<_Iter>>
529*4c3eb207Smrg     constexpr _Iter
530*4c3eb207Smrg     __destroy_fn::operator()(_Iter __first, _Sent __last) const noexcept
531*4c3eb207Smrg     {
532*4c3eb207Smrg       if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
533*4c3eb207Smrg 	return ranges::next(std::move(__first), __last);
534*4c3eb207Smrg       else
535*4c3eb207Smrg 	{
536*4c3eb207Smrg 	  for (; __first != __last; ++__first)
537*4c3eb207Smrg 	    ranges::destroy_at(std::__addressof(*__first));
538*4c3eb207Smrg 	  return __first;
539*4c3eb207Smrg 	}
540*4c3eb207Smrg     }
541*4c3eb207Smrg 
542*4c3eb207Smrg   template<__detail::__nothrow_input_range _Range>
543*4c3eb207Smrg     requires destructible<range_value_t<_Range>>
544*4c3eb207Smrg     constexpr borrowed_iterator_t<_Range>
545*4c3eb207Smrg     __destroy_fn::operator()(_Range&& __r) const noexcept
546*4c3eb207Smrg     {
547*4c3eb207Smrg       return (*this)(ranges::begin(__r), ranges::end(__r));
548*4c3eb207Smrg     }
549*4c3eb207Smrg 
550*4c3eb207Smrg   struct __destroy_n_fn
551*4c3eb207Smrg   {
552*4c3eb207Smrg     template<__detail::__nothrow_input_iterator _Iter>
553*4c3eb207Smrg       requires destructible<iter_value_t<_Iter>>
554*4c3eb207Smrg       constexpr _Iter
555*4c3eb207Smrg       operator()(_Iter __first, iter_difference_t<_Iter> __n) const noexcept
556*4c3eb207Smrg       {
557*4c3eb207Smrg 	if constexpr (is_trivially_destructible_v<iter_value_t<_Iter>>)
558*4c3eb207Smrg 	  return ranges::next(std::move(__first), __n);
559*4c3eb207Smrg 	else
560*4c3eb207Smrg 	  {
561*4c3eb207Smrg 	    for (; __n > 0; ++__first, (void)--__n)
562*4c3eb207Smrg 	      ranges::destroy_at(std::__addressof(*__first));
563*4c3eb207Smrg 	    return __first;
564*4c3eb207Smrg 	  }
565*4c3eb207Smrg       }
566*4c3eb207Smrg   };
567*4c3eb207Smrg 
568*4c3eb207Smrg   inline constexpr __destroy_n_fn destroy_n{};
569*4c3eb207Smrg }
570*4c3eb207Smrg _GLIBCXX_END_NAMESPACE_VERSION
571*4c3eb207Smrg } // namespace std
572*4c3eb207Smrg #endif // concepts
573*4c3eb207Smrg #endif // C++20
574*4c3eb207Smrg #endif // _RANGES_UNINITIALIZED_H
575