1 | // Raw memory manipulators -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2022 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 | __do_uninit_copy(_InputIterator __first, _InputIterator __last, |
114 | _ForwardIterator __result) |
115 | { |
116 | _ForwardIterator __cur = __result; |
117 | __try |
118 | { |
119 | for (; __first != __last; ++__first, (void)++__cur) |
120 | std::_Construct(std::__addressof(*__cur), *__first); |
121 | return __cur; |
122 | } |
123 | __catch(...) |
124 | { |
125 | std::_Destroy(__result, __cur); |
126 | __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 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
136 | _ForwardIterator __result) |
137 | { 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 | 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 | 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 | const bool __assignable |
182 | = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From); |
183 | |
184 | return std::__uninitialized_copy<__can_memmove && __assignable>:: |
185 | __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 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp> |
363 | _GLIBCXX20_CONSTEXPR |
364 | inline _ForwardIterator |
365 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, |
366 | _ForwardIterator __result, allocator<_Tp>&) |
367 | { |
368 | #ifdef __cpp_lib_is_constant_evaluated |
369 | if (std::is_constant_evaluated()) |
370 | return std::__do_uninit_copy(__first, __last, __result); |
371 | #endif |
372 | return std::uninitialized_copy(__first, __last, __result); |
373 | } |
374 | |
375 | template<typename _InputIterator, typename _ForwardIterator, |
376 | typename _Allocator> |
377 | _GLIBCXX20_CONSTEXPR |
378 | inline _ForwardIterator |
379 | __uninitialized_move_a(_InputIterator __first, _InputIterator __last, |
380 | _ForwardIterator __result, _Allocator& __alloc) |
381 | { |
382 | return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), |
383 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), |
384 | __result, __alloc); |
385 | } |
386 | |
387 | template<typename _InputIterator, typename _ForwardIterator, |
388 | typename _Allocator> |
389 | _GLIBCXX20_CONSTEXPR |
390 | inline _ForwardIterator |
391 | __uninitialized_move_if_noexcept_a(_InputIterator __first, |
392 | _InputIterator __last, |
393 | _ForwardIterator __result, |
394 | _Allocator& __alloc) |
395 | { |
396 | return std::__uninitialized_copy_a |
397 | (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), |
398 | _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); |
399 | } |
400 | |
401 | template<typename _ForwardIterator, typename _Tp, typename _Allocator> |
402 | _GLIBCXX20_CONSTEXPR |
403 | void |
404 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, |
405 | const _Tp& __x, _Allocator& __alloc) |
406 | { |
407 | _ForwardIterator __cur = __first; |
408 | __try |
409 | { |
410 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
411 | for (; __cur != __last; ++__cur) |
412 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
413 | } |
414 | __catch(...) |
415 | { |
416 | std::_Destroy(__first, __cur, __alloc); |
417 | __throw_exception_again; |
418 | } |
419 | } |
420 | |
421 | template<typename _ForwardIterator, typename _Tp, typename _Tp2> |
422 | _GLIBCXX20_CONSTEXPR |
423 | inline void |
424 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, |
425 | const _Tp& __x, allocator<_Tp2>&) |
426 | { |
427 | #ifdef __cpp_lib_is_constant_evaluated |
428 | if (std::is_constant_evaluated()) |
429 | return std::__do_uninit_fill(__first, __last, __x); |
430 | #endif |
431 | std::uninitialized_fill(__first, __last, __x); |
432 | } |
433 | |
434 | template<typename _ForwardIterator, typename _Size, typename _Tp, |
435 | typename _Allocator> |
436 | _GLIBCXX20_CONSTEXPR |
437 | _ForwardIterator |
438 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
439 | const _Tp& __x, _Allocator& __alloc) |
440 | { |
441 | _ForwardIterator __cur = __first; |
442 | __try |
443 | { |
444 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
445 | for (; __n > 0; --__n, (void) ++__cur) |
446 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
447 | return __cur; |
448 | } |
449 | __catch(...) |
450 | { |
451 | std::_Destroy(__first, __cur, __alloc); |
452 | __throw_exception_again; |
453 | } |
454 | } |
455 | |
456 | template<typename _ForwardIterator, typename _Size, typename _Tp, |
457 | typename _Tp2> |
458 | _GLIBCXX20_CONSTEXPR |
459 | inline _ForwardIterator |
460 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
461 | const _Tp& __x, allocator<_Tp2>&) |
462 | { |
463 | #ifdef __cpp_lib_is_constant_evaluated |
464 | if (std::is_constant_evaluated()) |
465 | return std::__do_uninit_fill_n(__first, __n, __x); |
466 | #endif |
467 | return std::uninitialized_fill_n(__first, __n, __x); |
468 | } |
469 | |
470 | |
471 | // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, |
472 | // __uninitialized_fill_move, __uninitialized_move_fill. |
473 | // All of these algorithms take a user-supplied allocator, which is used |
474 | // for construction and destruction. |
475 | |
476 | // __uninitialized_copy_move |
477 | // Copies [first1, last1) into [result, result + (last1 - first1)), and |
478 | // move [first2, last2) into |
479 | // [result, result + (last1 - first1) + (last2 - first2)). |
480 | template<typename _InputIterator1, typename _InputIterator2, |
481 | typename _ForwardIterator, typename _Allocator> |
482 | inline _ForwardIterator |
483 | __uninitialized_copy_move(_InputIterator1 __first1, |
484 | _InputIterator1 __last1, |
485 | _InputIterator2 __first2, |
486 | _InputIterator2 __last2, |
487 | _ForwardIterator __result, |
488 | _Allocator& __alloc) |
489 | { |
490 | _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, |
491 | __result, |
492 | __alloc); |
493 | __try |
494 | { |
495 | return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); |
496 | } |
497 | __catch(...) |
498 | { |
499 | std::_Destroy(__result, __mid, __alloc); |
500 | __throw_exception_again; |
501 | } |
502 | } |
503 | |
504 | // __uninitialized_move_copy |
505 | // Moves [first1, last1) into [result, result + (last1 - first1)), and |
506 | // copies [first2, last2) into |
507 | // [result, result + (last1 - first1) + (last2 - first2)). |
508 | template<typename _InputIterator1, typename _InputIterator2, |
509 | typename _ForwardIterator, typename _Allocator> |
510 | inline _ForwardIterator |
511 | __uninitialized_move_copy(_InputIterator1 __first1, |
512 | _InputIterator1 __last1, |
513 | _InputIterator2 __first2, |
514 | _InputIterator2 __last2, |
515 | _ForwardIterator __result, |
516 | _Allocator& __alloc) |
517 | { |
518 | _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, |
519 | __result, |
520 | __alloc); |
521 | __try |
522 | { |
523 | return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); |
524 | } |
525 | __catch(...) |
526 | { |
527 | std::_Destroy(__result, __mid, __alloc); |
528 | __throw_exception_again; |
529 | } |
530 | } |
531 | |
532 | // __uninitialized_fill_move |
533 | // Fills [result, mid) with x, and moves [first, last) into |
534 | // [mid, mid + (last - first)). |
535 | template<typename _ForwardIterator, typename _Tp, typename _InputIterator, |
536 | typename _Allocator> |
537 | inline _ForwardIterator |
538 | __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, |
539 | const _Tp& __x, _InputIterator __first, |
540 | _InputIterator __last, _Allocator& __alloc) |
541 | { |
542 | std::__uninitialized_fill_a(__result, __mid, __x, __alloc); |
543 | __try |
544 | { |
545 | return std::__uninitialized_move_a(__first, __last, __mid, __alloc); |
546 | } |
547 | __catch(...) |
548 | { |
549 | std::_Destroy(__result, __mid, __alloc); |
550 | __throw_exception_again; |
551 | } |
552 | } |
553 | |
554 | // __uninitialized_move_fill |
555 | // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and |
556 | // fills [first2 + (last1 - first1), last2) with x. |
557 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp, |
558 | typename _Allocator> |
559 | inline void |
560 | __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, |
561 | _ForwardIterator __first2, |
562 | _ForwardIterator __last2, const _Tp& __x, |
563 | _Allocator& __alloc) |
564 | { |
565 | _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, |
566 | __first2, |
567 | __alloc); |
568 | __try |
569 | { |
570 | std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); |
571 | } |
572 | __catch(...) |
573 | { |
574 | std::_Destroy(__first2, __mid2, __alloc); |
575 | __throw_exception_again; |
576 | } |
577 | } |
578 | |
579 | /// @endcond |
580 | |
581 | #if __cplusplus >= 201103L |
582 | /// @cond undocumented |
583 | |
584 | // Extensions: __uninitialized_default, __uninitialized_default_n, |
585 | // __uninitialized_default_a, __uninitialized_default_n_a. |
586 | |
587 | template<bool _TrivialValueType> |
588 | struct __uninitialized_default_1 |
589 | { |
590 | template<typename _ForwardIterator> |
591 | static void |
592 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) |
593 | { |
594 | _ForwardIterator __cur = __first; |
595 | __try |
596 | { |
597 | for (; __cur != __last; ++__cur) |
598 | std::_Construct(std::__addressof(*__cur)); |
599 | } |
600 | __catch(...) |
601 | { |
602 | std::_Destroy(__first, __cur); |
603 | __throw_exception_again; |
604 | } |
605 | } |
606 | }; |
607 | |
608 | template<> |
609 | struct __uninitialized_default_1<true> |
610 | { |
611 | template<typename _ForwardIterator> |
612 | static void |
613 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) |
614 | { |
615 | if (__first == __last) |
616 | return; |
617 | |
618 | typename iterator_traits<_ForwardIterator>::value_type* __val |
619 | = std::__addressof(*__first); |
620 | std::_Construct(__val); |
621 | if (++__first != __last) |
622 | std::fill(__first, __last, *__val); |
623 | } |
624 | }; |
625 | |
626 | template<bool _TrivialValueType> |
627 | struct __uninitialized_default_n_1 |
628 | { |
629 | template<typename _ForwardIterator, typename _Size> |
630 | _GLIBCXX20_CONSTEXPR |
631 | static _ForwardIterator |
632 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
633 | { |
634 | _ForwardIterator __cur = __first; |
635 | __try |
636 | { |
637 | for (; __n > 0; --__n, (void) ++__cur) |
638 | std::_Construct(std::__addressof(*__cur)); |
639 | return __cur; |
640 | } |
641 | __catch(...) |
642 | { |
643 | std::_Destroy(__first, __cur); |
644 | __throw_exception_again; |
645 | } |
646 | } |
647 | }; |
648 | |
649 | template<> |
650 | struct __uninitialized_default_n_1<true> |
651 | { |
652 | template<typename _ForwardIterator, typename _Size> |
653 | _GLIBCXX20_CONSTEXPR |
654 | static _ForwardIterator |
655 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
656 | { |
657 | if (__n > 0) |
658 | { |
659 | typename iterator_traits<_ForwardIterator>::value_type* __val |
660 | = std::__addressof(*__first); |
661 | std::_Construct(__val); |
662 | ++__first; |
663 | __first = std::fill_n(__first, __n - 1, *__val); |
664 | } |
665 | return __first; |
666 | } |
667 | }; |
668 | |
669 | // __uninitialized_default |
670 | // Fills [first, last) with value-initialized value_types. |
671 | template<typename _ForwardIterator> |
672 | inline void |
673 | __uninitialized_default(_ForwardIterator __first, |
674 | _ForwardIterator __last) |
675 | { |
676 | typedef typename iterator_traits<_ForwardIterator>::value_type |
677 | _ValueType; |
678 | // trivial types can have deleted assignment |
679 | const bool __assignable = is_copy_assignable<_ValueType>::value; |
680 | |
681 | std::__uninitialized_default_1<__is_trivial(_ValueType) |
682 | && __assignable>:: |
683 | __uninit_default(__first, __last); |
684 | } |
685 | |
686 | // __uninitialized_default_n |
687 | // Fills [first, first + n) with value-initialized value_types. |
688 | template<typename _ForwardIterator, typename _Size> |
689 | _GLIBCXX20_CONSTEXPR |
690 | inline _ForwardIterator |
691 | __uninitialized_default_n(_ForwardIterator __first, _Size __n) |
692 | { |
693 | typedef typename iterator_traits<_ForwardIterator>::value_type |
694 | _ValueType; |
695 | // See uninitialized_fill_n for the conditions for using std::fill_n. |
696 | constexpr bool __can_fill |
697 | = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value; |
698 | |
699 | return __uninitialized_default_n_1<__is_trivial(_ValueType) |
700 | && __can_fill>:: |
701 | __uninit_default_n(__first, __n); |
702 | } |
703 | |
704 | |
705 | // __uninitialized_default_a |
706 | // Fills [first, last) with value_types constructed by the allocator |
707 | // alloc, with no arguments passed to the construct call. |
708 | template<typename _ForwardIterator, typename _Allocator> |
709 | void |
710 | __uninitialized_default_a(_ForwardIterator __first, |
711 | _ForwardIterator __last, |
712 | _Allocator& __alloc) |
713 | { |
714 | _ForwardIterator __cur = __first; |
715 | __try |
716 | { |
717 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
718 | for (; __cur != __last; ++__cur) |
719 | __traits::construct(__alloc, std::__addressof(*__cur)); |
720 | } |
721 | __catch(...) |
722 | { |
723 | std::_Destroy(__first, __cur, __alloc); |
724 | __throw_exception_again; |
725 | } |
726 | } |
727 | |
728 | template<typename _ForwardIterator, typename _Tp> |
729 | inline void |
730 | __uninitialized_default_a(_ForwardIterator __first, |
731 | _ForwardIterator __last, |
732 | allocator<_Tp>&) |
733 | { std::__uninitialized_default(__first, __last); } |
734 | |
735 | |
736 | // __uninitialized_default_n_a |
737 | // Fills [first, first + n) with value_types constructed by the allocator |
738 | // alloc, with no arguments passed to the construct call. |
739 | template<typename _ForwardIterator, typename _Size, typename _Allocator> |
740 | _GLIBCXX20_CONSTEXPR _ForwardIterator |
741 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
742 | _Allocator& __alloc) |
743 | { |
744 | _ForwardIterator __cur = __first; |
745 | __try |
746 | { |
747 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
748 | for (; __n > 0; --__n, (void) ++__cur) |
749 | __traits::construct(__alloc, std::__addressof(*__cur)); |
750 | return __cur; |
751 | } |
752 | __catch(...) |
753 | { |
754 | std::_Destroy(__first, __cur, __alloc); |
755 | __throw_exception_again; |
756 | } |
757 | } |
758 | |
759 | // __uninitialized_default_n_a specialization for std::allocator, |
760 | // which ignores the allocator and value-initializes the elements. |
761 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
762 | _GLIBCXX20_CONSTEXPR |
763 | inline _ForwardIterator |
764 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
765 | allocator<_Tp>&) |
766 | { return std::__uninitialized_default_n(__first, __n); } |
767 | |
768 | template<bool _TrivialValueType> |
769 | struct __uninitialized_default_novalue_1 |
770 | { |
771 | template<typename _ForwardIterator> |
772 | static void |
773 | __uninit_default_novalue(_ForwardIterator __first, |
774 | _ForwardIterator __last) |
775 | { |
776 | _ForwardIterator __cur = __first; |
777 | __try |
778 | { |
779 | for (; __cur != __last; ++__cur) |
780 | std::_Construct_novalue(std::__addressof(*__cur)); |
781 | } |
782 | __catch(...) |
783 | { |
784 | std::_Destroy(__first, __cur); |
785 | __throw_exception_again; |
786 | } |
787 | } |
788 | }; |
789 | |
790 | template<> |
791 | struct __uninitialized_default_novalue_1<true> |
792 | { |
793 | template<typename _ForwardIterator> |
794 | static void |
795 | __uninit_default_novalue(_ForwardIterator __first, |
796 | _ForwardIterator __last) |
797 | { |
798 | } |
799 | }; |
800 | |
801 | template<bool _TrivialValueType> |
802 | struct __uninitialized_default_novalue_n_1 |
803 | { |
804 | template<typename _ForwardIterator, typename _Size> |
805 | static _ForwardIterator |
806 | __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) |
807 | { |
808 | _ForwardIterator __cur = __first; |
809 | __try |
810 | { |
811 | for (; __n > 0; --__n, (void) ++__cur) |
812 | std::_Construct_novalue(std::__addressof(*__cur)); |
813 | return __cur; |
814 | } |
815 | __catch(...) |
816 | { |
817 | std::_Destroy(__first, __cur); |
818 | __throw_exception_again; |
819 | } |
820 | } |
821 | }; |
822 | |
823 | template<> |
824 | struct __uninitialized_default_novalue_n_1<true> |
825 | { |
826 | template<typename _ForwardIterator, typename _Size> |
827 | static _ForwardIterator |
828 | __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) |
829 | { return std::next(__first, __n); } |
830 | }; |
831 | |
832 | // __uninitialized_default_novalue |
833 | // Fills [first, last) with default-initialized value_types. |
834 | template<typename _ForwardIterator> |
835 | inline void |
836 | __uninitialized_default_novalue(_ForwardIterator __first, |
837 | _ForwardIterator __last) |
838 | { |
839 | typedef typename iterator_traits<_ForwardIterator>::value_type |
840 | _ValueType; |
841 | |
842 | std::__uninitialized_default_novalue_1< |
843 | is_trivially_default_constructible<_ValueType>::value>:: |
844 | __uninit_default_novalue(__first, __last); |
845 | } |
846 | |
847 | // __uninitialized_default_novalue_n |
848 | // Fills [first, first + n) with default-initialized value_types. |
849 | template<typename _ForwardIterator, typename _Size> |
850 | inline _ForwardIterator |
851 | __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) |
852 | { |
853 | typedef typename iterator_traits<_ForwardIterator>::value_type |
854 | _ValueType; |
855 | |
856 | return __uninitialized_default_novalue_n_1< |
857 | is_trivially_default_constructible<_ValueType>::value>:: |
858 | __uninit_default_novalue_n(__first, __n); |
859 | } |
860 | |
861 | template<typename _InputIterator, typename _Size, |
862 | typename _ForwardIterator> |
863 | _ForwardIterator |
864 | __uninitialized_copy_n(_InputIterator __first, _Size __n, |
865 | _ForwardIterator __result, input_iterator_tag) |
866 | { |
867 | _ForwardIterator __cur = __result; |
868 | __try |
869 | { |
870 | for (; __n > 0; --__n, (void) ++__first, ++__cur) |
871 | std::_Construct(std::__addressof(*__cur), *__first); |
872 | return __cur; |
873 | } |
874 | __catch(...) |
875 | { |
876 | std::_Destroy(__result, __cur); |
877 | __throw_exception_again; |
878 | } |
879 | } |
880 | |
881 | template<typename _RandomAccessIterator, typename _Size, |
882 | typename _ForwardIterator> |
883 | inline _ForwardIterator |
884 | __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, |
885 | _ForwardIterator __result, |
886 | random_access_iterator_tag) |
887 | { return std::uninitialized_copy(__first, __first + __n, __result); } |
888 | |
889 | template<typename _InputIterator, typename _Size, |
890 | typename _ForwardIterator> |
891 | pair<_InputIterator, _ForwardIterator> |
892 | __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, |
893 | _ForwardIterator __result, input_iterator_tag) |
894 | { |
895 | _ForwardIterator __cur = __result; |
896 | __try |
897 | { |
898 | for (; __n > 0; --__n, (void) ++__first, ++__cur) |
899 | std::_Construct(std::__addressof(*__cur), *__first); |
900 | return {__first, __cur}; |
901 | } |
902 | __catch(...) |
903 | { |
904 | std::_Destroy(__result, __cur); |
905 | __throw_exception_again; |
906 | } |
907 | } |
908 | |
909 | template<typename _RandomAccessIterator, typename _Size, |
910 | typename _ForwardIterator> |
911 | inline pair<_RandomAccessIterator, _ForwardIterator> |
912 | __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, |
913 | _ForwardIterator __result, |
914 | random_access_iterator_tag) |
915 | { |
916 | auto __second_res = uninitialized_copy(__first, __first + __n, __result); |
917 | auto __first_res = std::next(__first, __n); |
918 | return {__first_res, __second_res}; |
919 | } |
920 | |
921 | /// @endcond |
922 | |
923 | /** |
924 | * @brief Copies the range [first,first+n) into result. |
925 | * @param __first An input iterator. |
926 | * @param __n The number of elements to copy. |
927 | * @param __result An output iterator. |
928 | * @return __result + __n |
929 | * @since C++11 |
930 | * |
931 | * Like copy_n(), but does not require an initialized output range. |
932 | */ |
933 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> |
934 | inline _ForwardIterator |
935 | uninitialized_copy_n(_InputIterator __first, _Size __n, |
936 | _ForwardIterator __result) |
937 | { return std::__uninitialized_copy_n(__first, __n, __result, |
938 | std::__iterator_category(__first)); } |
939 | |
940 | /// @cond undocumented |
941 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> |
942 | inline pair<_InputIterator, _ForwardIterator> |
943 | __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, |
944 | _ForwardIterator __result) |
945 | { |
946 | return |
947 | std::__uninitialized_copy_n_pair(__first, __n, __result, |
948 | std::__iterator_category(__first)); |
949 | } |
950 | /// @endcond |
951 | #endif |
952 | |
953 | #if __cplusplus >= 201703L |
954 | # define __cpp_lib_raw_memory_algorithms 201606L |
955 | |
956 | /** |
957 | * @brief Default-initializes objects in the range [first,last). |
958 | * @param __first A forward iterator. |
959 | * @param __last A forward iterator. |
960 | * @since C++17 |
961 | */ |
962 | template <typename _ForwardIterator> |
963 | inline void |
964 | uninitialized_default_construct(_ForwardIterator __first, |
965 | _ForwardIterator __last) |
966 | { |
967 | __uninitialized_default_novalue(__first, __last); |
968 | } |
969 | |
970 | /** |
971 | * @brief Default-initializes objects in the range [first,first+count). |
972 | * @param __first A forward iterator. |
973 | * @param __count The number of objects to construct. |
974 | * @return __first + __count |
975 | * @since C++17 |
976 | */ |
977 | template <typename _ForwardIterator, typename _Size> |
978 | inline _ForwardIterator |
979 | uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) |
980 | { |
981 | return __uninitialized_default_novalue_n(__first, __count); |
982 | } |
983 | |
984 | /** |
985 | * @brief Value-initializes objects in the range [first,last). |
986 | * @param __first A forward iterator. |
987 | * @param __last A forward iterator. |
988 | * @since C++17 |
989 | */ |
990 | template <typename _ForwardIterator> |
991 | inline void |
992 | uninitialized_value_construct(_ForwardIterator __first, |
993 | _ForwardIterator __last) |
994 | { |
995 | return __uninitialized_default(__first, __last); |
996 | } |
997 | |
998 | /** |
999 | * @brief Value-initializes objects in the range [first,first+count). |
1000 | * @param __first A forward iterator. |
1001 | * @param __count The number of objects to construct. |
1002 | * @return __result + __count |
1003 | * @since C++17 |
1004 | */ |
1005 | template <typename _ForwardIterator, typename _Size> |
1006 | inline _ForwardIterator |
1007 | uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) |
1008 | { |
1009 | return __uninitialized_default_n(__first, __count); |
1010 | } |
1011 | |
1012 | /** |
1013 | * @brief Move-construct from the range [first,last) into result. |
1014 | * @param __first An input iterator. |
1015 | * @param __last An input iterator. |
1016 | * @param __result An output iterator. |
1017 | * @return __result + (__first - __last) |
1018 | * @since C++17 |
1019 | */ |
1020 | template <typename _InputIterator, typename _ForwardIterator> |
1021 | inline _ForwardIterator |
1022 | uninitialized_move(_InputIterator __first, _InputIterator __last, |
1023 | _ForwardIterator __result) |
1024 | { |
1025 | return std::uninitialized_copy |
1026 | (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), |
1027 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); |
1028 | } |
1029 | |
1030 | /** |
1031 | * @brief Move-construct from the range [first,first+count) into result. |
1032 | * @param __first An input iterator. |
1033 | * @param __count The number of objects to initialize. |
1034 | * @param __result An output iterator. |
1035 | * @return __result + __count |
1036 | * @since C++17 |
1037 | */ |
1038 | template <typename _InputIterator, typename _Size, typename _ForwardIterator> |
1039 | inline pair<_InputIterator, _ForwardIterator> |
1040 | uninitialized_move_n(_InputIterator __first, _Size __count, |
1041 | _ForwardIterator __result) |
1042 | { |
1043 | auto __res = std::__uninitialized_copy_n_pair |
1044 | (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), |
1045 | __count, __result); |
1046 | return {__res.first.base(), __res.second}; |
1047 | } |
1048 | #endif // C++17 |
1049 | |
1050 | #if __cplusplus >= 201103L |
1051 | /// @cond undocumented |
1052 | |
1053 | template<typename _Tp, typename _Up, typename _Allocator> |
1054 | _GLIBCXX20_CONSTEXPR |
1055 | inline void |
1056 | __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, |
1057 | _Allocator& __alloc) |
1058 | noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, |
1059 | __dest, std::move(*__orig))) |
1060 | && noexcept(std::allocator_traits<_Allocator>::destroy( |
1061 | __alloc, std::__addressof(*__orig)))) |
1062 | { |
1063 | typedef std::allocator_traits<_Allocator> __traits; |
1064 | __traits::construct(__alloc, __dest, std::move(*__orig)); |
1065 | __traits::destroy(__alloc, std::__addressof(*__orig)); |
1066 | } |
1067 | |
1068 | // This class may be specialized for specific types. |
1069 | // Also known as is_trivially_relocatable. |
1070 | template<typename _Tp, typename = void> |
1071 | struct __is_bitwise_relocatable |
1072 | : is_trivial<_Tp> { }; |
1073 | |
1074 | template <typename _InputIterator, typename _ForwardIterator, |
1075 | typename _Allocator> |
1076 | _GLIBCXX20_CONSTEXPR |
1077 | inline _ForwardIterator |
1078 | __relocate_a_1(_InputIterator __first, _InputIterator __last, |
1079 | _ForwardIterator __result, _Allocator& __alloc) |
1080 | noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result), |
1081 | std::addressof(*__first), |
1082 | __alloc))) |
1083 | { |
1084 | typedef typename iterator_traits<_InputIterator>::value_type |
1085 | _ValueType; |
1086 | typedef typename iterator_traits<_ForwardIterator>::value_type |
1087 | _ValueType2; |
1088 | static_assert(std::is_same<_ValueType, _ValueType2>::value, |
1089 | "relocation is only possible for values of the same type" ); |
1090 | _ForwardIterator __cur = __result; |
1091 | for (; __first != __last; ++__first, (void)++__cur) |
1092 | std::__relocate_object_a(std::__addressof(*__cur), |
1093 | std::__addressof(*__first), __alloc); |
1094 | return __cur; |
1095 | } |
1096 | |
1097 | template <typename _Tp, typename _Up> |
1098 | _GLIBCXX20_CONSTEXPR |
1099 | inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*> |
1100 | __relocate_a_1(_Tp* __first, _Tp* __last, |
1101 | _Tp* __result, |
1102 | [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept |
1103 | { |
1104 | ptrdiff_t __count = __last - __first; |
1105 | if (__count > 0) |
1106 | { |
1107 | #ifdef __cpp_lib_is_constant_evaluated |
1108 | if (std::is_constant_evaluated()) |
1109 | { |
1110 | // Can't use memmove. Wrap the pointer so that __relocate_a_1 |
1111 | // resolves to the non-trivial overload above. |
1112 | __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result); |
1113 | __out = std::__relocate_a_1(__first, __last, __out, __alloc); |
1114 | return __out.base(); |
1115 | } |
1116 | #endif |
1117 | __builtin_memmove(__result, __first, __count * sizeof(_Tp)); |
1118 | } |
1119 | return __result + __count; |
1120 | } |
1121 | |
1122 | |
1123 | template <typename _InputIterator, typename _ForwardIterator, |
1124 | typename _Allocator> |
1125 | _GLIBCXX20_CONSTEXPR |
1126 | inline _ForwardIterator |
1127 | __relocate_a(_InputIterator __first, _InputIterator __last, |
1128 | _ForwardIterator __result, _Allocator& __alloc) |
1129 | noexcept(noexcept(__relocate_a_1(std::__niter_base(__first), |
1130 | std::__niter_base(__last), |
1131 | std::__niter_base(__result), __alloc))) |
1132 | { |
1133 | return std::__relocate_a_1(std::__niter_base(__first), |
1134 | std::__niter_base(__last), |
1135 | std::__niter_base(__result), __alloc); |
1136 | } |
1137 | |
1138 | /// @endcond |
1139 | #endif |
1140 | |
1141 | /// @} group memory |
1142 | |
1143 | _GLIBCXX_END_NAMESPACE_VERSION |
1144 | } // namespace |
1145 | |
1146 | #endif /* _STL_UNINITIALIZED_H */ |
1147 | |