libstdc++
|
00001 // Raw memory manipulators -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 00004 // 2009, 2010, 2011 00005 // Free Software Foundation, Inc. 00006 // 00007 // This file is part of the GNU ISO C++ Library. This library is free 00008 // software; you can redistribute it and/or modify it under the 00009 // terms of the GNU General Public License as published by the 00010 // Free Software Foundation; either version 3, or (at your option) 00011 // any later version. 00012 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 // GNU General Public License for more details. 00017 00018 // Under Section 7 of GPL version 3, you are granted additional 00019 // permissions described in the GCC Runtime Library Exception, version 00020 // 3.1, as published by the Free Software Foundation. 00021 00022 // You should have received a copy of the GNU General Public License and 00023 // a copy of the GCC Runtime Library Exception along with this program; 00024 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00025 // <http://www.gnu.org/licenses/>. 00026 00027 /* 00028 * 00029 * Copyright (c) 1994 00030 * Hewlett-Packard Company 00031 * 00032 * Permission to use, copy, modify, distribute and sell this software 00033 * and its documentation for any purpose is hereby granted without fee, 00034 * provided that the above copyright notice appear in all copies and 00035 * that both that copyright notice and this permission notice appear 00036 * in supporting documentation. Hewlett-Packard Company makes no 00037 * representations about the suitability of this software for any 00038 * purpose. It is provided "as is" without express or implied warranty. 00039 * 00040 * 00041 * Copyright (c) 1996,1997 00042 * Silicon Graphics Computer Systems, Inc. 00043 * 00044 * Permission to use, copy, modify, distribute and sell this software 00045 * and its documentation for any purpose is hereby granted without fee, 00046 * provided that the above copyright notice appear in all copies and 00047 * that both that copyright notice and this permission notice appear 00048 * in supporting documentation. Silicon Graphics makes no 00049 * representations about the suitability of this software for any 00050 * purpose. It is provided "as is" without express or implied warranty. 00051 */ 00052 00053 /** @file bits/stl_uninitialized.h 00054 * This is an internal header file, included by other library headers. 00055 * Do not attempt to use it directly. @headername{memory} 00056 */ 00057 00058 #ifndef _STL_UNINITIALIZED_H 00059 #define _STL_UNINITIALIZED_H 1 00060 00061 namespace std _GLIBCXX_VISIBILITY(default) 00062 { 00063 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00064 00065 template<bool _TrivialValueTypes> 00066 struct __uninitialized_copy 00067 { 00068 template<typename _InputIterator, typename _ForwardIterator> 00069 static _ForwardIterator 00070 __uninit_copy(_InputIterator __first, _InputIterator __last, 00071 _ForwardIterator __result) 00072 { 00073 _ForwardIterator __cur = __result; 00074 __try 00075 { 00076 for (; __first != __last; ++__first, ++__cur) 00077 std::_Construct(std::__addressof(*__cur), *__first); 00078 return __cur; 00079 } 00080 __catch(...) 00081 { 00082 std::_Destroy(__result, __cur); 00083 __throw_exception_again; 00084 } 00085 } 00086 }; 00087 00088 template<> 00089 struct __uninitialized_copy<true> 00090 { 00091 template<typename _InputIterator, typename _ForwardIterator> 00092 static _ForwardIterator 00093 __uninit_copy(_InputIterator __first, _InputIterator __last, 00094 _ForwardIterator __result) 00095 { return std::copy(__first, __last, __result); } 00096 }; 00097 00098 /** 00099 * @brief Copies the range [first,last) into result. 00100 * @param __first An input iterator. 00101 * @param __last An input iterator. 00102 * @param __result An output iterator. 00103 * @return __result + (__first - __last) 00104 * 00105 * Like copy(), but does not require an initialized output range. 00106 */ 00107 template<typename _InputIterator, typename _ForwardIterator> 00108 inline _ForwardIterator 00109 uninitialized_copy(_InputIterator __first, _InputIterator __last, 00110 _ForwardIterator __result) 00111 { 00112 typedef typename iterator_traits<_InputIterator>::value_type 00113 _ValueType1; 00114 typedef typename iterator_traits<_ForwardIterator>::value_type 00115 _ValueType2; 00116 00117 return std::__uninitialized_copy<(__is_trivial(_ValueType1) 00118 && __is_trivial(_ValueType2))>:: 00119 __uninit_copy(__first, __last, __result); 00120 } 00121 00122 00123 template<bool _TrivialValueType> 00124 struct __uninitialized_fill 00125 { 00126 template<typename _ForwardIterator, typename _Tp> 00127 static void 00128 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 00129 const _Tp& __x) 00130 { 00131 _ForwardIterator __cur = __first; 00132 __try 00133 { 00134 for (; __cur != __last; ++__cur) 00135 std::_Construct(std::__addressof(*__cur), __x); 00136 } 00137 __catch(...) 00138 { 00139 std::_Destroy(__first, __cur); 00140 __throw_exception_again; 00141 } 00142 } 00143 }; 00144 00145 template<> 00146 struct __uninitialized_fill<true> 00147 { 00148 template<typename _ForwardIterator, typename _Tp> 00149 static void 00150 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 00151 const _Tp& __x) 00152 { std::fill(__first, __last, __x); } 00153 }; 00154 00155 /** 00156 * @brief Copies the value x into the range [first,last). 00157 * @param __first An input iterator. 00158 * @param __last An input iterator. 00159 * @param __x The source value. 00160 * @return Nothing. 00161 * 00162 * Like fill(), but does not require an initialized output range. 00163 */ 00164 template<typename _ForwardIterator, typename _Tp> 00165 inline void 00166 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 00167 const _Tp& __x) 00168 { 00169 typedef typename iterator_traits<_ForwardIterator>::value_type 00170 _ValueType; 00171 00172 std::__uninitialized_fill<__is_trivial(_ValueType)>:: 00173 __uninit_fill(__first, __last, __x); 00174 } 00175 00176 00177 template<bool _TrivialValueType> 00178 struct __uninitialized_fill_n 00179 { 00180 template<typename _ForwardIterator, typename _Size, typename _Tp> 00181 static void 00182 __uninit_fill_n(_ForwardIterator __first, _Size __n, 00183 const _Tp& __x) 00184 { 00185 _ForwardIterator __cur = __first; 00186 __try 00187 { 00188 for (; __n > 0; --__n, ++__cur) 00189 std::_Construct(std::__addressof(*__cur), __x); 00190 } 00191 __catch(...) 00192 { 00193 std::_Destroy(__first, __cur); 00194 __throw_exception_again; 00195 } 00196 } 00197 }; 00198 00199 template<> 00200 struct __uninitialized_fill_n<true> 00201 { 00202 template<typename _ForwardIterator, typename _Size, typename _Tp> 00203 static void 00204 __uninit_fill_n(_ForwardIterator __first, _Size __n, 00205 const _Tp& __x) 00206 { std::fill_n(__first, __n, __x); } 00207 }; 00208 00209 /** 00210 * @brief Copies the value x into the range [first,first+n). 00211 * @param __first An input iterator. 00212 * @param __n The number of copies to make. 00213 * @param __x The source value. 00214 * @return Nothing. 00215 * 00216 * Like fill_n(), but does not require an initialized output range. 00217 */ 00218 template<typename _ForwardIterator, typename _Size, typename _Tp> 00219 inline void 00220 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 00221 { 00222 typedef typename iterator_traits<_ForwardIterator>::value_type 00223 _ValueType; 00224 00225 std::__uninitialized_fill_n<__is_trivial(_ValueType)>:: 00226 __uninit_fill_n(__first, __n, __x); 00227 } 00228 00229 // Extensions: versions of uninitialized_copy, uninitialized_fill, 00230 // and uninitialized_fill_n that take an allocator parameter. 00231 // We dispatch back to the standard versions when we're given the 00232 // default allocator. For nondefault allocators we do not use 00233 // any of the POD optimizations. 00234 00235 template<typename _InputIterator, typename _ForwardIterator, 00236 typename _Allocator> 00237 _ForwardIterator 00238 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00239 _ForwardIterator __result, _Allocator& __alloc) 00240 { 00241 _ForwardIterator __cur = __result; 00242 __try 00243 { 00244 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00245 for (; __first != __last; ++__first, ++__cur) 00246 __traits::construct(__alloc, std::__addressof(*__cur), *__first); 00247 return __cur; 00248 } 00249 __catch(...) 00250 { 00251 std::_Destroy(__result, __cur, __alloc); 00252 __throw_exception_again; 00253 } 00254 } 00255 00256 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 00257 inline _ForwardIterator 00258 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00259 _ForwardIterator __result, allocator<_Tp>&) 00260 { return std::uninitialized_copy(__first, __last, __result); } 00261 00262 template<typename _InputIterator, typename _ForwardIterator, 00263 typename _Allocator> 00264 inline _ForwardIterator 00265 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 00266 _ForwardIterator __result, _Allocator& __alloc) 00267 { 00268 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00269 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 00270 __result, __alloc); 00271 } 00272 00273 template<typename _InputIterator, typename _ForwardIterator, 00274 typename _Allocator> 00275 inline _ForwardIterator 00276 __uninitialized_move_if_noexcept_a(_InputIterator __first, 00277 _InputIterator __last, 00278 _ForwardIterator __result, 00279 _Allocator& __alloc) 00280 { 00281 return std::__uninitialized_copy_a 00282 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), 00283 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); 00284 } 00285 00286 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 00287 void 00288 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00289 const _Tp& __x, _Allocator& __alloc) 00290 { 00291 _ForwardIterator __cur = __first; 00292 __try 00293 { 00294 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00295 for (; __cur != __last; ++__cur) 00296 __traits::construct(__alloc, std::__addressof(*__cur), __x); 00297 } 00298 __catch(...) 00299 { 00300 std::_Destroy(__first, __cur, __alloc); 00301 __throw_exception_again; 00302 } 00303 } 00304 00305 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 00306 inline void 00307 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00308 const _Tp& __x, allocator<_Tp2>&) 00309 { std::uninitialized_fill(__first, __last, __x); } 00310 00311 template<typename _ForwardIterator, typename _Size, typename _Tp, 00312 typename _Allocator> 00313 void 00314 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00315 const _Tp& __x, _Allocator& __alloc) 00316 { 00317 _ForwardIterator __cur = __first; 00318 __try 00319 { 00320 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00321 for (; __n > 0; --__n, ++__cur) 00322 __traits::construct(__alloc, std::__addressof(*__cur), __x); 00323 } 00324 __catch(...) 00325 { 00326 std::_Destroy(__first, __cur, __alloc); 00327 __throw_exception_again; 00328 } 00329 } 00330 00331 template<typename _ForwardIterator, typename _Size, typename _Tp, 00332 typename _Tp2> 00333 inline void 00334 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00335 const _Tp& __x, allocator<_Tp2>&) 00336 { std::uninitialized_fill_n(__first, __n, __x); } 00337 00338 00339 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 00340 // __uninitialized_fill_move, __uninitialized_move_fill. 00341 // All of these algorithms take a user-supplied allocator, which is used 00342 // for construction and destruction. 00343 00344 // __uninitialized_copy_move 00345 // Copies [first1, last1) into [result, result + (last1 - first1)), and 00346 // move [first2, last2) into 00347 // [result, result + (last1 - first1) + (last2 - first2)). 00348 template<typename _InputIterator1, typename _InputIterator2, 00349 typename _ForwardIterator, typename _Allocator> 00350 inline _ForwardIterator 00351 __uninitialized_copy_move(_InputIterator1 __first1, 00352 _InputIterator1 __last1, 00353 _InputIterator2 __first2, 00354 _InputIterator2 __last2, 00355 _ForwardIterator __result, 00356 _Allocator& __alloc) 00357 { 00358 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 00359 __result, 00360 __alloc); 00361 __try 00362 { 00363 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 00364 } 00365 __catch(...) 00366 { 00367 std::_Destroy(__result, __mid, __alloc); 00368 __throw_exception_again; 00369 } 00370 } 00371 00372 // __uninitialized_move_copy 00373 // Moves [first1, last1) into [result, result + (last1 - first1)), and 00374 // copies [first2, last2) into 00375 // [result, result + (last1 - first1) + (last2 - first2)). 00376 template<typename _InputIterator1, typename _InputIterator2, 00377 typename _ForwardIterator, typename _Allocator> 00378 inline _ForwardIterator 00379 __uninitialized_move_copy(_InputIterator1 __first1, 00380 _InputIterator1 __last1, 00381 _InputIterator2 __first2, 00382 _InputIterator2 __last2, 00383 _ForwardIterator __result, 00384 _Allocator& __alloc) 00385 { 00386 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 00387 __result, 00388 __alloc); 00389 __try 00390 { 00391 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 00392 } 00393 __catch(...) 00394 { 00395 std::_Destroy(__result, __mid, __alloc); 00396 __throw_exception_again; 00397 } 00398 } 00399 00400 // __uninitialized_fill_move 00401 // Fills [result, mid) with x, and moves [first, last) into 00402 // [mid, mid + (last - first)). 00403 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 00404 typename _Allocator> 00405 inline _ForwardIterator 00406 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 00407 const _Tp& __x, _InputIterator __first, 00408 _InputIterator __last, _Allocator& __alloc) 00409 { 00410 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 00411 __try 00412 { 00413 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 00414 } 00415 __catch(...) 00416 { 00417 std::_Destroy(__result, __mid, __alloc); 00418 __throw_exception_again; 00419 } 00420 } 00421 00422 // __uninitialized_move_fill 00423 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 00424 // fills [first2 + (last1 - first1), last2) with x. 00425 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 00426 typename _Allocator> 00427 inline void 00428 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 00429 _ForwardIterator __first2, 00430 _ForwardIterator __last2, const _Tp& __x, 00431 _Allocator& __alloc) 00432 { 00433 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 00434 __first2, 00435 __alloc); 00436 __try 00437 { 00438 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 00439 } 00440 __catch(...) 00441 { 00442 std::_Destroy(__first2, __mid2, __alloc); 00443 __throw_exception_again; 00444 } 00445 } 00446 00447 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00448 // Extensions: __uninitialized_default, __uninitialized_default_n, 00449 // __uninitialized_default_a, __uninitialized_default_n_a. 00450 00451 template<bool _TrivialValueType> 00452 struct __uninitialized_default_1 00453 { 00454 template<typename _ForwardIterator> 00455 static void 00456 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00457 { 00458 _ForwardIterator __cur = __first; 00459 __try 00460 { 00461 for (; __cur != __last; ++__cur) 00462 std::_Construct(std::__addressof(*__cur)); 00463 } 00464 __catch(...) 00465 { 00466 std::_Destroy(__first, __cur); 00467 __throw_exception_again; 00468 } 00469 } 00470 }; 00471 00472 template<> 00473 struct __uninitialized_default_1<true> 00474 { 00475 template<typename _ForwardIterator> 00476 static void 00477 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00478 { 00479 typedef typename iterator_traits<_ForwardIterator>::value_type 00480 _ValueType; 00481 00482 std::fill(__first, __last, _ValueType()); 00483 } 00484 }; 00485 00486 template<bool _TrivialValueType> 00487 struct __uninitialized_default_n_1 00488 { 00489 template<typename _ForwardIterator, typename _Size> 00490 static void 00491 __uninit_default_n(_ForwardIterator __first, _Size __n) 00492 { 00493 _ForwardIterator __cur = __first; 00494 __try 00495 { 00496 for (; __n > 0; --__n, ++__cur) 00497 std::_Construct(std::__addressof(*__cur)); 00498 } 00499 __catch(...) 00500 { 00501 std::_Destroy(__first, __cur); 00502 __throw_exception_again; 00503 } 00504 } 00505 }; 00506 00507 template<> 00508 struct __uninitialized_default_n_1<true> 00509 { 00510 template<typename _ForwardIterator, typename _Size> 00511 static void 00512 __uninit_default_n(_ForwardIterator __first, _Size __n) 00513 { 00514 typedef typename iterator_traits<_ForwardIterator>::value_type 00515 _ValueType; 00516 00517 std::fill_n(__first, __n, _ValueType()); 00518 } 00519 }; 00520 00521 // __uninitialized_default 00522 // Fills [first, last) with std::distance(first, last) default 00523 // constructed value_types(s). 00524 template<typename _ForwardIterator> 00525 inline void 00526 __uninitialized_default(_ForwardIterator __first, 00527 _ForwardIterator __last) 00528 { 00529 typedef typename iterator_traits<_ForwardIterator>::value_type 00530 _ValueType; 00531 00532 std::__uninitialized_default_1<__is_trivial(_ValueType)>:: 00533 __uninit_default(__first, __last); 00534 } 00535 00536 // __uninitialized_default_n 00537 // Fills [first, first + n) with n default constructed value_type(s). 00538 template<typename _ForwardIterator, typename _Size> 00539 inline void 00540 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 00541 { 00542 typedef typename iterator_traits<_ForwardIterator>::value_type 00543 _ValueType; 00544 00545 std::__uninitialized_default_n_1<__is_trivial(_ValueType)>:: 00546 __uninit_default_n(__first, __n); 00547 } 00548 00549 00550 // __uninitialized_default_a 00551 // Fills [first, last) with std::distance(first, last) default 00552 // constructed value_types(s), constructed with the allocator alloc. 00553 template<typename _ForwardIterator, typename _Allocator> 00554 void 00555 __uninitialized_default_a(_ForwardIterator __first, 00556 _ForwardIterator __last, 00557 _Allocator& __alloc) 00558 { 00559 _ForwardIterator __cur = __first; 00560 __try 00561 { 00562 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00563 for (; __cur != __last; ++__cur) 00564 __traits::construct(__alloc, std::__addressof(*__cur)); 00565 } 00566 __catch(...) 00567 { 00568 std::_Destroy(__first, __cur, __alloc); 00569 __throw_exception_again; 00570 } 00571 } 00572 00573 template<typename _ForwardIterator, typename _Tp> 00574 inline void 00575 __uninitialized_default_a(_ForwardIterator __first, 00576 _ForwardIterator __last, 00577 allocator<_Tp>&) 00578 { std::__uninitialized_default(__first, __last); } 00579 00580 00581 // __uninitialized_default_n_a 00582 // Fills [first, first + n) with n default constructed value_types(s), 00583 // constructed with the allocator alloc. 00584 template<typename _ForwardIterator, typename _Size, typename _Allocator> 00585 void 00586 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00587 _Allocator& __alloc) 00588 { 00589 _ForwardIterator __cur = __first; 00590 __try 00591 { 00592 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00593 for (; __n > 0; --__n, ++__cur) 00594 __traits::construct(__alloc, std::__addressof(*__cur)); 00595 } 00596 __catch(...) 00597 { 00598 std::_Destroy(__first, __cur, __alloc); 00599 __throw_exception_again; 00600 } 00601 } 00602 00603 template<typename _ForwardIterator, typename _Size, typename _Tp> 00604 inline void 00605 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00606 allocator<_Tp>&) 00607 { std::__uninitialized_default_n(__first, __n); } 00608 00609 00610 template<typename _InputIterator, typename _Size, 00611 typename _ForwardIterator> 00612 _ForwardIterator 00613 __uninitialized_copy_n(_InputIterator __first, _Size __n, 00614 _ForwardIterator __result, input_iterator_tag) 00615 { 00616 _ForwardIterator __cur = __result; 00617 __try 00618 { 00619 for (; __n > 0; --__n, ++__first, ++__cur) 00620 std::_Construct(std::__addressof(*__cur), *__first); 00621 return __cur; 00622 } 00623 __catch(...) 00624 { 00625 std::_Destroy(__result, __cur); 00626 __throw_exception_again; 00627 } 00628 } 00629 00630 template<typename _RandomAccessIterator, typename _Size, 00631 typename _ForwardIterator> 00632 inline _ForwardIterator 00633 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 00634 _ForwardIterator __result, 00635 random_access_iterator_tag) 00636 { return std::uninitialized_copy(__first, __first + __n, __result); } 00637 00638 /** 00639 * @brief Copies the range [first,first+n) into result. 00640 * @param __first An input iterator. 00641 * @param __n The number of elements to copy. 00642 * @param __result An output iterator. 00643 * @return __result + __n 00644 * 00645 * Like copy_n(), but does not require an initialized output range. 00646 */ 00647 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 00648 inline _ForwardIterator 00649 uninitialized_copy_n(_InputIterator __first, _Size __n, 00650 _ForwardIterator __result) 00651 { return std::__uninitialized_copy_n(__first, __n, __result, 00652 std::__iterator_category(__first)); } 00653 #endif 00654 00655 _GLIBCXX_END_NAMESPACE_VERSION 00656 } // namespace 00657 00658 #endif /* _STL_UNINITIALIZED_H */