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