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