1 // Raw memory manipulators -*- C++ -*- 2 3 // Copyright (C) 2001-2016 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 namespace std _GLIBCXX_VISIBILITY(default) 60 { 61 _GLIBCXX_BEGIN_NAMESPACE_VERSION 62 63 template<bool _TrivialValueTypes> 64 struct __uninitialized_copy 65 { 66 template<typename _InputIterator, typename _ForwardIterator> 67 static _ForwardIterator 68 __uninit_copy(_InputIterator __first, _InputIterator __last, 69 _ForwardIterator __result) 70 { 71 _ForwardIterator __cur = __result; 72 __try 73 { 74 for (; __first != __last; ++__first, (void)++__cur) 75 std::_Construct(std::__addressof(*__cur), *__first); 76 return __cur; 77 } 78 __catch(...) 79 { 80 std::_Destroy(__result, __cur); 81 __throw_exception_again; 82 } 83 } 84 }; 85 86 template<> 87 struct __uninitialized_copy<true> 88 { 89 template<typename _InputIterator, typename _ForwardIterator> 90 static _ForwardIterator 91 __uninit_copy(_InputIterator __first, _InputIterator __last, 92 _ForwardIterator __result) 93 { return std::copy(__first, __last, __result); } 94 }; 95 96 /** 97 * @brief Copies the range [first,last) into result. 98 * @param __first An input iterator. 99 * @param __last An input iterator. 100 * @param __result An output iterator. 101 * @return __result + (__first - __last) 102 * 103 * Like copy(), but does not require an initialized output range. 104 */ 105 template<typename _InputIterator, typename _ForwardIterator> 106 inline _ForwardIterator 107 uninitialized_copy(_InputIterator __first, _InputIterator __last, 108 _ForwardIterator __result) 109 { 110 typedef typename iterator_traits<_InputIterator>::value_type 111 _ValueType1; 112 typedef typename iterator_traits<_ForwardIterator>::value_type 113 _ValueType2; 114 #if __cplusplus < 201103L 115 const bool __assignable = true; 116 #else 117 // trivial types can have deleted assignment 118 typedef typename iterator_traits<_InputIterator>::reference _RefType1; 119 typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; 120 const bool __assignable = is_assignable<_RefType2, _RefType1>::value; 121 #endif 122 123 return std::__uninitialized_copy<__is_trivial(_ValueType1) 124 && __is_trivial(_ValueType2) 125 && __assignable>:: 126 __uninit_copy(__first, __last, __result); 127 } 128 129 130 template<bool _TrivialValueType> 131 struct __uninitialized_fill 132 { 133 template<typename _ForwardIterator, typename _Tp> 134 static void 135 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 136 const _Tp& __x) 137 { 138 _ForwardIterator __cur = __first; 139 __try 140 { 141 for (; __cur != __last; ++__cur) 142 std::_Construct(std::__addressof(*__cur), __x); 143 } 144 __catch(...) 145 { 146 std::_Destroy(__first, __cur); 147 __throw_exception_again; 148 } 149 } 150 }; 151 152 template<> 153 struct __uninitialized_fill<true> 154 { 155 template<typename _ForwardIterator, typename _Tp> 156 static void 157 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 158 const _Tp& __x) 159 { std::fill(__first, __last, __x); } 160 }; 161 162 /** 163 * @brief Copies the value x into the range [first,last). 164 * @param __first An input iterator. 165 * @param __last An input iterator. 166 * @param __x The source value. 167 * @return Nothing. 168 * 169 * Like fill(), but does not require an initialized output range. 170 */ 171 template<typename _ForwardIterator, typename _Tp> 172 inline void 173 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 174 const _Tp& __x) 175 { 176 typedef typename iterator_traits<_ForwardIterator>::value_type 177 _ValueType; 178 #if __cplusplus < 201103L 179 const bool __assignable = true; 180 #else 181 // trivial types can have deleted assignment 182 const bool __assignable = is_copy_assignable<_ValueType>::value; 183 #endif 184 185 std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: 186 __uninit_fill(__first, __last, __x); 187 } 188 189 190 template<bool _TrivialValueType> 191 struct __uninitialized_fill_n 192 { 193 template<typename _ForwardIterator, typename _Size, typename _Tp> 194 static _ForwardIterator 195 __uninit_fill_n(_ForwardIterator __first, _Size __n, 196 const _Tp& __x) 197 { 198 _ForwardIterator __cur = __first; 199 __try 200 { 201 for (; __n > 0; --__n, ++__cur) 202 std::_Construct(std::__addressof(*__cur), __x); 203 return __cur; 204 } 205 __catch(...) 206 { 207 std::_Destroy(__first, __cur); 208 __throw_exception_again; 209 } 210 } 211 }; 212 213 template<> 214 struct __uninitialized_fill_n<true> 215 { 216 template<typename _ForwardIterator, typename _Size, typename _Tp> 217 static _ForwardIterator 218 __uninit_fill_n(_ForwardIterator __first, _Size __n, 219 const _Tp& __x) 220 { return std::fill_n(__first, __n, __x); } 221 }; 222 223 // _GLIBCXX_RESOLVE_LIB_DEFECTS 224 // DR 1339. uninitialized_fill_n should return the end of its range 225 /** 226 * @brief Copies the value x into the range [first,first+n). 227 * @param __first An input iterator. 228 * @param __n The number of copies to make. 229 * @param __x The source value. 230 * @return Nothing. 231 * 232 * Like fill_n(), but does not require an initialized output range. 233 */ 234 template<typename _ForwardIterator, typename _Size, typename _Tp> 235 inline _ForwardIterator 236 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 237 { 238 typedef typename iterator_traits<_ForwardIterator>::value_type 239 _ValueType; 240 #if __cplusplus < 201103L 241 const bool __assignable = true; 242 #else 243 // trivial types can have deleted assignment 244 const bool __assignable = is_copy_assignable<_ValueType>::value; 245 #endif 246 return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: 247 __uninit_fill_n(__first, __n, __x); 248 } 249 250 // Extensions: versions of uninitialized_copy, uninitialized_fill, 251 // and uninitialized_fill_n that take an allocator parameter. 252 // We dispatch back to the standard versions when we're given the 253 // default allocator. For nondefault allocators we do not use 254 // any of the POD optimizations. 255 256 template<typename _InputIterator, typename _ForwardIterator, 257 typename _Allocator> 258 _ForwardIterator 259 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 260 _ForwardIterator __result, _Allocator& __alloc) 261 { 262 _ForwardIterator __cur = __result; 263 __try 264 { 265 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 266 for (; __first != __last; ++__first, (void)++__cur) 267 __traits::construct(__alloc, std::__addressof(*__cur), *__first); 268 return __cur; 269 } 270 __catch(...) 271 { 272 std::_Destroy(__result, __cur, __alloc); 273 __throw_exception_again; 274 } 275 } 276 277 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 278 inline _ForwardIterator 279 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 280 _ForwardIterator __result, allocator<_Tp>&) 281 { return std::uninitialized_copy(__first, __last, __result); } 282 283 template<typename _InputIterator, typename _ForwardIterator, 284 typename _Allocator> 285 inline _ForwardIterator 286 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 287 _ForwardIterator __result, _Allocator& __alloc) 288 { 289 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 290 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 291 __result, __alloc); 292 } 293 294 template<typename _InputIterator, typename _ForwardIterator, 295 typename _Allocator> 296 inline _ForwardIterator 297 __uninitialized_move_if_noexcept_a(_InputIterator __first, 298 _InputIterator __last, 299 _ForwardIterator __result, 300 _Allocator& __alloc) 301 { 302 return std::__uninitialized_copy_a 303 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), 304 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); 305 } 306 307 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 308 void 309 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 310 const _Tp& __x, _Allocator& __alloc) 311 { 312 _ForwardIterator __cur = __first; 313 __try 314 { 315 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 316 for (; __cur != __last; ++__cur) 317 __traits::construct(__alloc, std::__addressof(*__cur), __x); 318 } 319 __catch(...) 320 { 321 std::_Destroy(__first, __cur, __alloc); 322 __throw_exception_again; 323 } 324 } 325 326 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 327 inline void 328 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 329 const _Tp& __x, allocator<_Tp2>&) 330 { std::uninitialized_fill(__first, __last, __x); } 331 332 template<typename _ForwardIterator, typename _Size, typename _Tp, 333 typename _Allocator> 334 _ForwardIterator 335 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 336 const _Tp& __x, _Allocator& __alloc) 337 { 338 _ForwardIterator __cur = __first; 339 __try 340 { 341 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 342 for (; __n > 0; --__n, ++__cur) 343 __traits::construct(__alloc, std::__addressof(*__cur), __x); 344 return __cur; 345 } 346 __catch(...) 347 { 348 std::_Destroy(__first, __cur, __alloc); 349 __throw_exception_again; 350 } 351 } 352 353 template<typename _ForwardIterator, typename _Size, typename _Tp, 354 typename _Tp2> 355 inline _ForwardIterator 356 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 357 const _Tp& __x, allocator<_Tp2>&) 358 { return std::uninitialized_fill_n(__first, __n, __x); } 359 360 361 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 362 // __uninitialized_fill_move, __uninitialized_move_fill. 363 // All of these algorithms take a user-supplied allocator, which is used 364 // for construction and destruction. 365 366 // __uninitialized_copy_move 367 // Copies [first1, last1) into [result, result + (last1 - first1)), and 368 // move [first2, last2) into 369 // [result, result + (last1 - first1) + (last2 - first2)). 370 template<typename _InputIterator1, typename _InputIterator2, 371 typename _ForwardIterator, typename _Allocator> 372 inline _ForwardIterator 373 __uninitialized_copy_move(_InputIterator1 __first1, 374 _InputIterator1 __last1, 375 _InputIterator2 __first2, 376 _InputIterator2 __last2, 377 _ForwardIterator __result, 378 _Allocator& __alloc) 379 { 380 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 381 __result, 382 __alloc); 383 __try 384 { 385 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 386 } 387 __catch(...) 388 { 389 std::_Destroy(__result, __mid, __alloc); 390 __throw_exception_again; 391 } 392 } 393 394 // __uninitialized_move_copy 395 // Moves [first1, last1) into [result, result + (last1 - first1)), and 396 // copies [first2, last2) into 397 // [result, result + (last1 - first1) + (last2 - first2)). 398 template<typename _InputIterator1, typename _InputIterator2, 399 typename _ForwardIterator, typename _Allocator> 400 inline _ForwardIterator 401 __uninitialized_move_copy(_InputIterator1 __first1, 402 _InputIterator1 __last1, 403 _InputIterator2 __first2, 404 _InputIterator2 __last2, 405 _ForwardIterator __result, 406 _Allocator& __alloc) 407 { 408 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 409 __result, 410 __alloc); 411 __try 412 { 413 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 414 } 415 __catch(...) 416 { 417 std::_Destroy(__result, __mid, __alloc); 418 __throw_exception_again; 419 } 420 } 421 422 // __uninitialized_fill_move 423 // Fills [result, mid) with x, and moves [first, last) into 424 // [mid, mid + (last - first)). 425 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 426 typename _Allocator> 427 inline _ForwardIterator 428 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 429 const _Tp& __x, _InputIterator __first, 430 _InputIterator __last, _Allocator& __alloc) 431 { 432 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 433 __try 434 { 435 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 436 } 437 __catch(...) 438 { 439 std::_Destroy(__result, __mid, __alloc); 440 __throw_exception_again; 441 } 442 } 443 444 // __uninitialized_move_fill 445 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 446 // fills [first2 + (last1 - first1), last2) with x. 447 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 448 typename _Allocator> 449 inline void 450 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 451 _ForwardIterator __first2, 452 _ForwardIterator __last2, const _Tp& __x, 453 _Allocator& __alloc) 454 { 455 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 456 __first2, 457 __alloc); 458 __try 459 { 460 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 461 } 462 __catch(...) 463 { 464 std::_Destroy(__first2, __mid2, __alloc); 465 __throw_exception_again; 466 } 467 } 468 469 #if __cplusplus >= 201103L 470 // Extensions: __uninitialized_default, __uninitialized_default_n, 471 // __uninitialized_default_a, __uninitialized_default_n_a. 472 473 template<bool _TrivialValueType> 474 struct __uninitialized_default_1 475 { 476 template<typename _ForwardIterator> 477 static void 478 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 479 { 480 _ForwardIterator __cur = __first; 481 __try 482 { 483 for (; __cur != __last; ++__cur) 484 std::_Construct(std::__addressof(*__cur)); 485 } 486 __catch(...) 487 { 488 std::_Destroy(__first, __cur); 489 __throw_exception_again; 490 } 491 } 492 }; 493 494 template<> 495 struct __uninitialized_default_1<true> 496 { 497 template<typename _ForwardIterator> 498 static void 499 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 500 { 501 typedef typename iterator_traits<_ForwardIterator>::value_type 502 _ValueType; 503 504 std::fill(__first, __last, _ValueType()); 505 } 506 }; 507 508 template<bool _TrivialValueType> 509 struct __uninitialized_default_n_1 510 { 511 template<typename _ForwardIterator, typename _Size> 512 static _ForwardIterator 513 __uninit_default_n(_ForwardIterator __first, _Size __n) 514 { 515 _ForwardIterator __cur = __first; 516 __try 517 { 518 for (; __n > 0; --__n, ++__cur) 519 std::_Construct(std::__addressof(*__cur)); 520 return __cur; 521 } 522 __catch(...) 523 { 524 std::_Destroy(__first, __cur); 525 __throw_exception_again; 526 } 527 } 528 }; 529 530 template<> 531 struct __uninitialized_default_n_1<true> 532 { 533 template<typename _ForwardIterator, typename _Size> 534 static _ForwardIterator 535 __uninit_default_n(_ForwardIterator __first, _Size __n) 536 { 537 typedef typename iterator_traits<_ForwardIterator>::value_type 538 _ValueType; 539 540 return std::fill_n(__first, __n, _ValueType()); 541 } 542 }; 543 544 // __uninitialized_default 545 // Fills [first, last) with std::distance(first, last) default 546 // constructed value_types(s). 547 template<typename _ForwardIterator> 548 inline void 549 __uninitialized_default(_ForwardIterator __first, 550 _ForwardIterator __last) 551 { 552 typedef typename iterator_traits<_ForwardIterator>::value_type 553 _ValueType; 554 // trivial types can have deleted assignment 555 const bool __assignable = is_copy_assignable<_ValueType>::value; 556 557 std::__uninitialized_default_1<__is_trivial(_ValueType) 558 && __assignable>:: 559 __uninit_default(__first, __last); 560 } 561 562 // __uninitialized_default_n 563 // Fills [first, first + n) with n default constructed value_type(s). 564 template<typename _ForwardIterator, typename _Size> 565 inline _ForwardIterator 566 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 567 { 568 typedef typename iterator_traits<_ForwardIterator>::value_type 569 _ValueType; 570 // trivial types can have deleted assignment 571 const bool __assignable = is_copy_assignable<_ValueType>::value; 572 573 return __uninitialized_default_n_1<__is_trivial(_ValueType) 574 && __assignable>:: 575 __uninit_default_n(__first, __n); 576 } 577 578 579 // __uninitialized_default_a 580 // Fills [first, last) with std::distance(first, last) default 581 // constructed value_types(s), constructed with the allocator alloc. 582 template<typename _ForwardIterator, typename _Allocator> 583 void 584 __uninitialized_default_a(_ForwardIterator __first, 585 _ForwardIterator __last, 586 _Allocator& __alloc) 587 { 588 _ForwardIterator __cur = __first; 589 __try 590 { 591 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 592 for (; __cur != __last; ++__cur) 593 __traits::construct(__alloc, std::__addressof(*__cur)); 594 } 595 __catch(...) 596 { 597 std::_Destroy(__first, __cur, __alloc); 598 __throw_exception_again; 599 } 600 } 601 602 template<typename _ForwardIterator, typename _Tp> 603 inline void 604 __uninitialized_default_a(_ForwardIterator __first, 605 _ForwardIterator __last, 606 allocator<_Tp>&) 607 { std::__uninitialized_default(__first, __last); } 608 609 610 // __uninitialized_default_n_a 611 // Fills [first, first + n) with n default constructed value_types(s), 612 // constructed with the allocator alloc. 613 template<typename _ForwardIterator, typename _Size, typename _Allocator> 614 _ForwardIterator 615 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 616 _Allocator& __alloc) 617 { 618 _ForwardIterator __cur = __first; 619 __try 620 { 621 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 622 for (; __n > 0; --__n, ++__cur) 623 __traits::construct(__alloc, std::__addressof(*__cur)); 624 return __cur; 625 } 626 __catch(...) 627 { 628 std::_Destroy(__first, __cur, __alloc); 629 __throw_exception_again; 630 } 631 } 632 633 template<typename _ForwardIterator, typename _Size, typename _Tp> 634 inline _ForwardIterator 635 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 636 allocator<_Tp>&) 637 { return std::__uninitialized_default_n(__first, __n); } 638 639 640 template<typename _InputIterator, typename _Size, 641 typename _ForwardIterator> 642 _ForwardIterator 643 __uninitialized_copy_n(_InputIterator __first, _Size __n, 644 _ForwardIterator __result, input_iterator_tag) 645 { 646 _ForwardIterator __cur = __result; 647 __try 648 { 649 for (; __n > 0; --__n, ++__first, ++__cur) 650 std::_Construct(std::__addressof(*__cur), *__first); 651 return __cur; 652 } 653 __catch(...) 654 { 655 std::_Destroy(__result, __cur); 656 __throw_exception_again; 657 } 658 } 659 660 template<typename _RandomAccessIterator, typename _Size, 661 typename _ForwardIterator> 662 inline _ForwardIterator 663 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 664 _ForwardIterator __result, 665 random_access_iterator_tag) 666 { return std::uninitialized_copy(__first, __first + __n, __result); } 667 668 /** 669 * @brief Copies the range [first,first+n) into result. 670 * @param __first An input iterator. 671 * @param __n The number of elements to copy. 672 * @param __result An output iterator. 673 * @return __result + __n 674 * 675 * Like copy_n(), but does not require an initialized output range. 676 */ 677 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 678 inline _ForwardIterator 679 uninitialized_copy_n(_InputIterator __first, _Size __n, 680 _ForwardIterator __result) 681 { return std::__uninitialized_copy_n(__first, __n, __result, 682 std::__iterator_category(__first)); } 683 #endif 684 685 _GLIBCXX_END_NAMESPACE_VERSION 686 } // namespace 687 688 #endif /* _STL_UNINITIALIZED_H */ 689