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