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