1 // Raw memory manipulators -*- C++ -*- 2 3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 4 // 2009, 2010, 2011 5 // Free Software Foundation, Inc. 6 // 7 // This file is part of the GNU ISO C++ Library. This library is free 8 // software; you can redistribute it and/or modify it under the 9 // terms of the GNU General Public License as published by the 10 // Free Software Foundation; either version 3, or (at your option) 11 // any later version. 12 13 // This library is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // Under Section 7 of GPL version 3, you are granted additional 19 // permissions described in the GCC Runtime Library Exception, version 20 // 3.1, as published by the Free Software Foundation. 21 22 // You should have received a copy of the GNU General Public License and 23 // a copy of the GCC Runtime Library Exception along with this program; 24 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25 // <http://www.gnu.org/licenses/>. 26 27 /* 28 * 29 * Copyright (c) 1994 30 * Hewlett-Packard Company 31 * 32 * Permission to use, copy, modify, distribute and sell this software 33 * and its documentation for any purpose is hereby granted without fee, 34 * provided that the above copyright notice appear in all copies and 35 * that both that copyright notice and this permission notice appear 36 * in supporting documentation. Hewlett-Packard Company makes no 37 * representations about the suitability of this software for any 38 * purpose. It is provided "as is" without express or implied warranty. 39 * 40 * 41 * Copyright (c) 1996,1997 42 * Silicon Graphics Computer Systems, Inc. 43 * 44 * Permission to use, copy, modify, distribute and sell this software 45 * and its documentation for any purpose is hereby granted without fee, 46 * provided that the above copyright notice appear in all copies and 47 * that both that copyright notice and this permission notice appear 48 * in supporting documentation. Silicon Graphics makes no 49 * representations about the suitability of this software for any 50 * purpose. It is provided "as is" without express or implied warranty. 51 */ 52 53 /** @file bits/stl_uninitialized.h 54 * This is an internal header file, included by other library headers. 55 * Do not attempt to use it directly. @headername{memory} 56 */ 57 58 #ifndef _STL_UNINITIALIZED_H 59 #define _STL_UNINITIALIZED_H 1 60 61 namespace std _GLIBCXX_VISIBILITY(default) 62 { 63 _GLIBCXX_BEGIN_NAMESPACE_VERSION 64 65 template<bool _TrivialValueTypes> 66 struct __uninitialized_copy 67 { 68 template<typename _InputIterator, typename _ForwardIterator> 69 static _ForwardIterator 70 __uninit_copy(_InputIterator __first, _InputIterator __last, 71 _ForwardIterator __result) 72 { 73 _ForwardIterator __cur = __result; 74 __try 75 { 76 for (; __first != __last; ++__first, ++__cur) 77 std::_Construct(std::__addressof(*__cur), *__first); 78 return __cur; 79 } 80 __catch(...) 81 { 82 std::_Destroy(__result, __cur); 83 __throw_exception_again; 84 } 85 } 86 }; 87 88 template<> 89 struct __uninitialized_copy<true> 90 { 91 template<typename _InputIterator, typename _ForwardIterator> 92 static _ForwardIterator 93 __uninit_copy(_InputIterator __first, _InputIterator __last, 94 _ForwardIterator __result) 95 { return std::copy(__first, __last, __result); } 96 }; 97 98 /** 99 * @brief Copies the range [first,last) into result. 100 * @param first An input iterator. 101 * @param last An input iterator. 102 * @param result An output iterator. 103 * @return result + (first - last) 104 * 105 * Like copy(), but does not require an initialized output range. 106 */ 107 template<typename _InputIterator, typename _ForwardIterator> 108 inline _ForwardIterator 109 uninitialized_copy(_InputIterator __first, _InputIterator __last, 110 _ForwardIterator __result) 111 { 112 typedef typename iterator_traits<_InputIterator>::value_type 113 _ValueType1; 114 typedef typename iterator_traits<_ForwardIterator>::value_type 115 _ValueType2; 116 117 return std::__uninitialized_copy<(__is_trivial(_ValueType1) 118 && __is_trivial(_ValueType2))>:: 119 __uninit_copy(__first, __last, __result); 120 } 121 122 123 template<bool _TrivialValueType> 124 struct __uninitialized_fill 125 { 126 template<typename _ForwardIterator, typename _Tp> 127 static void 128 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 129 const _Tp& __x) 130 { 131 _ForwardIterator __cur = __first; 132 __try 133 { 134 for (; __cur != __last; ++__cur) 135 std::_Construct(std::__addressof(*__cur), __x); 136 } 137 __catch(...) 138 { 139 std::_Destroy(__first, __cur); 140 __throw_exception_again; 141 } 142 } 143 }; 144 145 template<> 146 struct __uninitialized_fill<true> 147 { 148 template<typename _ForwardIterator, typename _Tp> 149 static void 150 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 151 const _Tp& __x) 152 { std::fill(__first, __last, __x); } 153 }; 154 155 /** 156 * @brief Copies the value x into the range [first,last). 157 * @param first An input iterator. 158 * @param last An input iterator. 159 * @param x The source value. 160 * @return Nothing. 161 * 162 * Like fill(), but does not require an initialized output range. 163 */ 164 template<typename _ForwardIterator, typename _Tp> 165 inline void 166 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 167 const _Tp& __x) 168 { 169 typedef typename iterator_traits<_ForwardIterator>::value_type 170 _ValueType; 171 172 std::__uninitialized_fill<__is_trivial(_ValueType)>:: 173 __uninit_fill(__first, __last, __x); 174 } 175 176 177 template<bool _TrivialValueType> 178 struct __uninitialized_fill_n 179 { 180 template<typename _ForwardIterator, typename _Size, typename _Tp> 181 static void 182 __uninit_fill_n(_ForwardIterator __first, _Size __n, 183 const _Tp& __x) 184 { 185 _ForwardIterator __cur = __first; 186 __try 187 { 188 for (; __n > 0; --__n, ++__cur) 189 std::_Construct(std::__addressof(*__cur), __x); 190 } 191 __catch(...) 192 { 193 std::_Destroy(__first, __cur); 194 __throw_exception_again; 195 } 196 } 197 }; 198 199 template<> 200 struct __uninitialized_fill_n<true> 201 { 202 template<typename _ForwardIterator, typename _Size, typename _Tp> 203 static void 204 __uninit_fill_n(_ForwardIterator __first, _Size __n, 205 const _Tp& __x) 206 { std::fill_n(__first, __n, __x); } 207 }; 208 209 /** 210 * @brief Copies the value x into the range [first,first+n). 211 * @param first An input iterator. 212 * @param n The number of copies to make. 213 * @param x The source value. 214 * @return Nothing. 215 * 216 * Like fill_n(), but does not require an initialized output range. 217 */ 218 template<typename _ForwardIterator, typename _Size, typename _Tp> 219 inline void 220 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 221 { 222 typedef typename iterator_traits<_ForwardIterator>::value_type 223 _ValueType; 224 225 std::__uninitialized_fill_n<__is_trivial(_ValueType)>:: 226 __uninit_fill_n(__first, __n, __x); 227 } 228 229 // Extensions: versions of uninitialized_copy, uninitialized_fill, 230 // and uninitialized_fill_n that take an allocator parameter. 231 // We dispatch back to the standard versions when we're given the 232 // default allocator. For nondefault allocators we do not use 233 // any of the POD optimizations. 234 235 template<typename _InputIterator, typename _ForwardIterator, 236 typename _Allocator> 237 _ForwardIterator 238 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 239 _ForwardIterator __result, _Allocator& __alloc) 240 { 241 _ForwardIterator __cur = __result; 242 __try 243 { 244 for (; __first != __last; ++__first, ++__cur) 245 __alloc.construct(std::__addressof(*__cur), *__first); 246 return __cur; 247 } 248 __catch(...) 249 { 250 std::_Destroy(__result, __cur, __alloc); 251 __throw_exception_again; 252 } 253 } 254 255 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 256 inline _ForwardIterator 257 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 258 _ForwardIterator __result, allocator<_Tp>&) 259 { return std::uninitialized_copy(__first, __last, __result); } 260 261 template<typename _InputIterator, typename _ForwardIterator, 262 typename _Allocator> 263 inline _ForwardIterator 264 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 265 _ForwardIterator __result, _Allocator& __alloc) 266 { 267 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 268 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 269 __result, __alloc); 270 } 271 272 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 273 void 274 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 275 const _Tp& __x, _Allocator& __alloc) 276 { 277 _ForwardIterator __cur = __first; 278 __try 279 { 280 for (; __cur != __last; ++__cur) 281 __alloc.construct(std::__addressof(*__cur), __x); 282 } 283 __catch(...) 284 { 285 std::_Destroy(__first, __cur, __alloc); 286 __throw_exception_again; 287 } 288 } 289 290 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 291 inline void 292 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 293 const _Tp& __x, allocator<_Tp2>&) 294 { std::uninitialized_fill(__first, __last, __x); } 295 296 template<typename _ForwardIterator, typename _Size, typename _Tp, 297 typename _Allocator> 298 void 299 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 300 const _Tp& __x, _Allocator& __alloc) 301 { 302 _ForwardIterator __cur = __first; 303 __try 304 { 305 for (; __n > 0; --__n, ++__cur) 306 __alloc.construct(std::__addressof(*__cur), __x); 307 } 308 __catch(...) 309 { 310 std::_Destroy(__first, __cur, __alloc); 311 __throw_exception_again; 312 } 313 } 314 315 template<typename _ForwardIterator, typename _Size, typename _Tp, 316 typename _Tp2> 317 inline void 318 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 319 const _Tp& __x, allocator<_Tp2>&) 320 { std::uninitialized_fill_n(__first, __n, __x); } 321 322 323 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 324 // __uninitialized_fill_move, __uninitialized_move_fill. 325 // All of these algorithms take a user-supplied allocator, which is used 326 // for construction and destruction. 327 328 // __uninitialized_copy_move 329 // Copies [first1, last1) into [result, result + (last1 - first1)), and 330 // move [first2, last2) into 331 // [result, result + (last1 - first1) + (last2 - first2)). 332 template<typename _InputIterator1, typename _InputIterator2, 333 typename _ForwardIterator, typename _Allocator> 334 inline _ForwardIterator 335 __uninitialized_copy_move(_InputIterator1 __first1, 336 _InputIterator1 __last1, 337 _InputIterator2 __first2, 338 _InputIterator2 __last2, 339 _ForwardIterator __result, 340 _Allocator& __alloc) 341 { 342 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 343 __result, 344 __alloc); 345 __try 346 { 347 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 348 } 349 __catch(...) 350 { 351 std::_Destroy(__result, __mid, __alloc); 352 __throw_exception_again; 353 } 354 } 355 356 // __uninitialized_move_copy 357 // Moves [first1, last1) into [result, result + (last1 - first1)), and 358 // copies [first2, last2) into 359 // [result, result + (last1 - first1) + (last2 - first2)). 360 template<typename _InputIterator1, typename _InputIterator2, 361 typename _ForwardIterator, typename _Allocator> 362 inline _ForwardIterator 363 __uninitialized_move_copy(_InputIterator1 __first1, 364 _InputIterator1 __last1, 365 _InputIterator2 __first2, 366 _InputIterator2 __last2, 367 _ForwardIterator __result, 368 _Allocator& __alloc) 369 { 370 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 371 __result, 372 __alloc); 373 __try 374 { 375 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 376 } 377 __catch(...) 378 { 379 std::_Destroy(__result, __mid, __alloc); 380 __throw_exception_again; 381 } 382 } 383 384 // __uninitialized_fill_move 385 // Fills [result, mid) with x, and moves [first, last) into 386 // [mid, mid + (last - first)). 387 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 388 typename _Allocator> 389 inline _ForwardIterator 390 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 391 const _Tp& __x, _InputIterator __first, 392 _InputIterator __last, _Allocator& __alloc) 393 { 394 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 395 __try 396 { 397 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 398 } 399 __catch(...) 400 { 401 std::_Destroy(__result, __mid, __alloc); 402 __throw_exception_again; 403 } 404 } 405 406 // __uninitialized_move_fill 407 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 408 // fills [first2 + (last1 - first1), last2) with x. 409 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 410 typename _Allocator> 411 inline void 412 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 413 _ForwardIterator __first2, 414 _ForwardIterator __last2, const _Tp& __x, 415 _Allocator& __alloc) 416 { 417 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 418 __first2, 419 __alloc); 420 __try 421 { 422 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 423 } 424 __catch(...) 425 { 426 std::_Destroy(__first2, __mid2, __alloc); 427 __throw_exception_again; 428 } 429 } 430 431 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 432 // Extensions: __uninitialized_default, __uninitialized_default_n, 433 // __uninitialized_default_a, __uninitialized_default_n_a. 434 435 template<bool _TrivialValueType> 436 struct __uninitialized_default_1 437 { 438 template<typename _ForwardIterator> 439 static void 440 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 441 { 442 _ForwardIterator __cur = __first; 443 __try 444 { 445 for (; __cur != __last; ++__cur) 446 std::_Construct(std::__addressof(*__cur)); 447 } 448 __catch(...) 449 { 450 std::_Destroy(__first, __cur); 451 __throw_exception_again; 452 } 453 } 454 }; 455 456 template<> 457 struct __uninitialized_default_1<true> 458 { 459 template<typename _ForwardIterator> 460 static void 461 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 462 { 463 typedef typename iterator_traits<_ForwardIterator>::value_type 464 _ValueType; 465 466 std::fill(__first, __last, _ValueType()); 467 } 468 }; 469 470 template<bool _TrivialValueType> 471 struct __uninitialized_default_n_1 472 { 473 template<typename _ForwardIterator, typename _Size> 474 static void 475 __uninit_default_n(_ForwardIterator __first, _Size __n) 476 { 477 _ForwardIterator __cur = __first; 478 __try 479 { 480 for (; __n > 0; --__n, ++__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_n_1<true> 493 { 494 template<typename _ForwardIterator, typename _Size> 495 static void 496 __uninit_default_n(_ForwardIterator __first, _Size __n) 497 { 498 typedef typename iterator_traits<_ForwardIterator>::value_type 499 _ValueType; 500 501 std::fill_n(__first, __n, _ValueType()); 502 } 503 }; 504 505 // __uninitialized_default 506 // Fills [first, last) with std::distance(first, last) default 507 // constructed value_types(s). 508 template<typename _ForwardIterator> 509 inline void 510 __uninitialized_default(_ForwardIterator __first, 511 _ForwardIterator __last) 512 { 513 typedef typename iterator_traits<_ForwardIterator>::value_type 514 _ValueType; 515 516 std::__uninitialized_default_1<__is_trivial(_ValueType)>:: 517 __uninit_default(__first, __last); 518 } 519 520 // __uninitialized_default_n 521 // Fills [first, first + n) with n default constructed value_type(s). 522 template<typename _ForwardIterator, typename _Size> 523 inline void 524 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 525 { 526 typedef typename iterator_traits<_ForwardIterator>::value_type 527 _ValueType; 528 529 std::__uninitialized_default_n_1<__is_trivial(_ValueType)>:: 530 __uninit_default_n(__first, __n); 531 } 532 533 template<typename _Tp, typename _Allocator> 534 inline auto 535 _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, void*) 536 -> decltype(__alloc.construct(__ptr)) 537 { return __alloc.construct(__ptr); } 538 539 template<typename _Tp, typename _Allocator> 540 inline void 541 _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, ...) 542 { _Construct(__ptr); } 543 544 template<typename _Tp, typename _Allocator> 545 inline void 546 _Construct_default_a(_Tp* __ptr, _Allocator& __alloc) 547 { _Construct_default_a_impl(__ptr, __alloc, nullptr); } 548 549 // __uninitialized_default_a 550 // Fills [first, last) with std::distance(first, last) default 551 // constructed value_types(s), constructed with the allocator alloc. 552 template<typename _ForwardIterator, typename _Allocator> 553 void 554 __uninitialized_default_a(_ForwardIterator __first, 555 _ForwardIterator __last, 556 _Allocator& __alloc) 557 { 558 _ForwardIterator __cur = __first; 559 __try 560 { 561 for (; __cur != __last; ++__cur) 562 _Construct_default_a(std::__addressof(*__cur), __alloc); 563 } 564 __catch(...) 565 { 566 std::_Destroy(__first, __cur, __alloc); 567 __throw_exception_again; 568 } 569 } 570 571 template<typename _ForwardIterator, typename _Tp> 572 inline void 573 __uninitialized_default_a(_ForwardIterator __first, 574 _ForwardIterator __last, 575 allocator<_Tp>&) 576 { std::__uninitialized_default(__first, __last); } 577 578 579 // __uninitialized_default_n_a 580 // Fills [first, first + n) with n default constructed value_types(s), 581 // constructed with the allocator alloc. 582 template<typename _ForwardIterator, typename _Size, typename _Allocator> 583 void 584 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 585 _Allocator& __alloc) 586 { 587 _ForwardIterator __cur = __first; 588 __try 589 { 590 for (; __n > 0; --__n, ++__cur) 591 _Construct_default_a(std::__addressof(*__cur), __alloc); 592 } 593 __catch(...) 594 { 595 std::_Destroy(__first, __cur, __alloc); 596 __throw_exception_again; 597 } 598 } 599 600 template<typename _ForwardIterator, typename _Size, typename _Tp> 601 inline void 602 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 603 allocator<_Tp>&) 604 { std::__uninitialized_default_n(__first, __n); } 605 606 607 template<typename _InputIterator, typename _Size, 608 typename _ForwardIterator> 609 _ForwardIterator 610 __uninitialized_copy_n(_InputIterator __first, _Size __n, 611 _ForwardIterator __result, input_iterator_tag) 612 { 613 _ForwardIterator __cur = __result; 614 __try 615 { 616 for (; __n > 0; --__n, ++__first, ++__cur) 617 std::_Construct(std::__addressof(*__cur), *__first); 618 return __cur; 619 } 620 __catch(...) 621 { 622 std::_Destroy(__result, __cur); 623 __throw_exception_again; 624 } 625 } 626 627 template<typename _RandomAccessIterator, typename _Size, 628 typename _ForwardIterator> 629 inline _ForwardIterator 630 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 631 _ForwardIterator __result, 632 random_access_iterator_tag) 633 { return std::uninitialized_copy(__first, __first + __n, __result); } 634 635 /** 636 * @brief Copies the range [first,first+n) into result. 637 * @param first An input iterator. 638 * @param n The number of elements to copy. 639 * @param result An output iterator. 640 * @return result + n 641 * 642 * Like copy_n(), but does not require an initialized output range. 643 */ 644 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 645 inline _ForwardIterator 646 uninitialized_copy_n(_InputIterator __first, _Size __n, 647 _ForwardIterator __result) 648 { return std::__uninitialized_copy_n(__first, __n, __result, 649 std::__iterator_category(__first)); } 650 #endif 651 652 _GLIBCXX_END_NAMESPACE_VERSION 653 } // namespace 654 655 #endif /* _STL_UNINITIALIZED_H */ 656