Line data Source code
1 : // Raw memory manipulators -*- C++ -*-
2 :
3 : // Copyright (C) 2001-2020 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 0 : __uninit_copy(_InputIterator __first, _InputIterator __last,
85 : _ForwardIterator __result)
86 : {
87 0 : _ForwardIterator __cur = __result;
88 : __try
89 : {
90 0 : for (; __first != __last; ++__first, (void)++__cur)
91 0 : std::_Construct(std::__addressof(*__cur), *__first);
92 0 : return __cur;
93 : }
94 0 : __catch(...)
95 : {
96 0 : std::_Destroy(__result, __cur);
97 0 : __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 0 : __uninit_copy(_InputIterator __first, _InputIterator __last,
108 : _ForwardIterator __result)
109 0 : { 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 0 : uninitialized_copy(_InputIterator __first, _InputIterator __last,
126 : _ForwardIterator __result)
127 : {
128 : typedef typename iterator_traits<_InputIterator>::value_type
129 : _ValueType1;
130 : typedef typename iterator_traits<_ForwardIterator>::value_type
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 0 : 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 0 : __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 : {
203 : typedef typename iterator_traits<_ForwardIterator>::value_type
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.
210 : static_assert(is_constructible<_ValueType, const _Tp&>::value,
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 : {
274 : typedef typename iterator_traits<_ForwardIterator>::value_type
275 : _ValueType;
276 : #if __cplusplus < 201103L
277 : const bool __assignable = true;
278 : #else
279 : // Trivial types can have deleted copy constructor, but the std::fill
280 : // optimization that uses memmove would happily "copy" them anyway.
281 : static_assert(is_constructible<_ValueType, const _Tp&>::value,
282 : "result type must be constructible from input type");
283 :
284 : // Trivial types can have deleted assignment, so using std::fill
285 : // would be ill-formed. Require assignability before using std::fill:
286 : const bool __assignable = is_copy_assignable<_ValueType>::value;
287 : #endif
288 : return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
289 : __uninit_fill_n(__first, __n, __x);
290 : }
291 :
292 : /// @cond undocumented
293 :
294 : // Extensions: versions of uninitialized_copy, uninitialized_fill,
295 : // and uninitialized_fill_n that take an allocator parameter.
296 : // We dispatch back to the standard versions when we're given the
297 : // default allocator. For nondefault allocators we do not use
298 : // any of the POD optimizations.
299 :
300 : template<typename _InputIterator, typename _ForwardIterator,
301 : typename _Allocator>
302 : _ForwardIterator
303 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
304 : _ForwardIterator __result, _Allocator& __alloc)
305 : {
306 : _ForwardIterator __cur = __result;
307 : __try
308 : {
309 : typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
310 : for (; __first != __last; ++__first, (void)++__cur)
311 : __traits::construct(__alloc, std::__addressof(*__cur), *__first);
312 : return __cur;
313 : }
314 : __catch(...)
315 : {
316 : std::_Destroy(__result, __cur, __alloc);
317 : __throw_exception_again;
318 : }
319 : }
320 :
321 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
322 : inline _ForwardIterator
323 0 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
324 : _ForwardIterator __result, allocator<_Tp>&)
325 0 : { return std::uninitialized_copy(__first, __last, __result); }
326 :
327 : template<typename _InputIterator, typename _ForwardIterator,
328 : typename _Allocator>
329 : inline _ForwardIterator
330 : __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
331 : _ForwardIterator __result, _Allocator& __alloc)
332 : {
333 : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
334 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
335 : __result, __alloc);
336 : }
337 :
338 : template<typename _InputIterator, typename _ForwardIterator,
339 : typename _Allocator>
340 : inline _ForwardIterator
341 0 : __uninitialized_move_if_noexcept_a(_InputIterator __first,
342 : _InputIterator __last,
343 : _ForwardIterator __result,
344 : _Allocator& __alloc)
345 : {
346 : return std::__uninitialized_copy_a
347 0 : (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
348 0 : _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
349 : }
350 :
351 : template<typename _ForwardIterator, typename _Tp, typename _Allocator>
352 : void
353 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
354 : const _Tp& __x, _Allocator& __alloc)
355 : {
356 : _ForwardIterator __cur = __first;
357 : __try
358 : {
359 : typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
360 : for (; __cur != __last; ++__cur)
361 : __traits::construct(__alloc, std::__addressof(*__cur), __x);
362 : }
363 : __catch(...)
364 : {
365 : std::_Destroy(__first, __cur, __alloc);
366 : __throw_exception_again;
367 : }
368 : }
369 :
370 : template<typename _ForwardIterator, typename _Tp, typename _Tp2>
371 : inline void
372 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
373 : const _Tp& __x, allocator<_Tp2>&)
374 : { std::uninitialized_fill(__first, __last, __x); }
375 :
376 : template<typename _ForwardIterator, typename _Size, typename _Tp,
377 : typename _Allocator>
378 : _ForwardIterator
379 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
380 : const _Tp& __x, _Allocator& __alloc)
381 : {
382 : _ForwardIterator __cur = __first;
383 : __try
384 : {
385 : typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
386 : for (; __n > 0; --__n, (void) ++__cur)
387 : __traits::construct(__alloc, std::__addressof(*__cur), __x);
388 : return __cur;
389 : }
390 : __catch(...)
391 : {
392 : std::_Destroy(__first, __cur, __alloc);
393 : __throw_exception_again;
394 : }
395 : }
396 :
397 : template<typename _ForwardIterator, typename _Size, typename _Tp,
398 : typename _Tp2>
399 : inline _ForwardIterator
400 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
401 : const _Tp& __x, allocator<_Tp2>&)
402 : { return std::uninitialized_fill_n(__first, __n, __x); }
403 :
404 :
405 : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
406 : // __uninitialized_fill_move, __uninitialized_move_fill.
407 : // All of these algorithms take a user-supplied allocator, which is used
408 : // for construction and destruction.
409 :
410 : // __uninitialized_copy_move
411 : // Copies [first1, last1) into [result, result + (last1 - first1)), and
412 : // move [first2, last2) into
413 : // [result, result + (last1 - first1) + (last2 - first2)).
414 : template<typename _InputIterator1, typename _InputIterator2,
415 : typename _ForwardIterator, typename _Allocator>
416 : inline _ForwardIterator
417 : __uninitialized_copy_move(_InputIterator1 __first1,
418 : _InputIterator1 __last1,
419 : _InputIterator2 __first2,
420 : _InputIterator2 __last2,
421 : _ForwardIterator __result,
422 : _Allocator& __alloc)
423 : {
424 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
425 : __result,
426 : __alloc);
427 : __try
428 : {
429 : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
430 : }
431 : __catch(...)
432 : {
433 : std::_Destroy(__result, __mid, __alloc);
434 : __throw_exception_again;
435 : }
436 : }
437 :
438 : // __uninitialized_move_copy
439 : // Moves [first1, last1) into [result, result + (last1 - first1)), and
440 : // copies [first2, last2) into
441 : // [result, result + (last1 - first1) + (last2 - first2)).
442 : template<typename _InputIterator1, typename _InputIterator2,
443 : typename _ForwardIterator, typename _Allocator>
444 : inline _ForwardIterator
445 : __uninitialized_move_copy(_InputIterator1 __first1,
446 : _InputIterator1 __last1,
447 : _InputIterator2 __first2,
448 : _InputIterator2 __last2,
449 : _ForwardIterator __result,
450 : _Allocator& __alloc)
451 : {
452 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
453 : __result,
454 : __alloc);
455 : __try
456 : {
457 : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
458 : }
459 : __catch(...)
460 : {
461 : std::_Destroy(__result, __mid, __alloc);
462 : __throw_exception_again;
463 : }
464 : }
465 :
466 : // __uninitialized_fill_move
467 : // Fills [result, mid) with x, and moves [first, last) into
468 : // [mid, mid + (last - first)).
469 : template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
470 : typename _Allocator>
471 : inline _ForwardIterator
472 : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
473 : const _Tp& __x, _InputIterator __first,
474 : _InputIterator __last, _Allocator& __alloc)
475 : {
476 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
477 : __try
478 : {
479 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
480 : }
481 : __catch(...)
482 : {
483 : std::_Destroy(__result, __mid, __alloc);
484 : __throw_exception_again;
485 : }
486 : }
487 :
488 : // __uninitialized_move_fill
489 : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
490 : // fills [first2 + (last1 - first1), last2) with x.
491 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
492 : typename _Allocator>
493 : inline void
494 : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
495 : _ForwardIterator __first2,
496 : _ForwardIterator __last2, const _Tp& __x,
497 : _Allocator& __alloc)
498 : {
499 : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
500 : __first2,
501 : __alloc);
502 : __try
503 : {
504 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
505 : }
506 : __catch(...)
507 : {
508 : std::_Destroy(__first2, __mid2, __alloc);
509 : __throw_exception_again;
510 : }
511 : }
512 :
513 : /// @endcond
514 :
515 : #if __cplusplus >= 201103L
516 : /// @cond undocumented
517 :
518 : // Extensions: __uninitialized_default, __uninitialized_default_n,
519 : // __uninitialized_default_a, __uninitialized_default_n_a.
520 :
521 : template<bool _TrivialValueType>
522 : struct __uninitialized_default_1
523 : {
524 : template<typename _ForwardIterator>
525 : static void
526 : __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
527 : {
528 : _ForwardIterator __cur = __first;
529 : __try
530 : {
531 : for (; __cur != __last; ++__cur)
532 : std::_Construct(std::__addressof(*__cur));
533 : }
534 : __catch(...)
535 : {
536 : std::_Destroy(__first, __cur);
537 : __throw_exception_again;
538 : }
539 : }
540 : };
541 :
542 : template<>
543 : struct __uninitialized_default_1<true>
544 : {
545 : template<typename _ForwardIterator>
546 : static void
547 : __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
548 : {
549 : typedef typename iterator_traits<_ForwardIterator>::value_type
550 : _ValueType;
551 :
552 : std::fill(__first, __last, _ValueType());
553 : }
554 : };
555 :
556 : template<bool _TrivialValueType>
557 : struct __uninitialized_default_n_1
558 : {
559 : template<typename _ForwardIterator, typename _Size>
560 : static _ForwardIterator
561 : __uninit_default_n(_ForwardIterator __first, _Size __n)
562 : {
563 : _ForwardIterator __cur = __first;
564 : __try
565 : {
566 : for (; __n > 0; --__n, (void) ++__cur)
567 : std::_Construct(std::__addressof(*__cur));
568 : return __cur;
569 : }
570 : __catch(...)
571 : {
572 : std::_Destroy(__first, __cur);
573 : __throw_exception_again;
574 : }
575 : }
576 : };
577 :
578 : template<>
579 : struct __uninitialized_default_n_1<true>
580 : {
581 : template<typename _ForwardIterator, typename _Size>
582 : static _ForwardIterator
583 : __uninit_default_n(_ForwardIterator __first, _Size __n)
584 : {
585 : typedef typename iterator_traits<_ForwardIterator>::value_type
586 : _ValueType;
587 :
588 : return std::fill_n(__first, __n, _ValueType());
589 : }
590 : };
591 :
592 : // __uninitialized_default
593 : // Fills [first, last) with std::distance(first, last) default
594 : // constructed value_types(s).
595 : template<typename _ForwardIterator>
596 : inline void
597 : __uninitialized_default(_ForwardIterator __first,
598 : _ForwardIterator __last)
599 : {
600 : typedef typename iterator_traits<_ForwardIterator>::value_type
601 : _ValueType;
602 : // trivial types can have deleted assignment
603 : const bool __assignable = is_copy_assignable<_ValueType>::value;
604 :
605 : std::__uninitialized_default_1<__is_trivial(_ValueType)
606 : && __assignable>::
607 : __uninit_default(__first, __last);
608 : }
609 :
610 : // __uninitialized_default_n
611 : // Fills [first, first + n) with n default constructed value_type(s).
612 : template<typename _ForwardIterator, typename _Size>
613 : inline _ForwardIterator
614 : __uninitialized_default_n(_ForwardIterator __first, _Size __n)
615 : {
616 : typedef typename iterator_traits<_ForwardIterator>::value_type
617 : _ValueType;
618 : // trivial types can have deleted assignment
619 : const bool __assignable = is_copy_assignable<_ValueType>::value;
620 :
621 : return __uninitialized_default_n_1<__is_trivial(_ValueType)
622 : && __assignable>::
623 : __uninit_default_n(__first, __n);
624 : }
625 :
626 :
627 : // __uninitialized_default_a
628 : // Fills [first, last) with std::distance(first, last) default
629 : // constructed value_types(s), constructed with the allocator alloc.
630 : template<typename _ForwardIterator, typename _Allocator>
631 : void
632 : __uninitialized_default_a(_ForwardIterator __first,
633 : _ForwardIterator __last,
634 : _Allocator& __alloc)
635 : {
636 : _ForwardIterator __cur = __first;
637 : __try
638 : {
639 : typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
640 : for (; __cur != __last; ++__cur)
641 : __traits::construct(__alloc, std::__addressof(*__cur));
642 : }
643 : __catch(...)
644 : {
645 : std::_Destroy(__first, __cur, __alloc);
646 : __throw_exception_again;
647 : }
648 : }
649 :
650 : template<typename _ForwardIterator, typename _Tp>
651 : inline void
652 : __uninitialized_default_a(_ForwardIterator __first,
653 : _ForwardIterator __last,
654 : allocator<_Tp>&)
655 : { std::__uninitialized_default(__first, __last); }
656 :
657 :
658 : // __uninitialized_default_n_a
659 : // Fills [first, first + n) with n default constructed value_types(s),
660 : // constructed with the allocator alloc.
661 : template<typename _ForwardIterator, typename _Size, typename _Allocator>
662 : _ForwardIterator
663 : __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
664 : _Allocator& __alloc)
665 : {
666 : _ForwardIterator __cur = __first;
667 : __try
668 : {
669 : typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
670 : for (; __n > 0; --__n, (void) ++__cur)
671 : __traits::construct(__alloc, std::__addressof(*__cur));
672 : return __cur;
673 : }
674 : __catch(...)
675 : {
676 : std::_Destroy(__first, __cur, __alloc);
677 : __throw_exception_again;
678 : }
679 : }
680 :
681 : template<typename _ForwardIterator, typename _Size, typename _Tp>
682 : inline _ForwardIterator
683 : __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
684 : allocator<_Tp>&)
685 : { return std::__uninitialized_default_n(__first, __n); }
686 :
687 : template<bool _TrivialValueType>
688 : struct __uninitialized_default_novalue_1
689 : {
690 : template<typename _ForwardIterator>
691 : static void
692 : __uninit_default_novalue(_ForwardIterator __first,
693 : _ForwardIterator __last)
694 : {
695 : _ForwardIterator __cur = __first;
696 : __try
697 : {
698 : for (; __cur != __last; ++__cur)
699 : std::_Construct_novalue(std::__addressof(*__cur));
700 : }
701 : __catch(...)
702 : {
703 : std::_Destroy(__first, __cur);
704 : __throw_exception_again;
705 : }
706 : }
707 : };
708 :
709 : template<>
710 : struct __uninitialized_default_novalue_1<true>
711 : {
712 : template<typename _ForwardIterator>
713 : static void
714 : __uninit_default_novalue(_ForwardIterator __first,
715 : _ForwardIterator __last)
716 : {
717 : }
718 : };
719 :
720 : template<bool _TrivialValueType>
721 : struct __uninitialized_default_novalue_n_1
722 : {
723 : template<typename _ForwardIterator, typename _Size>
724 : static _ForwardIterator
725 : __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
726 : {
727 : _ForwardIterator __cur = __first;
728 : __try
729 : {
730 : for (; __n > 0; --__n, (void) ++__cur)
731 : std::_Construct_novalue(std::__addressof(*__cur));
732 : return __cur;
733 : }
734 : __catch(...)
735 : {
736 : std::_Destroy(__first, __cur);
737 : __throw_exception_again;
738 : }
739 : }
740 : };
741 :
742 : template<>
743 : struct __uninitialized_default_novalue_n_1<true>
744 : {
745 : template<typename _ForwardIterator, typename _Size>
746 : static _ForwardIterator
747 : __uninit_default_novalue_n(_ForwardIterator __first, _Size __n)
748 : { return std::next(__first, __n); }
749 : };
750 :
751 : // __uninitialized_default_novalue
752 : // Fills [first, last) with std::distance(first, last) default-initialized
753 : // value_types(s).
754 : template<typename _ForwardIterator>
755 : inline void
756 : __uninitialized_default_novalue(_ForwardIterator __first,
757 : _ForwardIterator __last)
758 : {
759 : typedef typename iterator_traits<_ForwardIterator>::value_type
760 : _ValueType;
761 :
762 : std::__uninitialized_default_novalue_1<
763 : is_trivially_default_constructible<_ValueType>::value>::
764 : __uninit_default_novalue(__first, __last);
765 : }
766 :
767 : // __uninitialized_default_n
768 : // Fills [first, first + n) with n default-initialized value_type(s).
769 : template<typename _ForwardIterator, typename _Size>
770 : inline _ForwardIterator
771 : __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n)
772 : {
773 : typedef typename iterator_traits<_ForwardIterator>::value_type
774 : _ValueType;
775 :
776 : return __uninitialized_default_novalue_n_1<
777 : is_trivially_default_constructible<_ValueType>::value>::
778 : __uninit_default_novalue_n(__first, __n);
779 : }
780 :
781 : template<typename _InputIterator, typename _Size,
782 : typename _ForwardIterator>
783 : _ForwardIterator
784 : __uninitialized_copy_n(_InputIterator __first, _Size __n,
785 : _ForwardIterator __result, input_iterator_tag)
786 : {
787 : _ForwardIterator __cur = __result;
788 : __try
789 : {
790 : for (; __n > 0; --__n, (void) ++__first, ++__cur)
791 : std::_Construct(std::__addressof(*__cur), *__first);
792 : return __cur;
793 : }
794 : __catch(...)
795 : {
796 : std::_Destroy(__result, __cur);
797 : __throw_exception_again;
798 : }
799 : }
800 :
801 : template<typename _RandomAccessIterator, typename _Size,
802 : typename _ForwardIterator>
803 : inline _ForwardIterator
804 : __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
805 : _ForwardIterator __result,
806 : random_access_iterator_tag)
807 : { return std::uninitialized_copy(__first, __first + __n, __result); }
808 :
809 : template<typename _InputIterator, typename _Size,
810 : typename _ForwardIterator>
811 : pair<_InputIterator, _ForwardIterator>
812 : __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
813 : _ForwardIterator __result, input_iterator_tag)
814 : {
815 : _ForwardIterator __cur = __result;
816 : __try
817 : {
818 : for (; __n > 0; --__n, (void) ++__first, ++__cur)
819 : std::_Construct(std::__addressof(*__cur), *__first);
820 : return {__first, __cur};
821 : }
822 : __catch(...)
823 : {
824 : std::_Destroy(__result, __cur);
825 : __throw_exception_again;
826 : }
827 : }
828 :
829 : template<typename _RandomAccessIterator, typename _Size,
830 : typename _ForwardIterator>
831 : inline pair<_RandomAccessIterator, _ForwardIterator>
832 : __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n,
833 : _ForwardIterator __result,
834 : random_access_iterator_tag)
835 : {
836 : auto __second_res = uninitialized_copy(__first, __first + __n, __result);
837 : auto __first_res = std::next(__first, __n);
838 : return {__first_res, __second_res};
839 : }
840 :
841 : /// @endcond
842 :
843 : /**
844 : * @brief Copies the range [first,first+n) into result.
845 : * @param __first An input iterator.
846 : * @param __n The number of elements to copy.
847 : * @param __result An output iterator.
848 : * @return __result + __n
849 : *
850 : * Like copy_n(), but does not require an initialized output range.
851 : */
852 : template<typename _InputIterator, typename _Size, typename _ForwardIterator>
853 : inline _ForwardIterator
854 : uninitialized_copy_n(_InputIterator __first, _Size __n,
855 : _ForwardIterator __result)
856 : { return std::__uninitialized_copy_n(__first, __n, __result,
857 : std::__iterator_category(__first)); }
858 :
859 : /// @cond undocumented
860 : template<typename _InputIterator, typename _Size, typename _ForwardIterator>
861 : inline pair<_InputIterator, _ForwardIterator>
862 : __uninitialized_copy_n_pair(_InputIterator __first, _Size __n,
863 : _ForwardIterator __result)
864 : {
865 : return
866 : std::__uninitialized_copy_n_pair(__first, __n, __result,
867 : std::__iterator_category(__first));
868 : }
869 : /// @endcond
870 : #endif
871 :
872 : #if __cplusplus >= 201703L
873 : # define __cpp_lib_raw_memory_algorithms 201606L
874 :
875 : /**
876 : * @brief Default-initializes objects in the range [first,last).
877 : * @param __first A forward iterator.
878 : * @param __last A forward iterator.
879 : */
880 : template <typename _ForwardIterator>
881 : inline void
882 : uninitialized_default_construct(_ForwardIterator __first,
883 : _ForwardIterator __last)
884 : {
885 : __uninitialized_default_novalue(__first, __last);
886 : }
887 :
888 : /**
889 : * @brief Default-initializes objects in the range [first,first+count).
890 : * @param __first A forward iterator.
891 : * @param __count The number of objects to construct.
892 : * @return __first + __count
893 : */
894 : template <typename _ForwardIterator, typename _Size>
895 : inline _ForwardIterator
896 : uninitialized_default_construct_n(_ForwardIterator __first, _Size __count)
897 : {
898 : return __uninitialized_default_novalue_n(__first, __count);
899 : }
900 :
901 : /**
902 : * @brief Value-initializes objects in the range [first,last).
903 : * @param __first A forward iterator.
904 : * @param __last A forward iterator.
905 : */
906 : template <typename _ForwardIterator>
907 : inline void
908 : uninitialized_value_construct(_ForwardIterator __first,
909 : _ForwardIterator __last)
910 : {
911 : return __uninitialized_default(__first, __last);
912 : }
913 :
914 : /**
915 : * @brief Value-initializes objects in the range [first,first+count).
916 : * @param __first A forward iterator.
917 : * @param __count The number of objects to construct.
918 : * @return __result + __count
919 : */
920 : template <typename _ForwardIterator, typename _Size>
921 : inline _ForwardIterator
922 : uninitialized_value_construct_n(_ForwardIterator __first, _Size __count)
923 : {
924 : return __uninitialized_default_n(__first, __count);
925 : }
926 :
927 : /**
928 : * @brief Move-construct from the range [first,last) into result.
929 : * @param __first An input iterator.
930 : * @param __last An input iterator.
931 : * @param __result An output iterator.
932 : * @return __result + (__first - __last)
933 : */
934 : template <typename _InputIterator, typename _ForwardIterator>
935 : inline _ForwardIterator
936 : uninitialized_move(_InputIterator __first, _InputIterator __last,
937 : _ForwardIterator __result)
938 : {
939 : return std::uninitialized_copy
940 : (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
941 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result);
942 : }
943 :
944 : /**
945 : * @brief Move-construct from the range [first,first+count) into result.
946 : * @param __first An input iterator.
947 : * @param __count The number of objects to initialize.
948 : * @param __result An output iterator.
949 : * @return __result + __count
950 : */
951 : template <typename _InputIterator, typename _Size, typename _ForwardIterator>
952 : inline pair<_InputIterator, _ForwardIterator>
953 : uninitialized_move_n(_InputIterator __first, _Size __count,
954 : _ForwardIterator __result)
955 : {
956 : auto __res = std::__uninitialized_copy_n_pair
957 : (_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
958 : __count, __result);
959 : return {__res.first.base(), __res.second};
960 : }
961 : #endif // C++17
962 :
963 : #if __cplusplus >= 201103L
964 : /// @cond undocumented
965 :
966 : template<typename _Tp, typename _Up, typename _Allocator>
967 : inline void
968 44882 : __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig,
969 : _Allocator& __alloc)
970 : noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc,
971 : __dest, std::move(*__orig)))
972 : && noexcept(std::allocator_traits<_Allocator>::destroy(
973 : __alloc, std::__addressof(*__orig))))
974 : {
975 : typedef std::allocator_traits<_Allocator> __traits;
976 44882 : __traits::construct(__alloc, __dest, std::move(*__orig));
977 44882 : __traits::destroy(__alloc, std::__addressof(*__orig));
978 44882 : }
979 :
980 : // This class may be specialized for specific types.
981 : // Also known as is_trivially_relocatable.
982 : template<typename _Tp, typename = void>
983 : struct __is_bitwise_relocatable
984 : : is_trivial<_Tp> { };
985 :
986 : template <typename _Tp, typename _Up>
987 : inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*>
988 0 : __relocate_a_1(_Tp* __first, _Tp* __last,
989 : _Tp* __result, allocator<_Up>&) noexcept
990 : {
991 0 : ptrdiff_t __count = __last - __first;
992 0 : if (__count > 0)
993 0 : __builtin_memmove(__result, __first, __count * sizeof(_Tp));
994 0 : return __result + __count;
995 : }
996 :
997 : template <typename _InputIterator, typename _ForwardIterator,
998 : typename _Allocator>
999 : inline _ForwardIterator
1000 17434 : __relocate_a_1(_InputIterator __first, _InputIterator __last,
1001 : _ForwardIterator __result, _Allocator& __alloc)
1002 : noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result),
1003 : std::addressof(*__first),
1004 : __alloc)))
1005 : {
1006 : typedef typename iterator_traits<_InputIterator>::value_type
1007 : _ValueType;
1008 : typedef typename iterator_traits<_ForwardIterator>::value_type
1009 : _ValueType2;
1010 : static_assert(std::is_same<_ValueType, _ValueType2>::value,
1011 : "relocation is only possible for values of the same type");
1012 17434 : _ForwardIterator __cur = __result;
1013 62316 : for (; __first != __last; ++__first, (void)++__cur)
1014 44882 : std::__relocate_object_a(std::__addressof(*__cur),
1015 : std::__addressof(*__first), __alloc);
1016 17434 : return __cur;
1017 : }
1018 :
1019 : template <typename _InputIterator, typename _ForwardIterator,
1020 : typename _Allocator>
1021 : inline _ForwardIterator
1022 17434 : __relocate_a(_InputIterator __first, _InputIterator __last,
1023 : _ForwardIterator __result, _Allocator& __alloc)
1024 : noexcept(noexcept(__relocate_a_1(std::__niter_base(__first),
1025 : std::__niter_base(__last),
1026 : std::__niter_base(__result), __alloc)))
1027 : {
1028 17434 : return __relocate_a_1(std::__niter_base(__first),
1029 : std::__niter_base(__last),
1030 17434 : std::__niter_base(__result), __alloc);
1031 : }
1032 :
1033 : /// @endcond
1034 : #endif
1035 :
1036 : // @} group memory
1037 :
1038 : _GLIBCXX_END_NAMESPACE_VERSION
1039 : } // namespace
1040 :
1041 : #endif /* _STL_UNINITIALIZED_H */
|