libstdc++
stl_uninitialized.h
Go to the documentation of this file.
1 // Raw memory manipulators -*- C++ -*-
2 
3 // Copyright (C) 2001-2024 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 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996,1997
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
51 /** @file bits/stl_uninitialized.h
52  * This is an internal header file, included by other library headers.
53  * Do not attempt to use it directly. @headername{memory}
54  */
55 
56 #ifndef _STL_UNINITIALIZED_H
57 #define _STL_UNINITIALIZED_H 1
58 
59 #if __cplusplus >= 201103L
60 #include <type_traits>
61 #endif
62 
63 #include <bits/stl_algobase.h> // copy
64 #include <ext/alloc_traits.h> // __alloc_traits
65 
66 #if __cplusplus >= 201703L
67 #include <bits/stl_pair.h>
68 #endif
69 
70 namespace std _GLIBCXX_VISIBILITY(default)
71 {
72 _GLIBCXX_BEGIN_NAMESPACE_VERSION
73 
74  /** @addtogroup memory
75  * @{
76  */
77 
78  /// @cond undocumented
79 
80 #if __cplusplus >= 201103L
81  template<typename _ValueType, typename _Tp>
82  constexpr bool
83  __check_constructible()
84  {
85  // Trivial types can have deleted constructors, but std::copy etc.
86  // only use assignment (or memmove) not construction, so we need an
87  // explicit check that construction from _Tp is actually valid,
88  // otherwise some ill-formed uses of std::uninitialized_xxx would
89  // compile without errors. This gives a nice clear error message.
90  static_assert(is_constructible<_ValueType, _Tp>::value,
91  "result type must be constructible from input type");
92 
93  return true;
94  }
95 
96 // If the type is trivial we don't need to construct it, just assign to it.
97 // But trivial types can still have deleted or inaccessible assignment,
98 // so don't try to use std::copy or std::fill etc. if we can't assign.
99 # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
100  __is_trivial(T) && __is_assignable(T&, U) \
101  && std::__check_constructible<T, U>()
102 #else
103 // No need to check if is_constructible<T, U> for C++98. Trivial types have
104 // no user-declared constructors, so if the assignment is valid, construction
105 // should be too.
106 # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \
107  __is_trivial(T) && __is_assignable(T&, U)
108 #endif
109 
110  template<typename _InputIterator, typename _ForwardIterator>
111  _GLIBCXX20_CONSTEXPR
112  _ForwardIterator
113  __do_uninit_copy(_InputIterator __first, _InputIterator __last,
114  _ForwardIterator __result)
115  {
116  _ForwardIterator __cur = __result;
117  __try
118  {
119  for (; __first != __last; ++__first, (void)++__cur)
120  std::_Construct(std::__addressof(*__cur), *__first);
121  return __cur;
122  }
123  __catch(...)
124  {
125  std::_Destroy(__result, __cur);
126  __throw_exception_again;
127  }
128  }
129 
130  template<bool _TrivialValueTypes>
131  struct __uninitialized_copy
132  {
133  template<typename _InputIterator, typename _ForwardIterator>
134  static _ForwardIterator
135  __uninit_copy(_InputIterator __first, _InputIterator __last,
136  _ForwardIterator __result)
137  { return std::__do_uninit_copy(__first, __last, __result); }
138  };
139 
140  template<>
141  struct __uninitialized_copy<true>
142  {
143  template<typename _InputIterator, typename _ForwardIterator>
144  static _ForwardIterator
145  __uninit_copy(_InputIterator __first, _InputIterator __last,
146  _ForwardIterator __result)
147  { return std::copy(__first, __last, __result); }
148  };
149 
150  /// @endcond
151 
152  /**
153  * @brief Copies the range [first,last) into result.
154  * @param __first An input iterator.
155  * @param __last An input iterator.
156  * @param __result An output iterator.
157  * @return __result + (__first - __last)
158  *
159  * Like copy(), but does not require an initialized output range.
160  */
161  template<typename _InputIterator, typename _ForwardIterator>
162  inline _ForwardIterator
163  uninitialized_copy(_InputIterator __first, _InputIterator __last,
164  _ForwardIterator __result)
165  {
167  _ValueType1;
169  _ValueType2;
170 
171  // _ValueType1 must be trivially-copyable to use memmove, so don't
172  // bother optimizing to std::copy if it isn't.
173  // XXX Unnecessary because std::copy would check it anyway?
174  const bool __can_memmove = __is_trivial(_ValueType1);
175 
176 #if __cplusplus < 201103L
177  typedef typename iterator_traits<_InputIterator>::reference _From;
178 #else
179  using _From = decltype(*__first);
180 #endif
181  const bool __assignable
182  = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From);
183 
184  return std::__uninitialized_copy<__can_memmove && __assignable>::
185  __uninit_copy(__first, __last, __result);
186  }
187 
188  /// @cond undocumented
189 
190  template<typename _ForwardIterator, typename _Tp>
191  _GLIBCXX20_CONSTEXPR void
192  __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
193  const _Tp& __x)
194  {
195  _ForwardIterator __cur = __first;
196  __try
197  {
198  for (; __cur != __last; ++__cur)
199  std::_Construct(std::__addressof(*__cur), __x);
200  }
201  __catch(...)
202  {
203  std::_Destroy(__first, __cur);
204  __throw_exception_again;
205  }
206  }
207 
208  template<bool _TrivialValueType>
209  struct __uninitialized_fill
210  {
211  template<typename _ForwardIterator, typename _Tp>
212  static void
213  __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
214  const _Tp& __x)
215  { std::__do_uninit_fill(__first, __last, __x); }
216  };
217 
218  template<>
219  struct __uninitialized_fill<true>
220  {
221  template<typename _ForwardIterator, typename _Tp>
222  static void
223  __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
224  const _Tp& __x)
225  { std::fill(__first, __last, __x); }
226  };
227 
228  /// @endcond
229 
230  /**
231  * @brief Copies the value x into the range [first,last).
232  * @param __first An input iterator.
233  * @param __last An input iterator.
234  * @param __x The source value.
235  * @return Nothing.
236  *
237  * Like fill(), but does not require an initialized output range.
238  */
239  template<typename _ForwardIterator, typename _Tp>
240  inline void
241  uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
242  const _Tp& __x)
243  {
245  _ValueType;
246 
247  // Trivial types do not need a constructor to begin their lifetime,
248  // so try to use std::fill to benefit from its memset optimization.
249  const bool __can_fill
250  = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&);
251 
252  std::__uninitialized_fill<__can_fill>::
253  __uninit_fill(__first, __last, __x);
254  }
255 
256  /// @cond undocumented
257 
258  template<typename _ForwardIterator, typename _Size, typename _Tp>
259  _GLIBCXX20_CONSTEXPR
260  _ForwardIterator
261  __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
262  {
263  _ForwardIterator __cur = __first;
264  __try
265  {
266  for (; __n > 0; --__n, (void) ++__cur)
267  std::_Construct(std::__addressof(*__cur), __x);
268  return __cur;
269  }
270  __catch(...)
271  {
272  std::_Destroy(__first, __cur);
273  __throw_exception_again;
274  }
275  }
276 
277  template<bool _TrivialValueType>
278  struct __uninitialized_fill_n
279  {
280  template<typename _ForwardIterator, typename _Size, typename _Tp>
281  static _ForwardIterator
282  __uninit_fill_n(_ForwardIterator __first, _Size __n,
283  const _Tp& __x)
284  { return std::__do_uninit_fill_n(__first, __n, __x); }
285  };
286 
287  template<>
288  struct __uninitialized_fill_n<true>
289  {
290  template<typename _ForwardIterator, typename _Size, typename _Tp>
291  static _ForwardIterator
292  __uninit_fill_n(_ForwardIterator __first, _Size __n,
293  const _Tp& __x)
294  { return std::fill_n(__first, __n, __x); }
295  };
296 
297  /// @endcond
298 
299  // _GLIBCXX_RESOLVE_LIB_DEFECTS
300  // DR 1339. uninitialized_fill_n should return the end of its range
301  /**
302  * @brief Copies the value x into the range [first,first+n).
303  * @param __first An input iterator.
304  * @param __n The number of copies to make.
305  * @param __x The source value.
306  * @return Nothing.
307  *
308  * Like fill_n(), but does not require an initialized output range.
309  */
310  template<typename _ForwardIterator, typename _Size, typename _Tp>
311  inline _ForwardIterator
312  uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
313  {
315  _ValueType;
316 
317  // Trivial types do not need a constructor to begin their lifetime,
318  // so try to use std::fill_n to benefit from its optimizations.
319  const bool __can_fill
320  = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&)
321  // For arbitrary class types and floating point types we can't assume
322  // that __n > 0 and std::__size_to_integer(__n) > 0 are equivalent,
323  // so only use std::fill_n when _Size is already an integral type.
324  && __is_integer<_Size>::__value;
325 
326  return __uninitialized_fill_n<__can_fill>::
327  __uninit_fill_n(__first, __n, __x);
328  }
329 
330 #undef _GLIBCXX_USE_ASSIGN_FOR_INIT
331 
332  /// @cond undocumented
333 
334  // Extensions: versions of uninitialized_copy, uninitialized_fill,
335  // and uninitialized_fill_n that take an allocator parameter.
336  // We dispatch back to the standard versions when we're given the
337  // default allocator. For nondefault allocators we do not use
338  // any of the POD optimizations.
339 
340  template<typename _InputIterator, typename _ForwardIterator,
341  typename _Allocator>
342  _GLIBCXX20_CONSTEXPR
343  _ForwardIterator
344  __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
345  _ForwardIterator __result, _Allocator& __alloc)
346  {
347  _ForwardIterator __cur = __result;
348  __try
349  {
350  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
351  for (; __first != __last; ++__first, (void)++__cur)
352  __traits::construct(__alloc, std::__addressof(*__cur), *__first);
353  return __cur;
354  }
355  __catch(...)
356  {
357  std::_Destroy(__result, __cur, __alloc);
358  __throw_exception_again;
359  }
360  }
361 
362 #if _GLIBCXX_HOSTED
363  template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
364  _GLIBCXX20_CONSTEXPR
365  inline _ForwardIterator
366  __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
367  _ForwardIterator __result, allocator<_Tp>&)
368  {
369 #ifdef __cpp_lib_is_constant_evaluated
370  if (std::is_constant_evaluated())
371  return std::__do_uninit_copy(__first, __last, __result);
372 #endif
373  return std::uninitialized_copy(__first, __last, __result);
374  }
375 #endif
376 
377  template<typename _InputIterator, typename _ForwardIterator,
378  typename _Allocator>
379  _GLIBCXX20_CONSTEXPR
380  inline _ForwardIterator
381  __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
382  _ForwardIterator __result, _Allocator& __alloc)
383  {
384  return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
385  _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
386  __result, __alloc);
387  }
388 
389  template<typename _InputIterator, typename _ForwardIterator,
390  typename _Allocator>
391  _GLIBCXX20_CONSTEXPR
392  inline _ForwardIterator
393  __uninitialized_move_if_noexcept_a(_InputIterator __first,
394  _InputIterator __last,
395  _ForwardIterator __result,
396  _Allocator& __alloc)
397  {
398  return std::__uninitialized_copy_a
399  (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
400  _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
401  }
402 
403  template<typename _ForwardIterator, typename _Tp, typename _Allocator>
404  _GLIBCXX20_CONSTEXPR
405  void
406  __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
407  const _Tp& __x, _Allocator& __alloc)
408  {
409  _ForwardIterator __cur = __first;
410  __try
411  {
412  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
413  for (; __cur != __last; ++__cur)
414  __traits::construct(__alloc, std::__addressof(*__cur), __x);
415  }
416  __catch(...)
417  {
418  std::_Destroy(__first, __cur, __alloc);
419  __throw_exception_again;
420  }
421  }
422 
423 #if _GLIBCXX_HOSTED
424  template<typename _ForwardIterator, typename _Tp, typename _Tp2>
425  _GLIBCXX20_CONSTEXPR
426  inline void
427  __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
428  const _Tp& __x, allocator<_Tp2>&)
429  {
430 #ifdef __cpp_lib_is_constant_evaluated
431  if (std::is_constant_evaluated())
432  return std::__do_uninit_fill(__first, __last, __x);
433 #endif
434  std::uninitialized_fill(__first, __last, __x);
435  }
436 #endif
437 
438  template<typename _ForwardIterator, typename _Size, typename _Tp,
439  typename _Allocator>
440  _GLIBCXX20_CONSTEXPR
441  _ForwardIterator
442  __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
443  const _Tp& __x, _Allocator& __alloc)
444  {
445  _ForwardIterator __cur = __first;
446  __try
447  {
448  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
449  for (; __n > 0; --__n, (void) ++__cur)
450  __traits::construct(__alloc, std::__addressof(*__cur), __x);
451  return __cur;
452  }
453  __catch(...)
454  {
455  std::_Destroy(__first, __cur, __alloc);
456  __throw_exception_again;
457  }
458  }
459 
460 #if _GLIBCXX_HOSTED
461  template<typename _ForwardIterator, typename _Size, typename _Tp,
462  typename _Tp2>
463  _GLIBCXX20_CONSTEXPR
464  inline _ForwardIterator
465  __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
466  const _Tp& __x, allocator<_Tp2>&)
467  {
468 #ifdef __cpp_lib_is_constant_evaluated
469  if (std::is_constant_evaluated())
470  return std::__do_uninit_fill_n(__first, __n, __x);
471 #endif
472  return std::uninitialized_fill_n(__first, __n, __x);
473  }
474 #endif
475 
476  // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
477  // __uninitialized_fill_move, __uninitialized_move_fill.
478  // All of these algorithms take a user-supplied allocator, which is used
479  // for construction and destruction.
480 
481  // __uninitialized_copy_move
482  // Copies [first1, last1) into [result, result + (last1 - first1)), and
483  // move [first2, last2) into
484  // [result, result + (last1 - first1) + (last2 - first2)).
485  template<typename _InputIterator1, typename _InputIterator2,
486  typename _ForwardIterator, typename _Allocator>
487  inline _ForwardIterator
488  __uninitialized_copy_move(_InputIterator1 __first1,
489  _InputIterator1 __last1,
490  _InputIterator2 __first2,
491  _InputIterator2 __last2,
492  _ForwardIterator __result,
493  _Allocator& __alloc)
494  {
495  _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
496  __result,
497  __alloc);
498  __try
499  {
500  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
501  }
502  __catch(...)
503  {
504  std::_Destroy(__result, __mid, __alloc);
505  __throw_exception_again;
506  }
507  }
508 
509  // __uninitialized_move_copy
510  // Moves [first1, last1) into [result, result + (last1 - first1)), and
511  // copies [first2, last2) into
512  // [result, result + (last1 - first1) + (last2 - first2)).
513  template<typename _InputIterator1, typename _InputIterator2,
514  typename _ForwardIterator, typename _Allocator>
515  inline _ForwardIterator
516  __uninitialized_move_copy(_InputIterator1 __first1,
517  _InputIterator1 __last1,
518  _InputIterator2 __first2,
519  _InputIterator2 __last2,
520  _ForwardIterator __result,
521  _Allocator& __alloc)
522  {
523  _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
524  __result,
525  __alloc);
526  __try
527  {
528  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
529  }
530  __catch(...)
531  {
532  std::_Destroy(__result, __mid, __alloc);
533  __throw_exception_again;
534  }
535  }
536 
537  // __uninitialized_fill_move
538  // Fills [result, mid) with x, and moves [first, last) into
539  // [mid, mid + (last - first)).
540  template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
541  typename _Allocator>
542  inline _ForwardIterator
543  __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
544  const _Tp& __x, _InputIterator __first,
545  _InputIterator __last, _Allocator& __alloc)
546  {
547  std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
548  __try
549  {
550  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
551  }
552  __catch(...)
553  {
554  std::_Destroy(__result, __mid, __alloc);
555  __throw_exception_again;
556  }
557  }
558 
559  // __uninitialized_move_fill
560  // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
561  // fills [first2 + (last1 - first1), last2) with x.
562  template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
563  typename _Allocator>
564  inline void
565  __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
566  _ForwardIterator __first2,
567  _ForwardIterator __last2, const _Tp& __x,
568  _Allocator& __alloc)
569  {
570  _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
571  __first2,
572  __alloc);
573  __try
574  {
575  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
576  }
577  __catch(...)
578  {
579  std::_Destroy(__first2, __mid2, __alloc);
580  __throw_exception_again;
581  }
582  }
583 
584  /// @endcond
585 
586 #if __cplusplus >= 201103L
587  /// @cond undocumented
588 
589  // Extensions: __uninitialized_default, __uninitialized_default_n,
590  // __uninitialized_default_a, __uninitialized_default_n_a.
591 
592  template<bool _TrivialValueType>
593  struct __uninitialized_default_1
594  {
595  template<typename _ForwardIterator>
596  static void
597  __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
598  {
599  _ForwardIterator __cur = __first;
600  __try
601  {
602  for (; __cur != __last; ++__cur)
604  }
605  __catch(...)
606  {
607  std::_Destroy(__first, __cur);
608  __throw_exception_again;
609  }
610  }
611  };
612 
613  template<>
614  struct __uninitialized_default_1<true>
615  {
616  template<typename _ForwardIterator>
617  static void
618  __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
619  {
620  if (__first == __last)
621  return;
622 
623  typename iterator_traits<_ForwardIterator>::value_type* __val
624  = std::__addressof(*__first);
625  std::_Construct(__val);
626  if (++__first != __last)
627  std::fill(__first, __last, *__val);
628  }
629  };
630 
631  template<bool _TrivialValueType>
632  struct __uninitialized_default_n_1
633  {
634  template<typename _ForwardIterator, typename _Size>
635  _GLIBCXX20_CONSTEXPR
636  static _ForwardIterator
637  __uninit_default_n(_ForwardIterator __first, _Size __n)
638  {
639  _ForwardIterator __cur = __first;
640  __try
641  {
642  for (; __n > 0; --__n, (void) ++__cur)
644  return __cur;
645  }
646  __catch(...)
647  {
648  std::_Destroy(__first, __cur);
649  __throw_exception_again;
650  }
651  }
652  };
653 
654  template<>
655  struct __uninitialized_default_n_1<true>
656  {
657  template<typename _ForwardIterator, typename _Size>
658  _GLIBCXX20_CONSTEXPR
659  static _ForwardIterator
660  __uninit_default_n(_ForwardIterator __first, _Size __n)
661  {
662  if (__n > 0)
663  {
664  typename iterator_traits<_ForwardIterator>::value_type* __val
665  = std::__addressof(*__first);
666  std::_Construct(__val);
667  ++__first;
668  __first = std::fill_n(__first, __n - 1, *__val);
669  }
670  return __first;
671  }
672  };
673 
674  // __uninitialized_default
675  // Fills [first, last) with value-initialized value_types.
676  template<typename _ForwardIterator>
677  inline void
678  __uninitialized_default(_ForwardIterator __first,
679  _ForwardIterator __last)
680  {
681  typedef typename iterator_traits<_ForwardIterator>::value_type
682  _ValueType;
683  // trivial types can have deleted assignment
684  const bool __assignable = is_copy_assignable<_ValueType>::value;
685 
686  std::__uninitialized_default_1<__is_trivial(_ValueType)
687  && __assignable>::
688  __uninit_default(__first, __last);
689  }
690 
691  // __uninitialized_default_n
692  // Fills [first, first + n) with value-initialized value_types.
693  template<typename _ForwardIterator, typename _Size>
694  _GLIBCXX20_CONSTEXPR
695  inline _ForwardIterator
696  __uninitialized_default_n(_ForwardIterator __first, _Size __n)
697  {
698 #ifdef __cpp_lib_is_constant_evaluated
699  if (std::is_constant_evaluated())
700  return __uninitialized_default_n_1<false>::
701  __uninit_default_n(__first, __n);
702 #endif
703 
704  typedef typename iterator_traits<_ForwardIterator>::value_type
705  _ValueType;
706  // See uninitialized_fill_n for the conditions for using std::fill_n.
707  constexpr bool __can_fill
708  = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value;
709 
710  return __uninitialized_default_n_1<__is_trivial(_ValueType)
711  && __can_fill>::
712  __uninit_default_n(__first, __n);
713  }
714 
715 
716  // __uninitialized_default_a
717  // Fills [first, last) with value_types constructed by the allocator
718  // alloc, with no arguments passed to the construct call.
719  template<typename _ForwardIterator, typename _Allocator>
720  void
721  __uninitialized_default_a(_ForwardIterator __first,
722  _ForwardIterator __last,
723  _Allocator& __alloc)
724  {
725  _ForwardIterator __cur = __first;
726  __try
727  {
728  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
729  for (; __cur != __last; ++__cur)
730  __traits::construct(__alloc, std::__addressof(*__cur));
731  }
732  __catch(...)
733  {
734  std::_Destroy(__first, __cur, __alloc);
735  __throw_exception_again;
736  }
737  }
738 
739 #if _GLIBCXX_HOSTED
740  template<typename _ForwardIterator, typename _Tp>
741  inline void
742  __uninitialized_default_a(_ForwardIterator __first,
743  _ForwardIterator __last,
744  allocator<_Tp>&)
745  { std::__uninitialized_default(__first, __last); }
746 #endif
747 
748  // __uninitialized_default_n_a
749  // Fills [first, first + n) with value_types constructed by the allocator
750  // alloc, with no arguments passed to the construct call.
751  template<typename _ForwardIterator, typename _Size, typename _Allocator>
752  _GLIBCXX20_CONSTEXPR _ForwardIterator
753  __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
754  _Allocator& __alloc)
755  {
756  _ForwardIterator __cur = __first;
757  __try
758  {
759  typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
760  for (; __n > 0; --__n, (void) ++__cur)
761  __traits::construct(__alloc, std::__addressof(*__cur));
762  return __cur;
763  }
764  __catch(...)
765  {
766  std::_Destroy(__first, __cur, __alloc);
767  __throw_exception_again;
768  }
769  }
770 
771 #if _GLIBCXX_HOSTED
772  // __uninitialized_default_n_a specialization for std::allocator,
773  // which ignores the allocator and value-initializes the elements.
774  template<typename _ForwardIterator, typename _Size, typename _Tp>
775  _GLIBCXX20_CONSTEXPR
776  inline _ForwardIterator
777  __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
778  allocator<_Tp>&)
779  { return std::__uninitialized_default_n(__first, __n); }
780 #endif
781 
782  template<bool _TrivialValueType>
783  struct __uninitialized_default_novalue_1
784  {
785  template<typename _ForwardIterator>
786  static void
787  __uninit_default_novalue(_ForwardIterator __first,
788  _ForwardIterator __last)
789  {
790  _ForwardIterator __cur = __first;
791  __try
792  {
793  for (; __cur != __last; ++__cur)
794  std::_Construct_novalue(std::__addressof(*__cur));
795  }
796  __catch(...)
797  {
798  std::_Destroy(__first, __cur);
799  __throw_exception_again;
800  }
801  }
802  };
803 
804  template<>
805  struct __uninitialized_default_novalue_1<true>
806  {
807  template<typename _ForwardIterator>
808  static void
809  __uninit_default_novalue(_ForwardIterator, _ForwardIterator)
810  {
811  }
812  };
813 
814  template<bool _TrivialValueType>
815  struct __uninitialized_default_novalue_n_1
816  {
817  template<typename _ForwardIterator, typename _Size>
818  static _ForwardIterator
819  __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
820  {
821  _ForwardIterator __cur = __first;
822  __try
823  {
824  for (; __n > 0; --__n, (void) ++__cur)
825  std::_Construct_novalue(std::__addressof(*__cur));
826  return __cur;
827  }
828  __catch(...)
829  {
830  std::_Destroy(__first, __cur);
831  __throw_exception_again;
832  }
833  }
834  };
835 
836  template<>
837  struct __uninitialized_default_novalue_n_1<true>
838  {
839  template<typename _ForwardIterator, typename _Size>
840  static _ForwardIterator
841  __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
842  { return std::next(__first, __n); }
843  };
844 
845  // __uninitialized_default_novalue
846  // Fills [first, last) with default-initialized value_types.
847  template<typename _ForwardIterator>
848  inline void
849  __uninitialized_default_novalue(_ForwardIterator __first,
850  _ForwardIterator __last)
851  {
852  typedef typename iterator_traits<_ForwardIterator>::value_type
853  _ValueType;
854 
855  std::__uninitialized_default_novalue_1<
856  is_trivially_default_constructible<_ValueType>::value>::
857  __uninit_default_novalue(__first, __last);
858  }
859 
860  // __uninitialized_default_novalue_n
861  // Fills [first, first + n) with default-initialized value_types.
862  template<typename _ForwardIterator, typename _Size>
863  inline _ForwardIterator
864  __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
865  {
866  typedef typename iterator_traits<_ForwardIterator>::value_type
867  _ValueType;
868 
869  return __uninitialized_default_novalue_n_1<
870  is_trivially_default_constructible<_ValueType>::value>::
871  __uninit_default_novalue_n(__first, __n);
872  }
873 
874  template<typename _InputIterator, typename _Size,
875  typename _ForwardIterator>
876  _ForwardIterator
877  __uninitialized_copy_n(_InputIterator __first, _Size __n,
878  _ForwardIterator __result, input_iterator_tag)
879  {
880  _ForwardIterator __cur = __result;
881  __try
882  {
883  for (; __n > 0; --__n, (void) ++__first, ++__cur)
884  std::_Construct(std::__addressof(*__cur), *__first);
885  return __cur;
886  }
887  __catch(...)
888  {
889  std::_Destroy(__result, __cur);
890  __throw_exception_again;
891  }
892  }
893 
894  template<typename _RandomAccessIterator, typename _Size,
895  typename _ForwardIterator>
896  inline _ForwardIterator
897  __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
898  _ForwardIterator __result,
899  random_access_iterator_tag)
900  { return std::uninitialized_copy(__first, __first + __n, __result); }
901 
902  template<typename _InputIterator, typename _Size,
903  typename _ForwardIterator>
904  pair<_InputIterator, _ForwardIterator>
905  __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
906  _ForwardIterator __result, input_iterator_tag)
907  {
908  _ForwardIterator __cur = __result;
909  __try
910  {
911  for (; __n > 0; --__n, (void) ++__first, ++__cur)
912  std::_Construct(std::__addressof(*__cur), *__first);
913  return {__first, __cur};
914  }
915  __catch(...)
916  {
917  std::_Destroy(__result, __cur);
918  __throw_exception_again;
919  }
920  }
921 
922  template<typename _RandomAccessIterator, typename _Size,
923  typename _ForwardIterator>
924  inline pair<_RandomAccessIterator, _ForwardIterator>
925  __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
926  _ForwardIterator __result,
927  random_access_iterator_tag)
928  {
929  auto __second_res = uninitialized_copy(__first, __first + __n, __result);
930  auto __first_res = std::next(__first, __n);
931  return {__first_res, __second_res};
932  }
933 
934  /// @endcond
935 
936  /**
937  * @brief Copies the range [first,first+n) into result.
938  * @param __first An input iterator.
939  * @param __n The number of elements to copy.
940  * @param __result An output iterator.
941  * @return __result + __n
942  * @since C++11
943  *
944  * Like copy_n(), but does not require an initialized output range.
945  */
946  template<typename _InputIterator, typename _Size, typename _ForwardIterator>
947  inline _ForwardIterator
948  uninitialized_copy_n(_InputIterator __first, _Size __n,
949  _ForwardIterator __result)
950  { return std::__uninitialized_copy_n(__first, __n, __result,
951  std::__iterator_category(__first)); }
952 
953  /// @cond undocumented
954  template<typename _InputIterator, typename _Size, typename _ForwardIterator>
955  inline pair<_InputIterator, _ForwardIterator>
956  __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
957  _ForwardIterator __result)
958  {
959  return
960  std::__uninitialized_copy_n_pair(__first, __n, __result,
961  std::__iterator_category(__first));
962  }
963  /// @endcond
964 #endif
965 
966 #ifdef __glibcxx_raw_memory_algorithms // C++ >= 17
967  /**
968  * @brief Default-initializes objects in the range [first,last).
969  * @param __first A forward iterator.
970  * @param __last A forward iterator.
971  * @since C++17
972  */
973  template <typename _ForwardIterator>
974  inline void
975  uninitialized_default_construct(_ForwardIterator __first,
976  _ForwardIterator __last)
977  {
978  __uninitialized_default_novalue(__first, __last);
979  }
980 
981  /**
982  * @brief Default-initializes objects in the range [first,first+count).
983  * @param __first A forward iterator.
984  * @param __count The number of objects to construct.
985  * @return __first + __count
986  * @since C++17
987  */
988  template <typename _ForwardIterator, typename _Size>
989  inline _ForwardIterator
990  uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
991  {
992  return __uninitialized_default_novalue_n(__first, __count);
993  }
994 
995  /**
996  * @brief Value-initializes objects in the range [first,last).
997  * @param __first A forward iterator.
998  * @param __last A forward iterator.
999  * @since C++17
1000  */
1001  template <typename _ForwardIterator>
1002  inline void
1003  uninitialized_value_construct(_ForwardIterator __first,
1004  _ForwardIterator __last)
1005  {
1006  return __uninitialized_default(__first, __last);
1007  }
1008 
1009  /**
1010  * @brief Value-initializes objects in the range [first,first+count).
1011  * @param __first A forward iterator.
1012  * @param __count The number of objects to construct.
1013  * @return __result + __count
1014  * @since C++17
1015  */
1016  template <typename _ForwardIterator, typename _Size>
1017  inline _ForwardIterator
1018  uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
1019  {
1020  return __uninitialized_default_n(__first, __count);
1021  }
1022 
1023  /**
1024  * @brief Move-construct from the range [first,last) into result.
1025  * @param __first An input iterator.
1026  * @param __last An input iterator.
1027  * @param __result An output iterator.
1028  * @return __result + (__first - __last)
1029  * @since C++17
1030  */
1031  template <typename _InputIterator, typename _ForwardIterator>
1032  inline _ForwardIterator
1033  uninitialized_move(_InputIterator __first, _InputIterator __last,
1034  _ForwardIterator __result)
1035  {
1037  (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1038  _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
1039  }
1040 
1041  /**
1042  * @brief Move-construct from the range [first,first+count) into result.
1043  * @param __first An input iterator.
1044  * @param __count The number of objects to initialize.
1045  * @param __result An output iterator.
1046  * @return __result + __count
1047  * @since C++17
1048  */
1049  template <typename _InputIterator, typename _Size, typename _ForwardIterator>
1050  inline pair<_InputIterator, _ForwardIterator>
1051  uninitialized_move_n(_InputIterator __first, _Size __count,
1052  _ForwardIterator __result)
1053  {
1054  auto __res = std::__uninitialized_copy_n_pair
1055  (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
1056  __count, __result);
1057  return {__res.first.base(), __res.second};
1058  }
1059 #endif // __glibcxx_raw_memory_algorithms
1060 
1061 #if __cplusplus >= 201103L
1062  /// @cond undocumented
1063 
1064  template<typename _Tp, typename _Up, typename _Allocator>
1065  _GLIBCXX20_CONSTEXPR
1066  inline void
1067  __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
1068  _Allocator& __alloc)
1069  noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
1070  __dest, std::move(*__orig)))
1072  __alloc, std::__addressof(*__orig))))
1073  {
1074  typedef std::allocator_traits<_Allocator> __traits;
1075  __traits::construct(__alloc, __dest, std::move(*__orig));
1076  __traits::destroy(__alloc, std::__addressof(*__orig));
1077  }
1078 
1079  // This class may be specialized for specific types.
1080  // Also known as is_trivially_relocatable.
1081  template<typename _Tp, typename = void>
1082  struct __is_bitwise_relocatable
1083  : is_trivial<_Tp> { };
1084 
1085  template <typename _InputIterator, typename _ForwardIterator,
1086  typename _Allocator>
1087  _GLIBCXX20_CONSTEXPR
1088  inline _ForwardIterator
1089  __relocate_a_1(_InputIterator __first, _InputIterator __last,
1090  _ForwardIterator __result, _Allocator& __alloc)
1091  noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1092  std::addressof(*__first),
1093  __alloc)))
1094  {
1095  typedef typename iterator_traits<_InputIterator>::value_type
1096  _ValueType;
1097  typedef typename iterator_traits<_ForwardIterator>::value_type
1098  _ValueType2;
1100  "relocation is only possible for values of the same type");
1101  _ForwardIterator __cur = __result;
1102  for (; __first != __last; ++__first, (void)++__cur)
1103  std::__relocate_object_a(std::__addressof(*__cur),
1104  std::__addressof(*__first), __alloc);
1105  return __cur;
1106  }
1107 
1108 #if _GLIBCXX_HOSTED
1109  template <typename _Tp, typename _Up>
1110  _GLIBCXX20_CONSTEXPR
1111  inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
1112  __relocate_a_1(_Tp* __first, _Tp* __last,
1113  _Tp* __result,
1114  [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept
1115  {
1116  ptrdiff_t __count = __last - __first;
1117  if (__count > 0)
1118  {
1119 #ifdef __cpp_lib_is_constant_evaluated
1120  if (std::is_constant_evaluated())
1121  {
1122  // Can't use memcpy. Wrap the pointer so that __relocate_a_1
1123  // resolves to the non-trivial overload above.
1124  __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result);
1125  __out = std::__relocate_a_1(__first, __last, __out, __alloc);
1126  return __out.base();
1127  }
1128 #endif
1129  __builtin_memcpy(__result, __first, __count * sizeof(_Tp));
1130  }
1131  return __result + __count;
1132  }
1133 #endif
1134 
1135  template <typename _InputIterator, typename _ForwardIterator,
1136  typename _Allocator>
1137  _GLIBCXX20_CONSTEXPR
1138  inline _ForwardIterator
1139  __relocate_a(_InputIterator __first, _InputIterator __last,
1140  _ForwardIterator __result, _Allocator& __alloc)
1141  noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1142  std::__niter_base(__last),
1143  std::__niter_base(__result), __alloc)))
1144  {
1145  return std::__relocate_a_1(std::__niter_base(__first),
1146  std::__niter_base(__last),
1147  std::__niter_base(__result), __alloc);
1148  }
1149 
1150  /// @endcond
1151 #endif // C++11
1152 
1153  /// @} group memory
1154 
1155 _GLIBCXX_END_NAMESPACE_VERSION
1156 } // namespace
1157 
1158 #endif /* _STL_UNINITIALIZED_H */
ISO C++ entities toplevel namespace is std.
is_same
Definition: type_traits:780
pair< _InputIterator, _ForwardIterator > uninitialized_move_n(_InputIterator __first, _Size __count, _ForwardIterator __result)
Move-construct from the range [first,first+count) into result.
Uniform interface to C++98 and C++11 allocators.
constexpr void _Destroy(_ForwardIterator __first, _ForwardIterator __last)
_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
Default-initializes objects in the range [first,first+count).
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
Definition: move.h:175
_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
Value-initializes objects in the range [first,first+count).
Uniform interface to all allocator types.
void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last)
Default-initializes objects in the range [first,last).
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
_ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp &__x)
Copies the value x into the range [first,first+n).
constexpr void _Construct(_Tp *__p, _Args &&... __args)
constexpr _OI fill_n(_OI __first, _Size __n, const _Tp &__value)
Fills the range [first,first+n) with copies of value.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:137
_ForwardIterator uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result)
Copies the range [first,first+n) into result.
_ForwardIterator uninitialized_move(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Move-construct from the range [first,last) into result.
Traits class for iterators.
void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last)
Value-initializes objects in the range [first,last).
_ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Copies the range [first,last) into result.
void uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__x)
Copies the value x into the range [first,last).
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:51
constexpr void fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__value)
Fills the range [first,last) with copies of value.