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 for (; __first != __last; ++__first, ++__cur) 00245 __alloc.construct(std::__addressof(*__cur), *__first); 00246 return __cur; 00247 } 00248 __catch(...) 00249 { 00250 std::_Destroy(__result, __cur, __alloc); 00251 __throw_exception_again; 00252 } 00253 } 00254 00255 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 00256 inline _ForwardIterator 00257 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00258 _ForwardIterator __result, allocator<_Tp>&) 00259 { return std::uninitialized_copy(__first, __last, __result); } 00260 00261 template<typename _InputIterator, typename _ForwardIterator, 00262 typename _Allocator> 00263 inline _ForwardIterator 00264 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 00265 _ForwardIterator __result, _Allocator& __alloc) 00266 { 00267 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00268 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 00269 __result, __alloc); 00270 } 00271 00272 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 00273 void 00274 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00275 const _Tp& __x, _Allocator& __alloc) 00276 { 00277 _ForwardIterator __cur = __first; 00278 __try 00279 { 00280 for (; __cur != __last; ++__cur) 00281 __alloc.construct(std::__addressof(*__cur), __x); 00282 } 00283 __catch(...) 00284 { 00285 std::_Destroy(__first, __cur, __alloc); 00286 __throw_exception_again; 00287 } 00288 } 00289 00290 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 00291 inline void 00292 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00293 const _Tp& __x, allocator<_Tp2>&) 00294 { std::uninitialized_fill(__first, __last, __x); } 00295 00296 template<typename _ForwardIterator, typename _Size, typename _Tp, 00297 typename _Allocator> 00298 void 00299 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00300 const _Tp& __x, _Allocator& __alloc) 00301 { 00302 _ForwardIterator __cur = __first; 00303 __try 00304 { 00305 for (; __n > 0; --__n, ++__cur) 00306 __alloc.construct(std::__addressof(*__cur), __x); 00307 } 00308 __catch(...) 00309 { 00310 std::_Destroy(__first, __cur, __alloc); 00311 __throw_exception_again; 00312 } 00313 } 00314 00315 template<typename _ForwardIterator, typename _Size, typename _Tp, 00316 typename _Tp2> 00317 inline void 00318 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00319 const _Tp& __x, allocator<_Tp2>&) 00320 { std::uninitialized_fill_n(__first, __n, __x); } 00321 00322 00323 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 00324 // __uninitialized_fill_move, __uninitialized_move_fill. 00325 // All of these algorithms take a user-supplied allocator, which is used 00326 // for construction and destruction. 00327 00328 // __uninitialized_copy_move 00329 // Copies [first1, last1) into [result, result + (last1 - first1)), and 00330 // move [first2, last2) into 00331 // [result, result + (last1 - first1) + (last2 - first2)). 00332 template<typename _InputIterator1, typename _InputIterator2, 00333 typename _ForwardIterator, typename _Allocator> 00334 inline _ForwardIterator 00335 __uninitialized_copy_move(_InputIterator1 __first1, 00336 _InputIterator1 __last1, 00337 _InputIterator2 __first2, 00338 _InputIterator2 __last2, 00339 _ForwardIterator __result, 00340 _Allocator& __alloc) 00341 { 00342 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 00343 __result, 00344 __alloc); 00345 __try 00346 { 00347 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 00348 } 00349 __catch(...) 00350 { 00351 std::_Destroy(__result, __mid, __alloc); 00352 __throw_exception_again; 00353 } 00354 } 00355 00356 // __uninitialized_move_copy 00357 // Moves [first1, last1) into [result, result + (last1 - first1)), and 00358 // copies [first2, last2) into 00359 // [result, result + (last1 - first1) + (last2 - first2)). 00360 template<typename _InputIterator1, typename _InputIterator2, 00361 typename _ForwardIterator, typename _Allocator> 00362 inline _ForwardIterator 00363 __uninitialized_move_copy(_InputIterator1 __first1, 00364 _InputIterator1 __last1, 00365 _InputIterator2 __first2, 00366 _InputIterator2 __last2, 00367 _ForwardIterator __result, 00368 _Allocator& __alloc) 00369 { 00370 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 00371 __result, 00372 __alloc); 00373 __try 00374 { 00375 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 00376 } 00377 __catch(...) 00378 { 00379 std::_Destroy(__result, __mid, __alloc); 00380 __throw_exception_again; 00381 } 00382 } 00383 00384 // __uninitialized_fill_move 00385 // Fills [result, mid) with x, and moves [first, last) into 00386 // [mid, mid + (last - first)). 00387 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 00388 typename _Allocator> 00389 inline _ForwardIterator 00390 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 00391 const _Tp& __x, _InputIterator __first, 00392 _InputIterator __last, _Allocator& __alloc) 00393 { 00394 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 00395 __try 00396 { 00397 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 00398 } 00399 __catch(...) 00400 { 00401 std::_Destroy(__result, __mid, __alloc); 00402 __throw_exception_again; 00403 } 00404 } 00405 00406 // __uninitialized_move_fill 00407 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 00408 // fills [first2 + (last1 - first1), last2) with x. 00409 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 00410 typename _Allocator> 00411 inline void 00412 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 00413 _ForwardIterator __first2, 00414 _ForwardIterator __last2, const _Tp& __x, 00415 _Allocator& __alloc) 00416 { 00417 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 00418 __first2, 00419 __alloc); 00420 __try 00421 { 00422 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 00423 } 00424 __catch(...) 00425 { 00426 std::_Destroy(__first2, __mid2, __alloc); 00427 __throw_exception_again; 00428 } 00429 } 00430 00431 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00432 // Extensions: __uninitialized_default, __uninitialized_default_n, 00433 // __uninitialized_default_a, __uninitialized_default_n_a. 00434 00435 template<bool _TrivialValueType> 00436 struct __uninitialized_default_1 00437 { 00438 template<typename _ForwardIterator> 00439 static void 00440 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00441 { 00442 _ForwardIterator __cur = __first; 00443 __try 00444 { 00445 for (; __cur != __last; ++__cur) 00446 std::_Construct(std::__addressof(*__cur)); 00447 } 00448 __catch(...) 00449 { 00450 std::_Destroy(__first, __cur); 00451 __throw_exception_again; 00452 } 00453 } 00454 }; 00455 00456 template<> 00457 struct __uninitialized_default_1<true> 00458 { 00459 template<typename _ForwardIterator> 00460 static void 00461 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00462 { 00463 typedef typename iterator_traits<_ForwardIterator>::value_type 00464 _ValueType; 00465 00466 std::fill(__first, __last, _ValueType()); 00467 } 00468 }; 00469 00470 template<bool _TrivialValueType> 00471 struct __uninitialized_default_n_1 00472 { 00473 template<typename _ForwardIterator, typename _Size> 00474 static void 00475 __uninit_default_n(_ForwardIterator __first, _Size __n) 00476 { 00477 _ForwardIterator __cur = __first; 00478 __try 00479 { 00480 for (; __n > 0; --__n, ++__cur) 00481 std::_Construct(std::__addressof(*__cur)); 00482 } 00483 __catch(...) 00484 { 00485 std::_Destroy(__first, __cur); 00486 __throw_exception_again; 00487 } 00488 } 00489 }; 00490 00491 template<> 00492 struct __uninitialized_default_n_1<true> 00493 { 00494 template<typename _ForwardIterator, typename _Size> 00495 static void 00496 __uninit_default_n(_ForwardIterator __first, _Size __n) 00497 { 00498 typedef typename iterator_traits<_ForwardIterator>::value_type 00499 _ValueType; 00500 00501 std::fill_n(__first, __n, _ValueType()); 00502 } 00503 }; 00504 00505 // __uninitialized_default 00506 // Fills [first, last) with std::distance(first, last) default 00507 // constructed value_types(s). 00508 template<typename _ForwardIterator> 00509 inline void 00510 __uninitialized_default(_ForwardIterator __first, 00511 _ForwardIterator __last) 00512 { 00513 typedef typename iterator_traits<_ForwardIterator>::value_type 00514 _ValueType; 00515 00516 std::__uninitialized_default_1<__is_trivial(_ValueType)>:: 00517 __uninit_default(__first, __last); 00518 } 00519 00520 // __uninitialized_default_n 00521 // Fills [first, first + n) with n default constructed value_type(s). 00522 template<typename _ForwardIterator, typename _Size> 00523 inline void 00524 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 00525 { 00526 typedef typename iterator_traits<_ForwardIterator>::value_type 00527 _ValueType; 00528 00529 std::__uninitialized_default_n_1<__is_trivial(_ValueType)>:: 00530 __uninit_default_n(__first, __n); 00531 } 00532 00533 template<typename _Tp, typename _Allocator> 00534 inline auto 00535 _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, void*) 00536 -> decltype(__alloc.construct(__ptr)) 00537 { return __alloc.construct(__ptr); } 00538 00539 template<typename _Tp, typename _Allocator> 00540 inline void 00541 _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, ...) 00542 { _Construct(__ptr); } 00543 00544 template<typename _Tp, typename _Allocator> 00545 inline void 00546 _Construct_default_a(_Tp* __ptr, _Allocator& __alloc) 00547 { _Construct_default_a_impl(__ptr, __alloc, nullptr); } 00548 00549 // __uninitialized_default_a 00550 // Fills [first, last) with std::distance(first, last) default 00551 // constructed value_types(s), constructed with the allocator alloc. 00552 template<typename _ForwardIterator, typename _Allocator> 00553 void 00554 __uninitialized_default_a(_ForwardIterator __first, 00555 _ForwardIterator __last, 00556 _Allocator& __alloc) 00557 { 00558 _ForwardIterator __cur = __first; 00559 __try 00560 { 00561 for (; __cur != __last; ++__cur) 00562 _Construct_default_a(std::__addressof(*__cur), __alloc); 00563 } 00564 __catch(...) 00565 { 00566 std::_Destroy(__first, __cur, __alloc); 00567 __throw_exception_again; 00568 } 00569 } 00570 00571 template<typename _ForwardIterator, typename _Tp> 00572 inline void 00573 __uninitialized_default_a(_ForwardIterator __first, 00574 _ForwardIterator __last, 00575 allocator<_Tp>&) 00576 { std::__uninitialized_default(__first, __last); } 00577 00578 00579 // __uninitialized_default_n_a 00580 // Fills [first, first + n) with n default constructed value_types(s), 00581 // constructed with the allocator alloc. 00582 template<typename _ForwardIterator, typename _Size, typename _Allocator> 00583 void 00584 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00585 _Allocator& __alloc) 00586 { 00587 _ForwardIterator __cur = __first; 00588 __try 00589 { 00590 for (; __n > 0; --__n, ++__cur) 00591 _Construct_default_a(std::__addressof(*__cur), __alloc); 00592 } 00593 __catch(...) 00594 { 00595 std::_Destroy(__first, __cur, __alloc); 00596 __throw_exception_again; 00597 } 00598 } 00599 00600 template<typename _ForwardIterator, typename _Size, typename _Tp> 00601 inline void 00602 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00603 allocator<_Tp>&) 00604 { std::__uninitialized_default_n(__first, __n); } 00605 00606 00607 template<typename _InputIterator, typename _Size, 00608 typename _ForwardIterator> 00609 _ForwardIterator 00610 __uninitialized_copy_n(_InputIterator __first, _Size __n, 00611 _ForwardIterator __result, input_iterator_tag) 00612 { 00613 _ForwardIterator __cur = __result; 00614 __try 00615 { 00616 for (; __n > 0; --__n, ++__first, ++__cur) 00617 std::_Construct(std::__addressof(*__cur), *__first); 00618 return __cur; 00619 } 00620 __catch(...) 00621 { 00622 std::_Destroy(__result, __cur); 00623 __throw_exception_again; 00624 } 00625 } 00626 00627 template<typename _RandomAccessIterator, typename _Size, 00628 typename _ForwardIterator> 00629 inline _ForwardIterator 00630 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 00631 _ForwardIterator __result, 00632 random_access_iterator_tag) 00633 { return std::uninitialized_copy(__first, __first + __n, __result); } 00634 00635 /** 00636 * @brief Copies the range [first,first+n) into result. 00637 * @param first An input iterator. 00638 * @param n The number of elements to copy. 00639 * @param result An output iterator. 00640 * @return result + n 00641 * 00642 * Like copy_n(), but does not require an initialized output range. 00643 */ 00644 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 00645 inline _ForwardIterator 00646 uninitialized_copy_n(_InputIterator __first, _Size __n, 00647 _ForwardIterator __result) 00648 { return std::__uninitialized_copy_n(__first, __n, __result, 00649 std::__iterator_category(__first)); } 00650 #endif 00651 00652 _GLIBCXX_END_NAMESPACE_VERSION 00653 } // namespace 00654 00655 #endif /* _STL_UNINITIALIZED_H */