Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/stl_uninitialized.h
1 // Raw memory manipulators -*- C++ -*- 2 3 // Copyright (C) 2001-2025 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 # include <bits/ptr_traits.h> // to_address 62 # include <bits/stl_pair.h> // pair 63 # include <bits/stl_algobase.h> // fill, fill_n 64 #endif 65 66 #include <bits/cpp_type_traits.h> // __is_pointer 67 #include <bits/stl_iterator_base_funcs.h> // distance, advance 68 #include <bits/stl_iterator.h> // __niter_base 69 #include <ext/alloc_traits.h> // __alloc_traits 70 71 namespace std _GLIBCXX_VISIBILITY(default) 72 { 73 _GLIBCXX_BEGIN_NAMESPACE_VERSION 74 75 /** @addtogroup memory 76 * @{ 77 */ 78 79 /// @cond undocumented 80 81 template<typename _ForwardIterator, typename _Alloc = void> 82 struct _UninitDestroyGuard 83 { 84 _GLIBCXX20_CONSTEXPR 85 explicit 86 _UninitDestroyGuard(_ForwardIterator& __first, _Alloc& __a) 87 : _M_first(__first), _M_cur(__builtin_addressof(__first)), _M_alloc(__a) 88 { } 89 90 _GLIBCXX20_CONSTEXPR 91 ~_UninitDestroyGuard() 92 { 93 if (__builtin_expect(_M_cur != 0, 0)) 94 std::_Destroy(_M_first, *_M_cur, _M_alloc); 95 } 96 97 _GLIBCXX20_CONSTEXPR 98 void release() { _M_cur = 0; } 99 100 private: 101 _ForwardIterator const _M_first; 102 _ForwardIterator* _M_cur; 103 _Alloc& _M_alloc; 104 105 _UninitDestroyGuard(const _UninitDestroyGuard&); 106 }; 107 108 template<typename _ForwardIterator> 109 struct _UninitDestroyGuard<_ForwardIterator, void> 110 { 111 _GLIBCXX20_CONSTEXPR 112 explicit 113 _UninitDestroyGuard(_ForwardIterator& __first) 114 : _M_first(__first), _M_cur(__builtin_addressof(__first)) 115 { } 116 117 _GLIBCXX20_CONSTEXPR 118 ~_UninitDestroyGuard() 119 { 120 if (__builtin_expect(_M_cur != 0, 0)) 121 std::_Destroy(_M_first, *_M_cur); 122 } 123 124 _GLIBCXX20_CONSTEXPR 125 void release() { _M_cur = 0; } 126 127 _ForwardIterator const _M_first; 128 _ForwardIterator* _M_cur; 129 130 private: 131 _UninitDestroyGuard(const _UninitDestroyGuard&); 132 }; 133 134 // This is the default implementation of std::uninitialized_copy. 135 // This can be used with C++20 iterators and non-common ranges. 136 template<typename _InputIterator, typename _Sentinel, 137 typename _ForwardIterator> 138 _GLIBCXX20_CONSTEXPR 139 _ForwardIterator 140 __do_uninit_copy(_InputIterator __first, _Sentinel __last, 141 _ForwardIterator __result) 142 { 143 _UninitDestroyGuard<_ForwardIterator> __guard(__result); 144 for (; __first != __last; ++__first, (void)++__result) 145 std::_Construct(std::__addressof(*__result), *__first); 146 __guard.release(); 147 return __result; 148 } 149 150 #if __cplusplus < 201103L 151 152 // True if we can unwrap _Iter to get a pointer by using std::__niter_base. 153 template<typename _Iter, 154 typename _Base = __decltype(std::__niter_base(*(_Iter*)0))> 155 struct __unwrappable_niter 156 { enum { __value = false }; }; 157 158 template<typename _Iter, typename _Tp> 159 struct __unwrappable_niter<_Iter, _Tp*> 160 { enum { __value = true }; }; 161 162 // Use template specialization for C++98 when 'if constexpr' can't be used. 163 template<bool _CanMemcpy> 164 struct __uninitialized_copy 165 { 166 template<typename _InputIterator, typename _ForwardIterator> 167 static _ForwardIterator 168 __uninit_copy(_InputIterator __first, _InputIterator __last, 169 _ForwardIterator __result) 170 { return std::__do_uninit_copy(__first, __last, __result); } 171 }; 172 173 template<> 174 struct __uninitialized_copy<true> 175 { 176 // Overload for generic iterators. 177 template<typename _InputIterator, typename _ForwardIterator> 178 static _ForwardIterator 179 __uninit_copy(_InputIterator __first, _InputIterator __last, 180 _ForwardIterator __result) 181 { 182 if (__unwrappable_niter<_InputIterator>::__value 183 && __unwrappable_niter<_ForwardIterator>::__value) 184 { 185 __uninit_copy(std::__niter_base(__first), 186 std::__niter_base(__last), 187 std::__niter_base(__result)); 188 std::advance(__result, std::distance(__first, __last)); 189 return __result; 190 } 191 else 192 return std::__do_uninit_copy(__first, __last, __result); 193 } 194 195 // Overload for pointers. 196 template<typename _Tp, typename _Up> 197 static _Up* 198 __uninit_copy(_Tp* __first, _Tp* __last, _Up* __result) 199 { 200 // Ensure that we don't successfully memcpy in cases that should be 201 // ill-formed because is_constructible<_Up, _Tp&> is false. 202 typedef __typeof__(static_cast<_Up>(*__first)) __check 203 __attribute__((__unused__)); 204 205 const ptrdiff_t __n = __last - __first; 206 if (__builtin_expect(__n > 0, true)) 207 { 208 __builtin_memcpy(__result, __first, __n * sizeof(_Tp)); 209 __result += __n; 210 } 211 return __result; 212 } 213 }; 214 #endif 215 /// @endcond 216 217 #pragma GCC diagnostic push 218 #pragma GCC diagnostic ignored "-Wc++17-extensions" 219 /** 220 * @brief Copies the range [first,last) into result. 221 * @param __first An input iterator. 222 * @param __last An input iterator. 223 * @param __result A forward iterator. 224 * @return __result + (__last - __first) 225 * 226 * Like std::copy, but does not require an initialized output range. 227 */ 228 template<typename _InputIterator, typename _ForwardIterator> 229 _GLIBCXX26_CONSTEXPR 230 inline _ForwardIterator 231 uninitialized_copy(_InputIterator __first, _InputIterator __last, 232 _ForwardIterator __result) 233 { 234 // We can use memcpy to copy the ranges under these conditions: 235 // 236 // _ForwardIterator and _InputIterator are both contiguous iterators, 237 // so that we can turn them into pointers to pass to memcpy. 238 // Before C++20 we can't detect all contiguous iterators, so we only 239 // handle built-in pointers and __normal_iterator<T*, C> types. 240 // 241 // The value types of both iterators are trivially-copyable types, 242 // so that memcpy is not undefined and can begin the lifetime of 243 // new objects in the output range. 244 // 245 // Finally, memcpy from the source type, S, to the destination type, D, 246 // must give the same value as initialization of D from S would give. 247 // We require is_trivially_constructible<D, S> to be true, but that is 248 // not sufficient. Some cases of trivial initialization are not just a 249 // bitwise copy, even when sizeof(D) == sizeof(S), 250 // e.g. bit_cast<unsigned>(1.0f) != 1u because the corresponding bits 251 // of the value representations do not have the same meaning. 252 // We cannot tell when this condition is true in general, 253 // so we rely on the __memcpyable trait. 254 255 #if __cplusplus >= 201103L 256 using _Dest = decltype(std::__niter_base(__result)); 257 using _Src = decltype(std::__niter_base(__first)); 258 using _ValT = typename iterator_traits<_ForwardIterator>::value_type; 259 260 #if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26 261 if consteval { 262 return std::__do_uninit_copy(__first, __last, __result); 263 } 264 #endif 265 if constexpr (!__is_trivially_constructible(_ValT, decltype(*__first))) 266 return std::__do_uninit_copy(__first, __last, __result); 267 else if constexpr (__memcpyable<_Dest, _Src>::__value) 268 { 269 ptrdiff_t __n = __last - __first; 270 if (__n > 0) [[__likely__]] 271 { 272 using _ValT = typename remove_pointer<_Src>::type; 273 __builtin_memcpy(std::__niter_base(__result), 274 std::__niter_base(__first), 275 __n * sizeof(_ValT)); 276 __result += __n; 277 } 278 return __result; 279 } 280 #if __cpp_lib_concepts 281 else if constexpr (contiguous_iterator<_ForwardIterator> 282 && contiguous_iterator<_InputIterator>) 283 { 284 using _DestPtr = decltype(std::to_address(__result)); 285 using _SrcPtr = decltype(std::to_address(__first)); 286 if constexpr (__memcpyable<_DestPtr, _SrcPtr>::__value) 287 { 288 if (auto __n = __last - __first; __n > 0) [[likely]] 289 { 290 void* __dest = std::to_address(__result); 291 const void* __src = std::to_address(__first); 292 size_t __nbytes = __n * sizeof(remove_pointer_t<_DestPtr>); 293 __builtin_memcpy(__dest, __src, __nbytes); 294 __result += __n; 295 } 296 return __result; 297 } 298 else 299 return std::__do_uninit_copy(__first, __last, __result); 300 } 301 #endif 302 else 303 return std::__do_uninit_copy(__first, __last, __result); 304 #else // C++98 305 typedef typename iterator_traits<_InputIterator>::value_type 306 _ValueType1; 307 typedef typename iterator_traits<_ForwardIterator>::value_type 308 _ValueType2; 309 310 const bool __can_memcpy 311 = __memcpyable<_ValueType1*, _ValueType2*>::__value 312 && __is_trivially_constructible(_ValueType2, __decltype(*__first)); 313 314 return __uninitialized_copy<__can_memcpy>:: 315 __uninit_copy(__first, __last, __result); 316 #endif 317 } 318 #pragma GCC diagnostic pop 319 320 /// @cond undocumented 321 322 // This is the default implementation of std::uninitialized_fill. 323 template<typename _ForwardIterator, typename _Tp> 324 _GLIBCXX20_CONSTEXPR void 325 __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 326 const _Tp& __x) 327 { 328 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 329 for (; __first != __last; ++__first) 330 std::_Construct(std::__addressof(*__first), __x); 331 __guard.release(); 332 } 333 334 #if __cplusplus < 201103L 335 // Use template specialization for C++98 when 'if constexpr' can't be used. 336 template<bool _CanMemset> 337 struct __uninitialized_fill 338 { 339 template<typename _ForwardIterator, typename _Tp> 340 static void 341 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 342 const _Tp& __x) 343 { std::__do_uninit_fill(__first, __last, __x); } 344 }; 345 346 template<> 347 struct __uninitialized_fill<true> 348 { 349 // Overload for generic iterators. 350 template<typename _ForwardIterator, typename _Tp> 351 static void 352 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 353 const _Tp& __x) 354 { 355 if (__unwrappable_niter<_ForwardIterator>::__value) 356 __uninit_fill(std::__niter_base(__first), 357 std::__niter_base(__last), 358 __x); 359 else 360 std::__do_uninit_fill(__first, __last, __x); 361 } 362 363 // Overload for pointers. 364 template<typename _Up, typename _Tp> 365 static void 366 __uninit_fill(_Up* __first, _Up* __last, const _Tp& __x) 367 { 368 // Ensure that we don't successfully memset in cases that should be 369 // ill-formed because is_constructible<_Up, const _Tp&> is false. 370 typedef __typeof__(static_cast<_Up>(__x)) __check 371 __attribute__((__unused__)); 372 373 if (__first != __last) 374 __builtin_memset(__first, (unsigned char)__x, __last - __first); 375 } 376 }; 377 #endif 378 /// @endcond 379 380 /** 381 * @brief Copies the value x into the range [first,last). 382 * @param __first A forward iterator. 383 * @param __last A forward iterator. 384 * @param __x The source value. 385 * @return Nothing. 386 * 387 * Like std::fill, but does not require an initialized output range. 388 */ 389 template<typename _ForwardIterator, typename _Tp> 390 _GLIBCXX26_CONSTEXPR 391 inline void 392 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 393 const _Tp& __x) 394 { 395 // We would like to use memset to optimize this loop when possible. 396 // As for std::uninitialized_copy, the optimization requires 397 // contiguous iterators and trivially copyable value types, 398 // with the additional requirement that sizeof(_Tp) == 1 because 399 // memset only writes single bytes. 400 401 // FIXME: We could additionally enable this for 1-byte enums. 402 // Maybe any 1-byte Val if is_trivially_constructible<Val, const T&>? 403 404 typedef typename iterator_traits<_ForwardIterator>::value_type 405 _ValueType; 406 407 #if __cplusplus >= 201103L 408 #pragma GCC diagnostic push 409 #pragma GCC diagnostic ignored "-Wc++17-extensions" 410 #if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26 411 if consteval { 412 return std::__do_uninit_fill(__first, __last, __x); 413 } 414 #endif 415 if constexpr (__is_byte<_ValueType>::__value) 416 if constexpr (is_same<_ValueType, _Tp>::value 417 || is_integral<_Tp>::value) 418 { 419 using _BasePtr = decltype(std::__niter_base(__first)); 420 if constexpr (is_pointer<_BasePtr>::value) 421 { 422 void* __dest = std::__niter_base(__first); 423 ptrdiff_t __n = __last - __first; 424 if (__n > 0) [[__likely__]] 425 __builtin_memset(__dest, (unsigned char)__x, __n); 426 return; 427 } 428 #if __cpp_lib_concepts 429 else if constexpr (contiguous_iterator<_ForwardIterator>) 430 { 431 auto __dest = std::to_address(__first); 432 auto __n = __last - __first; 433 if (__n > 0) [[__likely__]] 434 __builtin_memset(__dest, (unsigned char)__x, __n); 435 return; 436 } 437 #endif 438 } 439 std::__do_uninit_fill(__first, __last, __x); 440 #pragma GCC diagnostic pop 441 #else // C++98 442 const bool __can_memset = __is_byte<_ValueType>::__value 443 && __is_integer<_Tp>::__value; 444 445 __uninitialized_fill<__can_memset>::__uninit_fill(__first, __last, __x); 446 #endif 447 } 448 449 /// @cond undocumented 450 451 // This is the default implementation of std::uninitialized_fill_n. 452 template<typename _ForwardIterator, typename _Size, typename _Tp> 453 _GLIBCXX20_CONSTEXPR 454 _ForwardIterator 455 __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 456 { 457 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 458 #if __cplusplus >= 201103L 459 #pragma GCC diagnostic push 460 #pragma GCC diagnostic ignored "-Wc++17-extensions" 461 if constexpr (is_integral<_Size>::value) 462 // Loop will never terminate if __n is negative. 463 __glibcxx_assert(__n >= 0); 464 else if constexpr (is_floating_point<_Size>::value) 465 // Loop will never terminate if __n is not an integer. 466 __glibcxx_assert(__n >= 0 && static_cast<size_t>(__n) == __n); 467 #pragma GCC diagnostic pop 468 #endif 469 for (; __n--; ++__first) 470 std::_Construct(std::__addressof(*__first), __x); 471 __guard.release(); 472 return __first; 473 } 474 475 #if __cplusplus < 201103L 476 // Use template specialization for C++98 when 'if constexpr' can't be used. 477 template<bool _CanMemset> 478 struct __uninitialized_fill_n 479 { 480 template<typename _ForwardIterator, typename _Size, typename _Tp> 481 static _ForwardIterator 482 __uninit_fill_n(_ForwardIterator __first, _Size __n, 483 const _Tp& __x) 484 { return std::__do_uninit_fill_n(__first, __n, __x); } 485 }; 486 487 template<> 488 struct __uninitialized_fill_n<true> 489 { 490 // Overload for generic iterators. 491 template<typename _ForwardIterator, typename _Size, typename _Tp> 492 static _ForwardIterator 493 __uninit_fill_n(_ForwardIterator __first, _Size __n, 494 const _Tp& __x) 495 { 496 if (__unwrappable_niter<_ForwardIterator>::__value) 497 { 498 _ForwardIterator __last = __first; 499 std::advance(__last, __n); 500 __uninitialized_fill<true>::__uninit_fill(__first, __last, __x); 501 return __last; 502 } 503 else 504 return std::__do_uninit_fill_n(__first, __n, __x); 505 } 506 }; 507 #endif 508 /// @endcond 509 510 #pragma GCC diagnostic push 511 #pragma GCC diagnostic ignored "-Wc++17-extensions" 512 // _GLIBCXX_RESOLVE_LIB_DEFECTS 513 // DR 1339. uninitialized_fill_n should return the end of its range 514 /** 515 * @brief Copies the value x into the range [first,first+n). 516 * @param __first A forward iterator. 517 * @param __n The number of copies to make. 518 * @param __x The source value. 519 * @return __first + __n. 520 * 521 * Like std::fill_n, but does not require an initialized output range. 522 */ 523 template<typename _ForwardIterator, typename _Size, typename _Tp> 524 _GLIBCXX26_CONSTEXPR 525 inline _ForwardIterator 526 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 527 { 528 // See uninitialized_fill conditions. We also require _Size to be 529 // an integer. The standard only requires _Size to be decrementable 530 // and contextually convertible to bool, so don't assume first+n works. 531 532 // FIXME: We could additionally enable this for 1-byte enums. 533 534 typedef typename iterator_traits<_ForwardIterator>::value_type 535 _ValueType; 536 537 #if __cplusplus >= 201103L 538 #if __glibcxx_raw_memory_algorithms >= 202411L // >= C++26 539 if consteval { 540 return std::__do_uninit_fill_n(__first, __n, __x); 541 } 542 #endif 543 if constexpr (__is_byte<_ValueType>::__value) 544 if constexpr (is_integral<_Tp>::value) 545 if constexpr (is_integral<_Size>::value) 546 { 547 using _BasePtr = decltype(std::__niter_base(__first)); 548 if constexpr (is_pointer<_BasePtr>::value) 549 { 550 void* __dest = std::__niter_base(__first); 551 if (__n > 0) [[__likely__]] 552 { 553 __builtin_memset(__dest, (unsigned char)__x, __n); 554 __first += __n; 555 } 556 return __first; 557 } 558 #if __cpp_lib_concepts 559 else if constexpr (contiguous_iterator<_ForwardIterator>) 560 { 561 auto __dest = std::to_address(__first); 562 if (__n > 0) [[__likely__]] 563 { 564 __builtin_memset(__dest, (unsigned char)__x, __n); 565 __first += __n; 566 } 567 return __first; 568 } 569 #endif 570 } 571 return std::__do_uninit_fill_n(__first, __n, __x); 572 #else // C++98 573 const bool __can_memset = __is_byte<_ValueType>::__value 574 && __is_integer<_Tp>::__value 575 && __is_integer<_Size>::__value; 576 577 return __uninitialized_fill_n<__can_memset>:: 578 __uninit_fill_n(__first, __n, __x); 579 #endif 580 } 581 #pragma GCC diagnostic pop 582 583 /// @cond undocumented 584 585 // Extensions: versions of uninitialized_copy, uninitialized_fill, 586 // and uninitialized_fill_n that take an allocator parameter. 587 // We dispatch back to the standard versions when we're given the 588 // default allocator. For nondefault allocators we do not use 589 // any of the POD optimizations. 590 591 template<typename _InputIterator, typename _Sentinel, 592 typename _ForwardIterator, typename _Allocator> 593 _GLIBCXX20_CONSTEXPR 594 _ForwardIterator 595 __uninitialized_copy_a(_InputIterator __first, _Sentinel __last, 596 _ForwardIterator __result, _Allocator& __alloc) 597 { 598 _UninitDestroyGuard<_ForwardIterator, _Allocator> 599 __guard(__result, __alloc); 600 601 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 602 for (; __first != __last; ++__first, (void)++__result) 603 __traits::construct(__alloc, std::__addressof(*__result), *__first); 604 __guard.release(); 605 return __result; 606 } 607 608 #if _GLIBCXX_HOSTED 609 template<typename _InputIterator, typename _Sentinel, 610 typename _ForwardIterator, typename _Tp> 611 _GLIBCXX20_CONSTEXPR 612 inline _ForwardIterator 613 __uninitialized_copy_a(_InputIterator __first, _Sentinel __last, 614 _ForwardIterator __result, allocator<_Tp>&) 615 { 616 #ifdef __cpp_lib_is_constant_evaluated 617 if (std::is_constant_evaluated()) 618 return std::__do_uninit_copy(std::move(__first), __last, __result); 619 #endif 620 621 #ifdef __glibcxx_ranges 622 if constexpr (!is_same_v<_InputIterator, _Sentinel>) 623 { 624 // Convert to a common range if possible, to benefit from memcpy 625 // optimizations that std::uninitialized_copy might use. 626 if constexpr (sized_sentinel_for<_Sentinel, _InputIterator> 627 && random_access_iterator<_InputIterator>) 628 return std::uninitialized_copy(__first, 629 __first + (__last - __first), 630 __result); 631 else // Just use default implementation. 632 return std::__do_uninit_copy(std::move(__first), __last, __result); 633 } 634 else 635 return std::uninitialized_copy(std::move(__first), __last, __result); 636 #else 637 return std::uninitialized_copy(__first, __last, __result); 638 #endif 639 } 640 #endif 641 642 template<typename _InputIterator, typename _ForwardIterator, 643 typename _Allocator> 644 _GLIBCXX20_CONSTEXPR 645 inline _ForwardIterator 646 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 647 _ForwardIterator __result, _Allocator& __alloc) 648 { 649 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 650 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 651 __result, __alloc); 652 } 653 654 template<typename _InputIterator, typename _ForwardIterator, 655 typename _Allocator> 656 _GLIBCXX20_CONSTEXPR 657 inline _ForwardIterator 658 __uninitialized_move_if_noexcept_a(_InputIterator __first, 659 _InputIterator __last, 660 _ForwardIterator __result, 661 _Allocator& __alloc) 662 { 663 return std::__uninitialized_copy_a 664 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), 665 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); 666 } 667 668 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 669 _GLIBCXX20_CONSTEXPR 670 void 671 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 672 const _Tp& __x, _Allocator& __alloc) 673 { 674 _UninitDestroyGuard<_ForwardIterator, _Allocator> 675 __guard(__first, __alloc); 676 677 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 678 for (; __first != __last; ++__first) 679 __traits::construct(__alloc, std::__addressof(*__first), __x); 680 681 __guard.release(); 682 } 683 684 #if _GLIBCXX_HOSTED 685 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 686 _GLIBCXX20_CONSTEXPR 687 inline void 688 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 689 const _Tp& __x, allocator<_Tp2>&) 690 { 691 #ifdef __cpp_lib_is_constant_evaluated 692 if (std::is_constant_evaluated()) 693 return std::__do_uninit_fill(__first, __last, __x); 694 #endif 695 std::uninitialized_fill(__first, __last, __x); 696 } 697 #endif 698 699 template<typename _ForwardIterator, typename _Size, typename _Tp, 700 typename _Allocator> 701 _GLIBCXX20_CONSTEXPR 702 _ForwardIterator 703 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 704 const _Tp& __x, _Allocator& __alloc) 705 { 706 _UninitDestroyGuard<_ForwardIterator, _Allocator> 707 __guard(__first, __alloc); 708 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 709 for (; __n > 0; --__n, (void) ++__first) 710 __traits::construct(__alloc, std::__addressof(*__first), __x); 711 __guard.release(); 712 return __first; 713 } 714 715 #if _GLIBCXX_HOSTED 716 template<typename _ForwardIterator, typename _Size, typename _Tp, 717 typename _Tp2> 718 _GLIBCXX20_CONSTEXPR 719 inline _ForwardIterator 720 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 721 const _Tp& __x, allocator<_Tp2>&) 722 { 723 #ifdef __cpp_lib_is_constant_evaluated 724 if (std::is_constant_evaluated()) 725 return std::__do_uninit_fill_n(__first, __n, __x); 726 #endif 727 return std::uninitialized_fill_n(__first, __n, __x); 728 } 729 #endif 730 731 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 732 // __uninitialized_fill_move, __uninitialized_move_fill. 733 // All of these algorithms take a user-supplied allocator, which is used 734 // for construction and destruction. 735 736 // __uninitialized_copy_move 737 // Copies [first1, last1) into [result, result + (last1 - first1)), and 738 // move [first2, last2) into 739 // [result, result + (last1 - first1) + (last2 - first2)). 740 template<typename _InputIterator1, typename _InputIterator2, 741 typename _ForwardIterator, typename _Allocator> 742 inline _ForwardIterator 743 __uninitialized_copy_move(_InputIterator1 __first1, 744 _InputIterator1 __last1, 745 _InputIterator2 __first2, 746 _InputIterator2 __last2, 747 _ForwardIterator __result, 748 _Allocator& __alloc) 749 { 750 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 751 __result, __alloc); 752 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result, 753 __alloc); 754 __result = __mid; // Everything up to __mid is now guarded. 755 __result = std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 756 __guard.release(); 757 return __result; 758 } 759 760 // __uninitialized_move_copy 761 // Moves [first1, last1) into [result, result + (last1 - first1)), and 762 // copies [first2, last2) into 763 // [result, result + (last1 - first1) + (last2 - first2)). 764 template<typename _InputIterator1, typename _InputIterator2, 765 typename _ForwardIterator, typename _Allocator> 766 inline _ForwardIterator 767 __uninitialized_move_copy(_InputIterator1 __first1, 768 _InputIterator1 __last1, 769 _InputIterator2 __first2, 770 _InputIterator2 __last2, 771 _ForwardIterator __result, 772 _Allocator& __alloc) 773 { 774 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 775 __result, __alloc); 776 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result, 777 __alloc); 778 __result = __mid; // Everything up to __mid is now guarded. 779 __result = std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 780 __guard.release(); 781 return __result; 782 } 783 784 // __uninitialized_fill_move 785 // Fills [result, mid) with x, and moves [first, last) into 786 // [mid, mid + (last - first)). 787 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 788 typename _Allocator> 789 inline _ForwardIterator 790 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 791 const _Tp& __x, _InputIterator __first, 792 _InputIterator __last, _Allocator& __alloc) 793 { 794 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 795 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__result, 796 __alloc); 797 __result = __mid; // Everything up to __mid is now guarded. 798 __result = std::__uninitialized_move_a(__first, __last, __mid, __alloc); 799 __guard.release(); 800 return __result; 801 } 802 803 // __uninitialized_move_fill 804 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 805 // fills [first2 + (last1 - first1), last2) with x. 806 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 807 typename _Allocator> 808 inline void 809 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 810 _ForwardIterator __first2, 811 _ForwardIterator __last2, const _Tp& __x, 812 _Allocator& __alloc) 813 { 814 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 815 __first2, 816 __alloc); 817 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first2, 818 __alloc); 819 __first2 = __mid2; // Everything up to __mid2 is now guarded. 820 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 821 __guard.release(); 822 } 823 824 /// @endcond 825 826 #if __cplusplus >= 201103L 827 /// @cond undocumented 828 829 // Extensions: __uninitialized_default, __uninitialized_default_n, 830 // __uninitialized_default_a, __uninitialized_default_n_a. 831 832 template<bool _TrivialValueType> 833 struct __uninitialized_default_1 834 { 835 template<typename _ForwardIterator> 836 _GLIBCXX26_CONSTEXPR 837 static void 838 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 839 { 840 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 841 for (; __first != __last; ++__first) 842 std::_Construct(std::__addressof(*__first)); 843 __guard.release(); 844 } 845 }; 846 847 template<> 848 struct __uninitialized_default_1<true> 849 { 850 template<typename _ForwardIterator> 851 _GLIBCXX26_CONSTEXPR 852 static void 853 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 854 { 855 if (__first == __last) 856 return; 857 858 typename iterator_traits<_ForwardIterator>::value_type* __val 859 = std::__addressof(*__first); 860 std::_Construct(__val); 861 if (++__first != __last) 862 std::fill(__first, __last, *__val); 863 } 864 }; 865 866 template<bool _TrivialValueType> 867 struct __uninitialized_default_n_1 868 { 869 template<typename _ForwardIterator, typename _Size> 870 _GLIBCXX20_CONSTEXPR 871 static _ForwardIterator 872 __uninit_default_n(_ForwardIterator __first, _Size __n) 873 { 874 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 875 for (; __n > 0; --__n, (void) ++__first) 876 std::_Construct(std::__addressof(*__first)); 877 __guard.release(); 878 return __first; 879 } 880 }; 881 882 template<> 883 struct __uninitialized_default_n_1<true> 884 { 885 template<typename _ForwardIterator, typename _Size> 886 _GLIBCXX20_CONSTEXPR 887 static _ForwardIterator 888 __uninit_default_n(_ForwardIterator __first, _Size __n) 889 { 890 if (__n > 0) 891 { 892 typename iterator_traits<_ForwardIterator>::value_type* __val 893 = std::__addressof(*__first); 894 std::_Construct(__val); 895 ++__first; 896 __first = std::fill_n(__first, __n - 1, *__val); 897 } 898 return __first; 899 } 900 }; 901 902 // __uninitialized_default 903 // Fills [first, last) with value-initialized value_types. 904 template<typename _ForwardIterator> 905 _GLIBCXX20_CONSTEXPR 906 inline void 907 __uninitialized_default(_ForwardIterator __first, 908 _ForwardIterator __last) 909 { 910 #ifdef __cpp_lib_is_constant_evaluated 911 if (std::is_constant_evaluated()) 912 return __uninitialized_default_1<false>:: 913 __uninit_default(__first, __last); 914 #endif 915 916 typedef typename iterator_traits<_ForwardIterator>::value_type 917 _ValueType; 918 // trivial types can have deleted assignment 919 const bool __assignable = is_copy_assignable<_ValueType>::value; 920 921 std::__uninitialized_default_1<__is_trivial(_ValueType) 922 && __assignable>:: 923 __uninit_default(__first, __last); 924 } 925 926 // __uninitialized_default_n 927 // Fills [first, first + n) with value-initialized value_types. 928 template<typename _ForwardIterator, typename _Size> 929 _GLIBCXX20_CONSTEXPR 930 inline _ForwardIterator 931 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 932 { 933 #ifdef __cpp_lib_is_constant_evaluated 934 if (std::is_constant_evaluated()) 935 return __uninitialized_default_n_1<false>:: 936 __uninit_default_n(__first, __n); 937 #endif 938 939 typedef typename iterator_traits<_ForwardIterator>::value_type 940 _ValueType; 941 // See uninitialized_fill_n for the conditions for using std::fill_n. 942 constexpr bool __can_fill 943 = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value; 944 945 return __uninitialized_default_n_1<__is_trivial(_ValueType) 946 && __can_fill>:: 947 __uninit_default_n(__first, __n); 948 } 949 950 951 // __uninitialized_default_a 952 // Fills [first, last) with value_types constructed by the allocator 953 // alloc, with no arguments passed to the construct call. 954 template<typename _ForwardIterator, typename _Allocator> 955 void 956 __uninitialized_default_a(_ForwardIterator __first, 957 _ForwardIterator __last, 958 _Allocator& __alloc) 959 { 960 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first, 961 __alloc); 962 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 963 for (; __first != __last; ++__first) 964 __traits::construct(__alloc, std::__addressof(*__first)); 965 __guard.release(); 966 } 967 968 #if _GLIBCXX_HOSTED 969 template<typename _ForwardIterator, typename _Tp> 970 inline void 971 __uninitialized_default_a(_ForwardIterator __first, 972 _ForwardIterator __last, 973 allocator<_Tp>&) 974 { std::__uninitialized_default(__first, __last); } 975 #endif 976 977 // __uninitialized_default_n_a 978 // Fills [first, first + n) with value_types constructed by the allocator 979 // alloc, with no arguments passed to the construct call. 980 template<typename _ForwardIterator, typename _Size, typename _Allocator> 981 _GLIBCXX20_CONSTEXPR _ForwardIterator 982 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 983 _Allocator& __alloc) 984 { 985 _UninitDestroyGuard<_ForwardIterator, _Allocator> __guard(__first, 986 __alloc); 987 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 988 for (; __n > 0; --__n, (void) ++__first) 989 __traits::construct(__alloc, std::__addressof(*__first)); 990 __guard.release(); 991 return __first; 992 } 993 994 #if _GLIBCXX_HOSTED 995 // __uninitialized_default_n_a specialization for std::allocator, 996 // which ignores the allocator and value-initializes the elements. 997 template<typename _ForwardIterator, typename _Size, typename _Tp> 998 _GLIBCXX20_CONSTEXPR 999 inline _ForwardIterator 1000 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 1001 allocator<_Tp>&) 1002 { return std::__uninitialized_default_n(__first, __n); } 1003 #endif 1004 1005 template<bool _TrivialValueType> 1006 struct __uninitialized_default_novalue_1 1007 { 1008 template<typename _ForwardIterator> 1009 _GLIBCXX26_CONSTEXPR 1010 static void 1011 __uninit_default_novalue(_ForwardIterator __first, 1012 _ForwardIterator __last) 1013 { 1014 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 1015 for (; __first != __last; ++__first) 1016 std::_Construct_novalue(std::__addressof(*__first)); 1017 __guard.release(); 1018 } 1019 }; 1020 1021 template<> 1022 struct __uninitialized_default_novalue_1<true> 1023 { 1024 template<typename _ForwardIterator> 1025 _GLIBCXX26_CONSTEXPR 1026 static void 1027 __uninit_default_novalue(_ForwardIterator, _ForwardIterator) 1028 { 1029 } 1030 }; 1031 1032 template<bool _TrivialValueType> 1033 struct __uninitialized_default_novalue_n_1 1034 { 1035 template<typename _ForwardIterator, typename _Size> 1036 _GLIBCXX26_CONSTEXPR 1037 static _ForwardIterator 1038 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 1039 { 1040 _UninitDestroyGuard<_ForwardIterator> __guard(__first); 1041 for (; __n > 0; --__n, (void) ++__first) 1042 std::_Construct_novalue(std::__addressof(*__first)); 1043 __guard.release(); 1044 return __first; 1045 } 1046 }; 1047 1048 template<> 1049 struct __uninitialized_default_novalue_n_1<true> 1050 { 1051 template<typename _ForwardIterator, typename _Size> 1052 _GLIBCXX26_CONSTEXPR 1053 static _ForwardIterator 1054 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 1055 { return std::next(__first, __n); } 1056 }; 1057 1058 // __uninitialized_default_novalue 1059 // Fills [first, last) with default-initialized value_types. 1060 template<typename _ForwardIterator> 1061 _GLIBCXX26_CONSTEXPR 1062 inline void 1063 __uninitialized_default_novalue(_ForwardIterator __first, 1064 _ForwardIterator __last) 1065 { 1066 typedef typename iterator_traits<_ForwardIterator>::value_type 1067 _ValueType; 1068 1069 std::__uninitialized_default_novalue_1< 1070 is_trivially_default_constructible<_ValueType>::value>:: 1071 __uninit_default_novalue(__first, __last); 1072 } 1073 1074 // __uninitialized_default_novalue_n 1075 // Fills [first, first + n) with default-initialized value_types. 1076 template<typename _ForwardIterator, typename _Size> 1077 _GLIBCXX26_CONSTEXPR 1078 inline _ForwardIterator 1079 __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) 1080 { 1081 typedef typename iterator_traits<_ForwardIterator>::value_type 1082 _ValueType; 1083 1084 return __uninitialized_default_novalue_n_1< 1085 is_trivially_default_constructible<_ValueType>::value>:: 1086 __uninit_default_novalue_n(__first, __n); 1087 } 1088 1089 template<typename _InputIterator, typename _Size, 1090 typename _ForwardIterator> 1091 _GLIBCXX26_CONSTEXPR 1092 _ForwardIterator 1093 __uninitialized_copy_n(_InputIterator __first, _Size __n, 1094 _ForwardIterator __result, input_iterator_tag) 1095 { 1096 _UninitDestroyGuard<_ForwardIterator> __guard(__result); 1097 for (; __n > 0; --__n, (void) ++__first, ++__result) 1098 std::_Construct(std::__addressof(*__result), *__first); 1099 __guard.release(); 1100 return __result; 1101 } 1102 1103 template<typename _RandomAccessIterator, typename _Size, 1104 typename _ForwardIterator> 1105 _GLIBCXX26_CONSTEXPR 1106 inline _ForwardIterator 1107 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 1108 _ForwardIterator __result, 1109 random_access_iterator_tag) 1110 { return std::uninitialized_copy(__first, __first + __n, __result); } 1111 1112 template<typename _InputIterator, typename _Size, 1113 typename _ForwardIterator> 1114 _GLIBCXX26_CONSTEXPR 1115 pair<_InputIterator, _ForwardIterator> 1116 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 1117 _ForwardIterator __result, input_iterator_tag) 1118 { 1119 _UninitDestroyGuard<_ForwardIterator> __guard(__result); 1120 for (; __n > 0; --__n, (void) ++__first, ++__result) 1121 std::_Construct(std::__addressof(*__result), *__first); 1122 __guard.release(); 1123 return {__first, __result}; 1124 } 1125 1126 template<typename _RandomAccessIterator, typename _Size, 1127 typename _ForwardIterator> 1128 _GLIBCXX26_CONSTEXPR 1129 inline pair<_RandomAccessIterator, _ForwardIterator> 1130 __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, 1131 _ForwardIterator __result, 1132 random_access_iterator_tag) 1133 { 1134 auto __second_res = uninitialized_copy(__first, __first + __n, __result); 1135 auto __first_res = std::next(__first, __n); 1136 return {__first_res, __second_res}; 1137 } 1138 1139 /// @endcond 1140 1141 /** 1142 * @brief Copies the range [first,first+n) into result. 1143 * @param __first An input iterator. 1144 * @param __n The number of elements to copy. 1145 * @param __result An output iterator. 1146 * @return __result + __n 1147 * @since C++11 1148 * 1149 * Like copy_n(), but does not require an initialized output range. 1150 */ 1151 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 1152 _GLIBCXX26_CONSTEXPR 1153 inline _ForwardIterator 1154 uninitialized_copy_n(_InputIterator __first, _Size __n, 1155 _ForwardIterator __result) 1156 { return std::__uninitialized_copy_n(__first, __n, __result, 1157 std::__iterator_category(__first)); } 1158 1159 /// @cond undocumented 1160 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 1161 _GLIBCXX26_CONSTEXPR 1162 inline pair<_InputIterator, _ForwardIterator> 1163 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 1164 _ForwardIterator __result) 1165 { 1166 return 1167 std::__uninitialized_copy_n_pair(__first, __n, __result, 1168 std::__iterator_category(__first)); 1169 } 1170 /// @endcond 1171 #endif 1172 1173 #ifdef __glibcxx_raw_memory_algorithms // C++ >= 17 1174 /** 1175 * @brief Default-initializes objects in the range [first,last). 1176 * @param __first A forward iterator. 1177 * @param __last A forward iterator. 1178 * @since C++17 1179 */ 1180 template <typename _ForwardIterator> 1181 _GLIBCXX26_CONSTEXPR 1182 inline void 1183 uninitialized_default_construct(_ForwardIterator __first, 1184 _ForwardIterator __last) 1185 { 1186 std::__uninitialized_default_novalue(__first, __last); 1187 } 1188 1189 /** 1190 * @brief Default-initializes objects in the range [first,first+count). 1191 * @param __first A forward iterator. 1192 * @param __count The number of objects to construct. 1193 * @return __first + __count 1194 * @since C++17 1195 */ 1196 template <typename _ForwardIterator, typename _Size> 1197 _GLIBCXX26_CONSTEXPR 1198 inline _ForwardIterator 1199 uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) 1200 { 1201 return std::__uninitialized_default_novalue_n(__first, __count); 1202 } 1203 1204 /** 1205 * @brief Value-initializes objects in the range [first,last). 1206 * @param __first A forward iterator. 1207 * @param __last A forward iterator. 1208 * @since C++17 1209 */ 1210 template <typename _ForwardIterator> 1211 _GLIBCXX26_CONSTEXPR 1212 inline void 1213 uninitialized_value_construct(_ForwardIterator __first, 1214 _ForwardIterator __last) 1215 { 1216 return std::__uninitialized_default(__first, __last); 1217 } 1218 1219 /** 1220 * @brief Value-initializes objects in the range [first,first+count). 1221 * @param __first A forward iterator. 1222 * @param __count The number of objects to construct. 1223 * @return __result + __count 1224 * @since C++17 1225 */ 1226 template <typename _ForwardIterator, typename _Size> 1227 _GLIBCXX26_CONSTEXPR 1228 inline _ForwardIterator 1229 uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) 1230 { 1231 return std::__uninitialized_default_n(__first, __count); 1232 } 1233 1234 /** 1235 * @brief Move-construct from the range [first,last) into result. 1236 * @param __first An input iterator. 1237 * @param __last An input iterator. 1238 * @param __result An output iterator. 1239 * @return __result + (__first - __last) 1240 * @since C++17 1241 */ 1242 template <typename _InputIterator, typename _ForwardIterator> 1243 _GLIBCXX26_CONSTEXPR 1244 inline _ForwardIterator 1245 uninitialized_move(_InputIterator __first, _InputIterator __last, 1246 _ForwardIterator __result) 1247 { 1248 return std::uninitialized_copy 1249 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 1250 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); 1251 } 1252 1253 /** 1254 * @brief Move-construct from the range [first,first+count) into result. 1255 * @param __first An input iterator. 1256 * @param __count The number of objects to initialize. 1257 * @param __result An output iterator. 1258 * @return __result + __count 1259 * @since C++17 1260 */ 1261 template <typename _InputIterator, typename _Size, typename _ForwardIterator> 1262 _GLIBCXX26_CONSTEXPR 1263 inline pair<_InputIterator, _ForwardIterator> 1264 uninitialized_move_n(_InputIterator __first, _Size __count, 1265 _ForwardIterator __result) 1266 { 1267 auto __res = std::__uninitialized_copy_n_pair 1268 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 1269 __count, __result); 1270 return {__res.first.base(), __res.second}; 1271 } 1272 #endif // __glibcxx_raw_memory_algorithms 1273 1274 #if __cplusplus >= 201103L 1275 /// @cond undocumented 1276 1277 template<typename _Tp, typename _Up, typename _Allocator> 1278 _GLIBCXX20_CONSTEXPR 1279 inline void 1280 __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, 1281 _Allocator& __alloc) 1282 noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, 1283 __dest, std::move(*__orig))) 1284 && noexcept(std::allocator_traits<_Allocator>::destroy( 1285 __alloc, std::__addressof(*__orig)))) 1286 { 1287 typedef std::allocator_traits<_Allocator> __traits; 1288 __traits::construct(__alloc, __dest, std::move(*__orig)); 1289 __traits::destroy(__alloc, std::__addressof(*__orig)); 1290 } 1291 1292 // This class may be specialized for specific types. 1293 // Also known as is_trivially_relocatable. 1294 template<typename _Tp, typename = void> 1295 struct __is_bitwise_relocatable 1296 : __bool_constant<__is_trivial(_Tp)> 1297 { }; 1298 1299 template <typename _InputIterator, typename _ForwardIterator, 1300 typename _Allocator> 1301 _GLIBCXX20_CONSTEXPR 1302 inline _ForwardIterator 1303 __relocate_a_1(_InputIterator __first, _InputIterator __last, 1304 _ForwardIterator __result, _Allocator& __alloc) 1305 noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result), 1306 std::addressof(*__first), 1307 __alloc))) 1308 { 1309 typedef typename iterator_traits<_InputIterator>::value_type 1310 _ValueType; 1311 typedef typename iterator_traits<_ForwardIterator>::value_type 1312 _ValueType2; 1313 static_assert(std::is_same<_ValueType, _ValueType2>::value, 1314 "relocation is only possible for values of the same type"); 1315 _ForwardIterator __cur = __result; 1316 for (; __first != __last; ++__first, (void)++__cur) 1317 std::__relocate_object_a(std::__addressof(*__cur), 1318 std::__addressof(*__first), __alloc); 1319 return __cur; 1320 } 1321 1322 #if _GLIBCXX_HOSTED 1323 template <typename _Tp, typename _Up> 1324 _GLIBCXX20_CONSTEXPR 1325 inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*> 1326 __relocate_a_1(_Tp* __first, _Tp* __last, 1327 _Tp* __result, 1328 [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept 1329 { 1330 ptrdiff_t __count = __last - __first; 1331 if (__count > 0) 1332 { 1333 #ifdef __cpp_lib_is_constant_evaluated 1334 if (std::is_constant_evaluated()) 1335 { 1336 // Can't use memcpy. Wrap the pointer so that __relocate_a_1 1337 // resolves to the non-trivial overload above. 1338 __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result); 1339 __out = std::__relocate_a_1(__first, __last, __out, __alloc); 1340 return __out.base(); 1341 } 1342 #endif 1343 __builtin_memcpy(__result, __first, __count * sizeof(_Tp)); 1344 } 1345 return __result + __count; 1346 } 1347 #endif 1348 1349 template <typename _InputIterator, typename _ForwardIterator, 1350 typename _Allocator> 1351 _GLIBCXX20_CONSTEXPR 1352 inline _ForwardIterator 1353 __relocate_a(_InputIterator __first, _InputIterator __last, 1354 _ForwardIterator __result, _Allocator& __alloc) 1355 noexcept(noexcept(__relocate_a_1(std::__niter_base(__first), 1356 std::__niter_base(__last), 1357 std::__niter_base(__result), __alloc))) 1358 { 1359 return std::__relocate_a_1(std::__niter_base(__first), 1360 std::__niter_base(__last), 1361 std::__niter_base(__result), __alloc); 1362 } 1363 1364 /// @endcond 1365 #endif // C++11 1366 1367 /// @} group memory 1368 1369 _GLIBCXX_END_NAMESPACE_VERSION 1370 } // namespace 1371 1372 #endif /* _STL_UNINITIALIZED_H */