1 // Raw memory manipulators -*- C++ -*- 2 3 // Copyright (C) 2001-2020 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /* 26 * 27 * Copyright (c) 1994 28 * Hewlett-Packard Company 29 * 30 * Permission to use, copy, modify, distribute and sell this software 31 * and its documentation for any purpose is hereby granted without fee, 32 * provided that the above copyright notice appear in all copies and 33 * that both that copyright notice and this permission notice appear 34 * in supporting documentation. Hewlett-Packard Company makes no 35 * representations about the suitability of this software for any 36 * purpose. It is provided "as is" without express or implied warranty. 37 * 38 * 39 * Copyright (c) 1996,1997 40 * Silicon Graphics Computer Systems, Inc. 41 * 42 * Permission to use, copy, modify, distribute and sell this software 43 * and its documentation for any purpose is hereby granted without fee, 44 * provided that the above copyright notice appear in all copies and 45 * that both that copyright notice and this permission notice appear 46 * in supporting documentation. Silicon Graphics makes no 47 * representations about the suitability of this software for any 48 * purpose. It is provided "as is" without express or implied warranty. 49 */ 50 51 /** @file bits/stl_uninitialized.h 52 * This is an internal header file, included by other library headers. 53 * Do not attempt to use it directly. @headername{memory} 54 */ 55 56 #ifndef _STL_UNINITIALIZED_H 57 #define _STL_UNINITIALIZED_H 1 58 59 #if __cplusplus > 201402L 60 #include <bits/stl_pair.h> 61 #endif 62 63 #if __cplusplus >= 201103L 64 #include <type_traits> 65 #endif 66 67 #include <ext/alloc_traits.h> 68 69 namespace std _GLIBCXX_VISIBILITY(default) 70 { 71 _GLIBCXX_BEGIN_NAMESPACE_VERSION 72 73 /** @addtogroup memory 74 * @{ 75 */ 76 77 /// @cond undocumented 78 79 template<bool _TrivialValueTypes> 80 struct __uninitialized_copy 81 { 82 template<typename _InputIterator, typename _ForwardIterator> 83 static _ForwardIterator 84 __uninit_copy(_InputIterator __first, _InputIterator __last, 85 _ForwardIterator __result) 86 { 87 _ForwardIterator __cur = __result; 88 __try 89 { 90 for (; __first != __last; ++__first, (void)++__cur) 91 std::_Construct(std::__addressof(*__cur), *__first); 92 return __cur; 93 } 94 __catch(...) 95 { 96 std::_Destroy(__result, __cur); 97 __throw_exception_again; 98 } 99 } 100 }; 101 102 template<> 103 struct __uninitialized_copy<true> 104 { 105 template<typename _InputIterator, typename _ForwardIterator> 106 static _ForwardIterator 107 __uninit_copy(_InputIterator __first, _InputIterator __last, 108 _ForwardIterator __result) 109 { return std::copy(__first, __last, __result); } 110 }; 111 112 /// @endcond 113 114 /** 115 * @brief Copies the range [first,last) into result. 116 * @param __first An input iterator. 117 * @param __last An input iterator. 118 * @param __result An output iterator. 119 * @return __result + (__first - __last) 120 * 121 * Like copy(), but does not require an initialized output range. 122 */ 123 template<typename _InputIterator, typename _ForwardIterator> 124 inline _ForwardIterator 125 uninitialized_copy(_InputIterator __first, _InputIterator __last, 126 _ForwardIterator __result) 127 { 128 typedef typename iterator_traits<_InputIterator>::value_type 129 _ValueType1; 130 typedef typename iterator_traits<_ForwardIterator>::value_type 131 _ValueType2; 132 #if __cplusplus < 201103L 133 const bool __assignable = true; 134 #else 135 // Trivial types can have deleted copy constructor, but the std::copy 136 // optimization that uses memmove would happily "copy" them anyway. 137 static_assert(is_constructible<_ValueType2, decltype(*__first)>::value, 138 "result type must be constructible from value type of input range"); 139 140 typedef typename iterator_traits<_InputIterator>::reference _RefType1; 141 typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; 142 // Trivial types can have deleted assignment, so using std::copy 143 // would be ill-formed. Require assignability before using std::copy: 144 const bool __assignable = is_assignable<_RefType2, _RefType1>::value; 145 #endif 146 147 return std::__uninitialized_copy<__is_trivial(_ValueType1) 148 && __is_trivial(_ValueType2) 149 && __assignable>:: 150 __uninit_copy(__first, __last, __result); 151 } 152 153 /// @cond undocumented 154 155 template<bool _TrivialValueType> 156 struct __uninitialized_fill 157 { 158 template<typename _ForwardIterator, typename _Tp> 159 static void 160 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 161 const _Tp& __x) 162 { 163 _ForwardIterator __cur = __first; 164 __try 165 { 166 for (; __cur != __last; ++__cur) 167 std::_Construct(std::__addressof(*__cur), __x); 168 } 169 __catch(...) 170 { 171 std::_Destroy(__first, __cur); 172 __throw_exception_again; 173 } 174 } 175 }; 176 177 template<> 178 struct __uninitialized_fill<true> 179 { 180 template<typename _ForwardIterator, typename _Tp> 181 static void 182 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 183 const _Tp& __x) 184 { std::fill(__first, __last, __x); } 185 }; 186 187 /// @endcond 188 189 /** 190 * @brief Copies the value x into the range [first,last). 191 * @param __first An input iterator. 192 * @param __last An input iterator. 193 * @param __x The source value. 194 * @return Nothing. 195 * 196 * Like fill(), but does not require an initialized output range. 197 */ 198 template<typename _ForwardIterator, typename _Tp> 199 inline void 200 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 201 const _Tp& __x) 202 { 203 typedef typename iterator_traits<_ForwardIterator>::value_type 204 _ValueType; 205 #if __cplusplus < 201103L 206 const bool __assignable = true; 207 #else 208 // Trivial types can have deleted copy constructor, but the std::fill 209 // optimization that uses memmove would happily "copy" them anyway. 210 static_assert(is_constructible<_ValueType, const _Tp&>::value, 211 "result type must be constructible from input type"); 212 213 // Trivial types can have deleted assignment, so using std::fill 214 // would be ill-formed. Require assignability before using std::fill: 215 const bool __assignable = is_copy_assignable<_ValueType>::value; 216 #endif 217 218 std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: 219 __uninit_fill(__first, __last, __x); 220 } 221 222 /// @cond undocumented 223 224 template<bool _TrivialValueType> 225 struct __uninitialized_fill_n 226 { 227 template<typename _ForwardIterator, typename _Size, typename _Tp> 228 static _ForwardIterator 229 __uninit_fill_n(_ForwardIterator __first, _Size __n, 230 const _Tp& __x) 231 { 232 _ForwardIterator __cur = __first; 233 __try 234 { 235 for (; __n > 0; --__n, (void) ++__cur) 236 std::_Construct(std::__addressof(*__cur), __x); 237 return __cur; 238 } 239 __catch(...) 240 { 241 std::_Destroy(__first, __cur); 242 __throw_exception_again; 243 } 244 } 245 }; 246 247 template<> 248 struct __uninitialized_fill_n<true> 249 { 250 template<typename _ForwardIterator, typename _Size, typename _Tp> 251 static _ForwardIterator 252 __uninit_fill_n(_ForwardIterator __first, _Size __n, 253 const _Tp& __x) 254 { return std::fill_n(__first, __n, __x); } 255 }; 256 257 /// @endcond 258 259 // _GLIBCXX_RESOLVE_LIB_DEFECTS 260 // DR 1339. uninitialized_fill_n should return the end of its range 261 /** 262 * @brief Copies the value x into the range [first,first+n). 263 * @param __first An input iterator. 264 * @param __n The number of copies to make. 265 * @param __x The source value. 266 * @return Nothing. 267 * 268 * Like fill_n(), but does not require an initialized output range. 269 */ 270 template<typename _ForwardIterator, typename _Size, typename _Tp> 271 inline _ForwardIterator 272 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 273 { 274 typedef typename iterator_traits<_ForwardIterator>::value_type 275 _ValueType; 276 #if __cplusplus < 201103L 277 const bool __assignable = true; 278 #else 279 // Trivial types can have deleted copy constructor, but the std::fill 280 // optimization that uses memmove would happily "copy" them anyway. 281 static_assert(is_constructible<_ValueType, const _Tp&>::value, 282 "result type must be constructible from input type"); 283 284 // Trivial types can have deleted assignment, so using std::fill 285 // would be ill-formed. Require assignability before using std::fill: 286 const bool __assignable = is_copy_assignable<_ValueType>::value; 287 #endif 288 return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: 289 __uninit_fill_n(__first, __n, __x); 290 } 291 292 /// @cond undocumented 293 294 // Extensions: versions of uninitialized_copy, uninitialized_fill, 295 // and uninitialized_fill_n that take an allocator parameter. 296 // We dispatch back to the standard versions when we're given the 297 // default allocator. For nondefault allocators we do not use 298 // any of the POD optimizations. 299 300 template<typename _InputIterator, typename _ForwardIterator, 301 typename _Allocator> 302 _ForwardIterator 303 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 304 _ForwardIterator __result, _Allocator& __alloc) 305 { 306 _ForwardIterator __cur = __result; 307 __try 308 { 309 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 310 for (; __first != __last; ++__first, (void)++__cur) 311 __traits::construct(__alloc, std::__addressof(*__cur), *__first); 312 return __cur; 313 } 314 __catch(...) 315 { 316 std::_Destroy(__result, __cur, __alloc); 317 __throw_exception_again; 318 } 319 } 320 321 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 322 inline _ForwardIterator 323 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 324 _ForwardIterator __result, allocator<_Tp>&) 325 { return std::uninitialized_copy(__first, __last, __result); } 326 327 template<typename _InputIterator, typename _ForwardIterator, 328 typename _Allocator> 329 inline _ForwardIterator 330 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 331 _ForwardIterator __result, _Allocator& __alloc) 332 { 333 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 334 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 335 __result, __alloc); 336 } 337 338 template<typename _InputIterator, typename _ForwardIterator, 339 typename _Allocator> 340 inline _ForwardIterator 341 __uninitialized_move_if_noexcept_a(_InputIterator __first, 342 _InputIterator __last, 343 _ForwardIterator __result, 344 _Allocator& __alloc) 345 { 346 return std::__uninitialized_copy_a 347 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), 348 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); 349 } 350 351 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 352 void 353 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 354 const _Tp& __x, _Allocator& __alloc) 355 { 356 _ForwardIterator __cur = __first; 357 __try 358 { 359 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 360 for (; __cur != __last; ++__cur) 361 __traits::construct(__alloc, std::__addressof(*__cur), __x); 362 } 363 __catch(...) 364 { 365 std::_Destroy(__first, __cur, __alloc); 366 __throw_exception_again; 367 } 368 } 369 370 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 371 inline void 372 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 373 const _Tp& __x, allocator<_Tp2>&) 374 { std::uninitialized_fill(__first, __last, __x); } 375 376 template<typename _ForwardIterator, typename _Size, typename _Tp, 377 typename _Allocator> 378 _ForwardIterator 379 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 380 const _Tp& __x, _Allocator& __alloc) 381 { 382 _ForwardIterator __cur = __first; 383 __try 384 { 385 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 386 for (; __n > 0; --__n, (void) ++__cur) 387 __traits::construct(__alloc, std::__addressof(*__cur), __x); 388 return __cur; 389 } 390 __catch(...) 391 { 392 std::_Destroy(__first, __cur, __alloc); 393 __throw_exception_again; 394 } 395 } 396 397 template<typename _ForwardIterator, typename _Size, typename _Tp, 398 typename _Tp2> 399 inline _ForwardIterator 400 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 401 const _Tp& __x, allocator<_Tp2>&) 402 { return std::uninitialized_fill_n(__first, __n, __x); } 403 404 405 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 406 // __uninitialized_fill_move, __uninitialized_move_fill. 407 // All of these algorithms take a user-supplied allocator, which is used 408 // for construction and destruction. 409 410 // __uninitialized_copy_move 411 // Copies [first1, last1) into [result, result + (last1 - first1)), and 412 // move [first2, last2) into 413 // [result, result + (last1 - first1) + (last2 - first2)). 414 template<typename _InputIterator1, typename _InputIterator2, 415 typename _ForwardIterator, typename _Allocator> 416 inline _ForwardIterator 417 __uninitialized_copy_move(_InputIterator1 __first1, 418 _InputIterator1 __last1, 419 _InputIterator2 __first2, 420 _InputIterator2 __last2, 421 _ForwardIterator __result, 422 _Allocator& __alloc) 423 { 424 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 425 __result, 426 __alloc); 427 __try 428 { 429 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 430 } 431 __catch(...) 432 { 433 std::_Destroy(__result, __mid, __alloc); 434 __throw_exception_again; 435 } 436 } 437 438 // __uninitialized_move_copy 439 // Moves [first1, last1) into [result, result + (last1 - first1)), and 440 // copies [first2, last2) into 441 // [result, result + (last1 - first1) + (last2 - first2)). 442 template<typename _InputIterator1, typename _InputIterator2, 443 typename _ForwardIterator, typename _Allocator> 444 inline _ForwardIterator 445 __uninitialized_move_copy(_InputIterator1 __first1, 446 _InputIterator1 __last1, 447 _InputIterator2 __first2, 448 _InputIterator2 __last2, 449 _ForwardIterator __result, 450 _Allocator& __alloc) 451 { 452 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 453 __result, 454 __alloc); 455 __try 456 { 457 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 458 } 459 __catch(...) 460 { 461 std::_Destroy(__result, __mid, __alloc); 462 __throw_exception_again; 463 } 464 } 465 466 // __uninitialized_fill_move 467 // Fills [result, mid) with x, and moves [first, last) into 468 // [mid, mid + (last - first)). 469 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 470 typename _Allocator> 471 inline _ForwardIterator 472 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 473 const _Tp& __x, _InputIterator __first, 474 _InputIterator __last, _Allocator& __alloc) 475 { 476 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 477 __try 478 { 479 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 480 } 481 __catch(...) 482 { 483 std::_Destroy(__result, __mid, __alloc); 484 __throw_exception_again; 485 } 486 } 487 488 // __uninitialized_move_fill 489 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 490 // fills [first2 + (last1 - first1), last2) with x. 491 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 492 typename _Allocator> 493 inline void 494 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 495 _ForwardIterator __first2, 496 _ForwardIterator __last2, const _Tp& __x, 497 _Allocator& __alloc) 498 { 499 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 500 __first2, 501 __alloc); 502 __try 503 { 504 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 505 } 506 __catch(...) 507 { 508 std::_Destroy(__first2, __mid2, __alloc); 509 __throw_exception_again; 510 } 511 } 512 513 /// @endcond 514 515 #if __cplusplus >= 201103L 516 /// @cond undocumented 517 518 // Extensions: __uninitialized_default, __uninitialized_default_n, 519 // __uninitialized_default_a, __uninitialized_default_n_a. 520 521 template<bool _TrivialValueType> 522 struct __uninitialized_default_1 523 { 524 template<typename _ForwardIterator> 525 static void 526 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 527 { 528 _ForwardIterator __cur = __first; 529 __try 530 { 531 for (; __cur != __last; ++__cur) 532 std::_Construct(std::__addressof(*__cur)); 533 } 534 __catch(...) 535 { 536 std::_Destroy(__first, __cur); 537 __throw_exception_again; 538 } 539 } 540 }; 541 542 template<> 543 struct __uninitialized_default_1<true> 544 { 545 template<typename _ForwardIterator> 546 static void 547 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 548 { 549 typedef typename iterator_traits<_ForwardIterator>::value_type 550 _ValueType; 551 552 if (__first == __last) 553 return; 554 555 typename iterator_traits<_ForwardIterator>::value_type* __val 556 = std::__addressof(*__first); 557 std::_Construct(__val); 558 if (++__first != __last) 559 std::fill(__first, __last, *__val); 560 } 561 }; 562 563 template<bool _TrivialValueType> 564 struct __uninitialized_default_n_1 565 { 566 template<typename _ForwardIterator, typename _Size> 567 static _ForwardIterator 568 __uninit_default_n(_ForwardIterator __first, _Size __n) 569 { 570 _ForwardIterator __cur = __first; 571 __try 572 { 573 for (; __n > 0; --__n, (void) ++__cur) 574 std::_Construct(std::__addressof(*__cur)); 575 return __cur; 576 } 577 __catch(...) 578 { 579 std::_Destroy(__first, __cur); 580 __throw_exception_again; 581 } 582 } 583 }; 584 585 template<> 586 struct __uninitialized_default_n_1<true> 587 { 588 template<typename _ForwardIterator, typename _Size> 589 static _ForwardIterator 590 __uninit_default_n(_ForwardIterator __first, _Size __n) 591 { 592 if (__n > 0) 593 { 594 typename iterator_traits<_ForwardIterator>::value_type* __val 595 = std::__addressof(*__first); 596 std::_Construct(__val); 597 ++__first; 598 __first = std::fill_n(__first, __n - 1, *__val); 599 } 600 return __first; 601 } 602 }; 603 604 // __uninitialized_default 605 // Fills [first, last) with value-initialized value_types. 606 template<typename _ForwardIterator> 607 inline void 608 __uninitialized_default(_ForwardIterator __first, 609 _ForwardIterator __last) 610 { 611 typedef typename iterator_traits<_ForwardIterator>::value_type 612 _ValueType; 613 // trivial types can have deleted assignment 614 const bool __assignable = is_copy_assignable<_ValueType>::value; 615 616 std::__uninitialized_default_1<__is_trivial(_ValueType) 617 && __assignable>:: 618 __uninit_default(__first, __last); 619 } 620 621 // __uninitialized_default_n 622 // Fills [first, first + n) with value-initialized value_types. 623 template<typename _ForwardIterator, typename _Size> 624 inline _ForwardIterator 625 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 626 { 627 typedef typename iterator_traits<_ForwardIterator>::value_type 628 _ValueType; 629 // trivial types can have deleted assignment 630 const bool __assignable = is_copy_assignable<_ValueType>::value; 631 632 return __uninitialized_default_n_1<__is_trivial(_ValueType) 633 && __assignable>:: 634 __uninit_default_n(__first, __n); 635 } 636 637 638 // __uninitialized_default_a 639 // Fills [first, last) with value_types constructed by the allocator 640 // alloc, with no arguments passed to the construct call. 641 template<typename _ForwardIterator, typename _Allocator> 642 void 643 __uninitialized_default_a(_ForwardIterator __first, 644 _ForwardIterator __last, 645 _Allocator& __alloc) 646 { 647 _ForwardIterator __cur = __first; 648 __try 649 { 650 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 651 for (; __cur != __last; ++__cur) 652 __traits::construct(__alloc, std::__addressof(*__cur)); 653 } 654 __catch(...) 655 { 656 std::_Destroy(__first, __cur, __alloc); 657 __throw_exception_again; 658 } 659 } 660 661 template<typename _ForwardIterator, typename _Tp> 662 inline void 663 __uninitialized_default_a(_ForwardIterator __first, 664 _ForwardIterator __last, 665 allocator<_Tp>&) 666 { std::__uninitialized_default(__first, __last); } 667 668 669 // __uninitialized_default_n_a 670 // Fills [first, first + n) with value_types constructed by the allocator 671 // alloc, with no arguments passed to the construct call. 672 template<typename _ForwardIterator, typename _Size, typename _Allocator> 673 _ForwardIterator 674 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 675 _Allocator& __alloc) 676 { 677 _ForwardIterator __cur = __first; 678 __try 679 { 680 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 681 for (; __n > 0; --__n, (void) ++__cur) 682 __traits::construct(__alloc, std::__addressof(*__cur)); 683 return __cur; 684 } 685 __catch(...) 686 { 687 std::_Destroy(__first, __cur, __alloc); 688 __throw_exception_again; 689 } 690 } 691 692 // __uninitialized_default_n_a specialization for std::allocator, 693 // which ignores the allocator and value-initializes the elements. 694 template<typename _ForwardIterator, typename _Size, typename _Tp> 695 inline _ForwardIterator 696 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 697 allocator<_Tp>&) 698 { return std::__uninitialized_default_n(__first, __n); } 699 700 template<bool _TrivialValueType> 701 struct __uninitialized_default_novalue_1 702 { 703 template<typename _ForwardIterator> 704 static void 705 __uninit_default_novalue(_ForwardIterator __first, 706 _ForwardIterator __last) 707 { 708 _ForwardIterator __cur = __first; 709 __try 710 { 711 for (; __cur != __last; ++__cur) 712 std::_Construct_novalue(std::__addressof(*__cur)); 713 } 714 __catch(...) 715 { 716 std::_Destroy(__first, __cur); 717 __throw_exception_again; 718 } 719 } 720 }; 721 722 template<> 723 struct __uninitialized_default_novalue_1<true> 724 { 725 template<typename _ForwardIterator> 726 static void 727 __uninit_default_novalue(_ForwardIterator __first, 728 _ForwardIterator __last) 729 { 730 } 731 }; 732 733 template<bool _TrivialValueType> 734 struct __uninitialized_default_novalue_n_1 735 { 736 template<typename _ForwardIterator, typename _Size> 737 static _ForwardIterator 738 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 739 { 740 _ForwardIterator __cur = __first; 741 __try 742 { 743 for (; __n > 0; --__n, (void) ++__cur) 744 std::_Construct_novalue(std::__addressof(*__cur)); 745 return __cur; 746 } 747 __catch(...) 748 { 749 std::_Destroy(__first, __cur); 750 __throw_exception_again; 751 } 752 } 753 }; 754 755 template<> 756 struct __uninitialized_default_novalue_n_1<true> 757 { 758 template<typename _ForwardIterator, typename _Size> 759 static _ForwardIterator 760 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 761 { return std::next(__first, __n); } 762 }; 763 764 // __uninitialized_default_novalue 765 // Fills [first, last) with default-initialized value_types. 766 template<typename _ForwardIterator> 767 inline void 768 __uninitialized_default_novalue(_ForwardIterator __first, 769 _ForwardIterator __last) 770 { 771 typedef typename iterator_traits<_ForwardIterator>::value_type 772 _ValueType; 773 774 std::__uninitialized_default_novalue_1< 775 is_trivially_default_constructible<_ValueType>::value>:: 776 __uninit_default_novalue(__first, __last); 777 } 778 779 // __uninitialized_default_novalue_n 780 // Fills [first, first + n) with default-initialized value_types. 781 template<typename _ForwardIterator, typename _Size> 782 inline _ForwardIterator 783 __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) 784 { 785 typedef typename iterator_traits<_ForwardIterator>::value_type 786 _ValueType; 787 788 return __uninitialized_default_novalue_n_1< 789 is_trivially_default_constructible<_ValueType>::value>:: 790 __uninit_default_novalue_n(__first, __n); 791 } 792 793 template<typename _InputIterator, typename _Size, 794 typename _ForwardIterator> 795 _ForwardIterator 796 __uninitialized_copy_n(_InputIterator __first, _Size __n, 797 _ForwardIterator __result, input_iterator_tag) 798 { 799 _ForwardIterator __cur = __result; 800 __try 801 { 802 for (; __n > 0; --__n, (void) ++__first, ++__cur) 803 std::_Construct(std::__addressof(*__cur), *__first); 804 return __cur; 805 } 806 __catch(...) 807 { 808 std::_Destroy(__result, __cur); 809 __throw_exception_again; 810 } 811 } 812 813 template<typename _RandomAccessIterator, typename _Size, 814 typename _ForwardIterator> 815 inline _ForwardIterator 816 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 817 _ForwardIterator __result, 818 random_access_iterator_tag) 819 { return std::uninitialized_copy(__first, __first + __n, __result); } 820 821 template<typename _InputIterator, typename _Size, 822 typename _ForwardIterator> 823 pair<_InputIterator, _ForwardIterator> 824 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 825 _ForwardIterator __result, input_iterator_tag) 826 { 827 _ForwardIterator __cur = __result; 828 __try 829 { 830 for (; __n > 0; --__n, (void) ++__first, ++__cur) 831 std::_Construct(std::__addressof(*__cur), *__first); 832 return {__first, __cur}; 833 } 834 __catch(...) 835 { 836 std::_Destroy(__result, __cur); 837 __throw_exception_again; 838 } 839 } 840 841 template<typename _RandomAccessIterator, typename _Size, 842 typename _ForwardIterator> 843 inline pair<_RandomAccessIterator, _ForwardIterator> 844 __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, 845 _ForwardIterator __result, 846 random_access_iterator_tag) 847 { 848 auto __second_res = uninitialized_copy(__first, __first + __n, __result); 849 auto __first_res = std::next(__first, __n); 850 return {__first_res, __second_res}; 851 } 852 853 /// @endcond 854 855 /** 856 * @brief Copies the range [first,first+n) into result. 857 * @param __first An input iterator. 858 * @param __n The number of elements to copy. 859 * @param __result An output iterator. 860 * @return __result + __n 861 * 862 * Like copy_n(), but does not require an initialized output range. 863 */ 864 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 865 inline _ForwardIterator 866 uninitialized_copy_n(_InputIterator __first, _Size __n, 867 _ForwardIterator __result) 868 { return std::__uninitialized_copy_n(__first, __n, __result, 869 std::__iterator_category(__first)); } 870 871 /// @cond undocumented 872 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 873 inline pair<_InputIterator, _ForwardIterator> 874 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 875 _ForwardIterator __result) 876 { 877 return 878 std::__uninitialized_copy_n_pair(__first, __n, __result, 879 std::__iterator_category(__first)); 880 } 881 /// @endcond 882 #endif 883 884 #if __cplusplus >= 201703L 885 # define __cpp_lib_raw_memory_algorithms 201606L 886 887 /** 888 * @brief Default-initializes objects in the range [first,last). 889 * @param __first A forward iterator. 890 * @param __last A forward iterator. 891 */ 892 template <typename _ForwardIterator> 893 inline void 894 uninitialized_default_construct(_ForwardIterator __first, 895 _ForwardIterator __last) 896 { 897 __uninitialized_default_novalue(__first, __last); 898 } 899 900 /** 901 * @brief Default-initializes objects in the range [first,first+count). 902 * @param __first A forward iterator. 903 * @param __count The number of objects to construct. 904 * @return __first + __count 905 */ 906 template <typename _ForwardIterator, typename _Size> 907 inline _ForwardIterator 908 uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) 909 { 910 return __uninitialized_default_novalue_n(__first, __count); 911 } 912 913 /** 914 * @brief Value-initializes objects in the range [first,last). 915 * @param __first A forward iterator. 916 * @param __last A forward iterator. 917 */ 918 template <typename _ForwardIterator> 919 inline void 920 uninitialized_value_construct(_ForwardIterator __first, 921 _ForwardIterator __last) 922 { 923 return __uninitialized_default(__first, __last); 924 } 925 926 /** 927 * @brief Value-initializes objects in the range [first,first+count). 928 * @param __first A forward iterator. 929 * @param __count The number of objects to construct. 930 * @return __result + __count 931 */ 932 template <typename _ForwardIterator, typename _Size> 933 inline _ForwardIterator 934 uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) 935 { 936 return __uninitialized_default_n(__first, __count); 937 } 938 939 /** 940 * @brief Move-construct from the range [first,last) into result. 941 * @param __first An input iterator. 942 * @param __last An input iterator. 943 * @param __result An output iterator. 944 * @return __result + (__first - __last) 945 */ 946 template <typename _InputIterator, typename _ForwardIterator> 947 inline _ForwardIterator 948 uninitialized_move(_InputIterator __first, _InputIterator __last, 949 _ForwardIterator __result) 950 { 951 return std::uninitialized_copy 952 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 953 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); 954 } 955 956 /** 957 * @brief Move-construct from the range [first,first+count) into result. 958 * @param __first An input iterator. 959 * @param __count The number of objects to initialize. 960 * @param __result An output iterator. 961 * @return __result + __count 962 */ 963 template <typename _InputIterator, typename _Size, typename _ForwardIterator> 964 inline pair<_InputIterator, _ForwardIterator> 965 uninitialized_move_n(_InputIterator __first, _Size __count, 966 _ForwardIterator __result) 967 { 968 auto __res = std::__uninitialized_copy_n_pair 969 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 970 __count, __result); 971 return {__res.first.base(), __res.second}; 972 } 973 #endif // C++17 974 975 #if __cplusplus >= 201103L 976 /// @cond undocumented 977 978 template<typename _Tp, typename _Up, typename _Allocator> 979 inline void 980 __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, 981 _Allocator& __alloc) 982 noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, 983 __dest, std::move(*__orig))) 984 && noexcept(std::allocator_traits<_Allocator>::destroy( 985 __alloc, std::__addressof(*__orig)))) 986 { 987 typedef std::allocator_traits<_Allocator> __traits; 988 __traits::construct(__alloc, __dest, std::move(*__orig)); 989 __traits::destroy(__alloc, std::__addressof(*__orig)); 990 } 991 992 // This class may be specialized for specific types. 993 // Also known as is_trivially_relocatable. 994 template<typename _Tp, typename = void> 995 struct __is_bitwise_relocatable 996 : is_trivial<_Tp> { }; 997 998 template <typename _Tp, typename _Up> 999 inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*> 1000 __relocate_a_1(_Tp* __first, _Tp* __last, 1001 _Tp* __result, allocator<_Up>&) noexcept 1002 { 1003 ptrdiff_t __count = __last - __first; 1004 if (__count > 0) 1005 __builtin_memmove(__result, __first, __count * sizeof(_Tp)); 1006 return __result + __count; 1007 } 1008 1009 template <typename _InputIterator, typename _ForwardIterator, 1010 typename _Allocator> 1011 inline _ForwardIterator 1012 __relocate_a_1(_InputIterator __first, _InputIterator __last, 1013 _ForwardIterator __result, _Allocator& __alloc) 1014 noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result), 1015 std::addressof(*__first), 1016 __alloc))) 1017 { 1018 typedef typename iterator_traits<_InputIterator>::value_type 1019 _ValueType; 1020 typedef typename iterator_traits<_ForwardIterator>::value_type 1021 _ValueType2; 1022 static_assert(std::is_same<_ValueType, _ValueType2>::value, 1023 "relocation is only possible for values of the same type"); 1024 _ForwardIterator __cur = __result; 1025 for (; __first != __last; ++__first, (void)++__cur) 1026 std::__relocate_object_a(std::__addressof(*__cur), 1027 std::__addressof(*__first), __alloc); 1028 return __cur; 1029 } 1030 1031 template <typename _InputIterator, typename _ForwardIterator, 1032 typename _Allocator> 1033 inline _ForwardIterator 1034 __relocate_a(_InputIterator __first, _InputIterator __last, 1035 _ForwardIterator __result, _Allocator& __alloc) 1036 noexcept(noexcept(__relocate_a_1(std::__niter_base(__first), 1037 std::__niter_base(__last), 1038 std::__niter_base(__result), __alloc))) 1039 { 1040 return __relocate_a_1(std::__niter_base(__first), 1041 std::__niter_base(__last), 1042 std::__niter_base(__result), __alloc); 1043 } 1044 1045 /// @endcond 1046 #endif 1047 1048 /// @} group memory 1049 1050 _GLIBCXX_END_NAMESPACE_VERSION 1051 } // namespace 1052 1053 #endif /* _STL_UNINITIALIZED_H */ 1054