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