Line data Source code
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 :
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 25116969 : __uninit_copy(_InputIterator __first, _InputIterator __last,
77 : _ForwardIterator __result)
78 : {
79 25107725 : _ForwardIterator __cur = __result;
80 : __try
81 : {
82 83734648 : for (; __first != __last; ++__first, (void)++__cur)
83 106535757 : std::_Construct(std::__addressof(*__cur), *__first);
84 25087788 : 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 159069945 : __uninit_copy(_InputIterator __first, _InputIterator __last,
100 : _ForwardIterator __result)
101 159069945 : { 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 184180966 : 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 183147615 : 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 184194666 : __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 1352 : __uninit_fill_n(_ForwardIterator __first, _Size __n,
216 : const _Tp& __x)
217 : {
218 1352 : _ForwardIterator __cur = __first;
219 : __try
220 : {
221 6014 : for (; __n > 0; --__n, (void) ++__cur)
222 6014 : std::_Construct(std::__addressof(*__cur), __x);
223 1352 : return __cur;
224 : }
225 0 : __catch(...)
226 : {
227 0 : std::_Destroy(__first, __cur);
228 0 : __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 3603 : __uninit_fill_n(_ForwardIterator __first, _Size __n,
239 : const _Tp& __x)
240 7206 : { 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 4955 : 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 11562 : const bool __assignable = is_copy_assignable<_ValueType>::value;
271 : #endif
272 : return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
273 11156 : __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 123934733 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
306 : _ForwardIterator __result, allocator<_Tp>&)
307 25434468 : { return std::uninitialized_copy(__first, __last, __result); }
308 :
309 : template<typename _InputIterator, typename _ForwardIterator,
310 : typename _Allocator>
311 : inline _ForwardIterator
312 386405 : __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
313 : _ForwardIterator __result, _Allocator& __alloc)
314 : {
315 386405 : 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 59884961 : __uninitialized_move_if_noexcept_a(_InputIterator __first,
324 : _InputIterator __last,
325 : _ForwardIterator __result,
326 : _Allocator& __alloc)
327 : {
328 : return std::__uninitialized_copy_a
329 59943487 : (_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 8252 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
383 : const _Tp& __x, allocator<_Tp2>&)
384 4955 : { 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 0 : __uninitialized_copy_move(_InputIterator1 __first1,
400 : _InputIterator1 __last1,
401 : _InputIterator2 __first2,
402 : _InputIterator2 __last2,
403 : _ForwardIterator __result,
404 : _Allocator& __alloc)
405 : {
406 0 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
407 : __result,
408 : __alloc);
409 : __try
410 : {
411 0 : 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 0 : __uninitialized_move_copy(_InputIterator1 __first1,
428 : _InputIterator1 __last1,
429 : _InputIterator2 __first2,
430 : _InputIterator2 __last2,
431 : _ForwardIterator __result,
432 : _Allocator& __alloc)
433 : {
434 0 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
435 : __result,
436 : __alloc);
437 : __try
438 : {
439 0 : 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 231 : __uninit_default_n(_ForwardIterator __first, _Size __n)
540 : {
541 231 : _ForwardIterator __cur = __first;
542 : __try
543 : {
544 512828 : for (; __n > 0; --__n, (void) ++__cur)
545 512597 : std::_Construct(std::__addressof(*__cur));
546 231 : return __cur;
547 : }
548 0 : __catch(...)
549 : {
550 0 : std::_Destroy(__first, __cur);
551 0 : __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 0 : __uninit_default_n(_ForwardIterator __first, _Size __n)
562 : {
563 : typedef typename iterator_traits<_ForwardIterator>::value_type
564 : _ValueType;
565 :
566 5403 : 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 231 : __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 547966 : const bool __assignable = is_copy_assignable<_ValueType>::value;
598 :
599 : return __uninitialized_default_n_1<__is_trivial(_ValueType)
600 : && __assignable>::
601 30943 : __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 30943 : __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
662 : allocator<_Tp>&)
663 29988 : { 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 770950815 : __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 770950815 : __traits::construct(__alloc, __dest, std::move(*__orig));
913 770950815 : __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 399733520 : __relocate_a_1(_Tp* __first, _Tp* __last,
925 : _Tp* __result, allocator<_Up>&) noexcept
926 : {
927 399733520 : ptrdiff_t __count = __last - __first;
928 175167203 : if (__count > 0)
929 94932860 : __builtin_memmove(__result, __first, __count * sizeof(_Tp));
930 175167203 : 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 4339895 : for (; __first != __last; ++__first, (void)++__cur)
950 1537557635 : 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 319498014 : __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 1370687266 : 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 */
|