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