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