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