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