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