|
libstdc++
|
00001 // Raw memory manipulators -*- C++ -*- 00002 00003 // Copyright (C) 2001-2019 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 #if __cplusplus > 201402L 00060 #include <utility> 00061 #endif 00062 00063 #if __cplusplus >= 201103L 00064 #include <type_traits> 00065 #endif 00066 00067 namespace std _GLIBCXX_VISIBILITY(default) 00068 { 00069 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00070 00071 template<bool _TrivialValueTypes> 00072 struct __uninitialized_copy 00073 { 00074 template<typename _InputIterator, typename _ForwardIterator> 00075 static _ForwardIterator 00076 __uninit_copy(_InputIterator __first, _InputIterator __last, 00077 _ForwardIterator __result) 00078 { 00079 _ForwardIterator __cur = __result; 00080 __try 00081 { 00082 for (; __first != __last; ++__first, (void)++__cur) 00083 std::_Construct(std::__addressof(*__cur), *__first); 00084 return __cur; 00085 } 00086 __catch(...) 00087 { 00088 std::_Destroy(__result, __cur); 00089 __throw_exception_again; 00090 } 00091 } 00092 }; 00093 00094 template<> 00095 struct __uninitialized_copy<true> 00096 { 00097 template<typename _InputIterator, typename _ForwardIterator> 00098 static _ForwardIterator 00099 __uninit_copy(_InputIterator __first, _InputIterator __last, 00100 _ForwardIterator __result) 00101 { return std::copy(__first, __last, __result); } 00102 }; 00103 00104 /** 00105 * @brief Copies the range [first,last) into result. 00106 * @param __first An input iterator. 00107 * @param __last An input iterator. 00108 * @param __result An output iterator. 00109 * @return __result + (__first - __last) 00110 * 00111 * Like copy(), but does not require an initialized output range. 00112 */ 00113 template<typename _InputIterator, typename _ForwardIterator> 00114 inline _ForwardIterator 00115 uninitialized_copy(_InputIterator __first, _InputIterator __last, 00116 _ForwardIterator __result) 00117 { 00118 typedef typename iterator_traits<_InputIterator>::value_type 00119 _ValueType1; 00120 typedef typename iterator_traits<_ForwardIterator>::value_type 00121 _ValueType2; 00122 #if __cplusplus < 201103L 00123 const bool __assignable = true; 00124 #else 00125 // Trivial types can have deleted copy constructor, but the std::copy 00126 // optimization that uses memmove would happily "copy" them anyway. 00127 static_assert(is_constructible<_ValueType2, decltype(*__first)>::value, 00128 "result type must be constructible from value type of input range"); 00129 00130 typedef typename iterator_traits<_InputIterator>::reference _RefType1; 00131 typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; 00132 // Trivial types can have deleted assignment, so using std::copy 00133 // would be ill-formed. Require assignability before using std::copy: 00134 const bool __assignable = is_assignable<_RefType2, _RefType1>::value; 00135 #endif 00136 00137 return std::__uninitialized_copy<__is_trivial(_ValueType1) 00138 && __is_trivial(_ValueType2) 00139 && __assignable>:: 00140 __uninit_copy(__first, __last, __result); 00141 } 00142 00143 00144 template<bool _TrivialValueType> 00145 struct __uninitialized_fill 00146 { 00147 template<typename _ForwardIterator, typename _Tp> 00148 static void 00149 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 00150 const _Tp& __x) 00151 { 00152 _ForwardIterator __cur = __first; 00153 __try 00154 { 00155 for (; __cur != __last; ++__cur) 00156 std::_Construct(std::__addressof(*__cur), __x); 00157 } 00158 __catch(...) 00159 { 00160 std::_Destroy(__first, __cur); 00161 __throw_exception_again; 00162 } 00163 } 00164 }; 00165 00166 template<> 00167 struct __uninitialized_fill<true> 00168 { 00169 template<typename _ForwardIterator, typename _Tp> 00170 static void 00171 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, 00172 const _Tp& __x) 00173 { std::fill(__first, __last, __x); } 00174 }; 00175 00176 /** 00177 * @brief Copies the value x into the range [first,last). 00178 * @param __first An input iterator. 00179 * @param __last An input iterator. 00180 * @param __x The source value. 00181 * @return Nothing. 00182 * 00183 * Like fill(), but does not require an initialized output range. 00184 */ 00185 template<typename _ForwardIterator, typename _Tp> 00186 inline void 00187 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 00188 const _Tp& __x) 00189 { 00190 typedef typename iterator_traits<_ForwardIterator>::value_type 00191 _ValueType; 00192 #if __cplusplus < 201103L 00193 const bool __assignable = true; 00194 #else 00195 // Trivial types can have deleted copy constructor, but the std::fill 00196 // optimization that uses memmove would happily "copy" them anyway. 00197 static_assert(is_constructible<_ValueType, const _Tp&>::value, 00198 "result type must be constructible from input type"); 00199 00200 // Trivial types can have deleted assignment, so using std::fill 00201 // would be ill-formed. Require assignability before using std::fill: 00202 const bool __assignable = is_copy_assignable<_ValueType>::value; 00203 #endif 00204 00205 std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: 00206 __uninit_fill(__first, __last, __x); 00207 } 00208 00209 00210 template<bool _TrivialValueType> 00211 struct __uninitialized_fill_n 00212 { 00213 template<typename _ForwardIterator, typename _Size, typename _Tp> 00214 static _ForwardIterator 00215 __uninit_fill_n(_ForwardIterator __first, _Size __n, 00216 const _Tp& __x) 00217 { 00218 _ForwardIterator __cur = __first; 00219 __try 00220 { 00221 for (; __n > 0; --__n, (void) ++__cur) 00222 std::_Construct(std::__addressof(*__cur), __x); 00223 return __cur; 00224 } 00225 __catch(...) 00226 { 00227 std::_Destroy(__first, __cur); 00228 __throw_exception_again; 00229 } 00230 } 00231 }; 00232 00233 template<> 00234 struct __uninitialized_fill_n<true> 00235 { 00236 template<typename _ForwardIterator, typename _Size, typename _Tp> 00237 static _ForwardIterator 00238 __uninit_fill_n(_ForwardIterator __first, _Size __n, 00239 const _Tp& __x) 00240 { return std::fill_n(__first, __n, __x); } 00241 }; 00242 00243 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00244 // DR 1339. uninitialized_fill_n should return the end of its range 00245 /** 00246 * @brief Copies the value x into the range [first,first+n). 00247 * @param __first An input iterator. 00248 * @param __n The number of copies to make. 00249 * @param __x The source value. 00250 * @return Nothing. 00251 * 00252 * Like fill_n(), but does not require an initialized output range. 00253 */ 00254 template<typename _ForwardIterator, typename _Size, typename _Tp> 00255 inline _ForwardIterator 00256 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 00257 { 00258 typedef typename iterator_traits<_ForwardIterator>::value_type 00259 _ValueType; 00260 #if __cplusplus < 201103L 00261 const bool __assignable = true; 00262 #else 00263 // Trivial types can have deleted copy constructor, but the std::fill 00264 // optimization that uses memmove would happily "copy" them anyway. 00265 static_assert(is_constructible<_ValueType, const _Tp&>::value, 00266 "result type must be constructible from input type"); 00267 00268 // Trivial types can have deleted assignment, so using std::fill 00269 // would be ill-formed. Require assignability before using std::fill: 00270 const bool __assignable = is_copy_assignable<_ValueType>::value; 00271 #endif 00272 return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: 00273 __uninit_fill_n(__first, __n, __x); 00274 } 00275 00276 // Extensions: versions of uninitialized_copy, uninitialized_fill, 00277 // and uninitialized_fill_n that take an allocator parameter. 00278 // We dispatch back to the standard versions when we're given the 00279 // default allocator. For nondefault allocators we do not use 00280 // any of the POD optimizations. 00281 00282 template<typename _InputIterator, typename _ForwardIterator, 00283 typename _Allocator> 00284 _ForwardIterator 00285 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00286 _ForwardIterator __result, _Allocator& __alloc) 00287 { 00288 _ForwardIterator __cur = __result; 00289 __try 00290 { 00291 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00292 for (; __first != __last; ++__first, (void)++__cur) 00293 __traits::construct(__alloc, std::__addressof(*__cur), *__first); 00294 return __cur; 00295 } 00296 __catch(...) 00297 { 00298 std::_Destroy(__result, __cur, __alloc); 00299 __throw_exception_again; 00300 } 00301 } 00302 00303 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 00304 inline _ForwardIterator 00305 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00306 _ForwardIterator __result, allocator<_Tp>&) 00307 { return std::uninitialized_copy(__first, __last, __result); } 00308 00309 template<typename _InputIterator, typename _ForwardIterator, 00310 typename _Allocator> 00311 inline _ForwardIterator 00312 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 00313 _ForwardIterator __result, _Allocator& __alloc) 00314 { 00315 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00316 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 00317 __result, __alloc); 00318 } 00319 00320 template<typename _InputIterator, typename _ForwardIterator, 00321 typename _Allocator> 00322 inline _ForwardIterator 00323 __uninitialized_move_if_noexcept_a(_InputIterator __first, 00324 _InputIterator __last, 00325 _ForwardIterator __result, 00326 _Allocator& __alloc) 00327 { 00328 return std::__uninitialized_copy_a 00329 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), 00330 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); 00331 } 00332 00333 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 00334 void 00335 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00336 const _Tp& __x, _Allocator& __alloc) 00337 { 00338 _ForwardIterator __cur = __first; 00339 __try 00340 { 00341 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00342 for (; __cur != __last; ++__cur) 00343 __traits::construct(__alloc, std::__addressof(*__cur), __x); 00344 } 00345 __catch(...) 00346 { 00347 std::_Destroy(__first, __cur, __alloc); 00348 __throw_exception_again; 00349 } 00350 } 00351 00352 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 00353 inline void 00354 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00355 const _Tp& __x, allocator<_Tp2>&) 00356 { std::uninitialized_fill(__first, __last, __x); } 00357 00358 template<typename _ForwardIterator, typename _Size, typename _Tp, 00359 typename _Allocator> 00360 _ForwardIterator 00361 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00362 const _Tp& __x, _Allocator& __alloc) 00363 { 00364 _ForwardIterator __cur = __first; 00365 __try 00366 { 00367 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00368 for (; __n > 0; --__n, (void) ++__cur) 00369 __traits::construct(__alloc, std::__addressof(*__cur), __x); 00370 return __cur; 00371 } 00372 __catch(...) 00373 { 00374 std::_Destroy(__first, __cur, __alloc); 00375 __throw_exception_again; 00376 } 00377 } 00378 00379 template<typename _ForwardIterator, typename _Size, typename _Tp, 00380 typename _Tp2> 00381 inline _ForwardIterator 00382 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00383 const _Tp& __x, allocator<_Tp2>&) 00384 { return std::uninitialized_fill_n(__first, __n, __x); } 00385 00386 00387 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 00388 // __uninitialized_fill_move, __uninitialized_move_fill. 00389 // All of these algorithms take a user-supplied allocator, which is used 00390 // for construction and destruction. 00391 00392 // __uninitialized_copy_move 00393 // Copies [first1, last1) into [result, result + (last1 - first1)), and 00394 // move [first2, last2) into 00395 // [result, result + (last1 - first1) + (last2 - first2)). 00396 template<typename _InputIterator1, typename _InputIterator2, 00397 typename _ForwardIterator, typename _Allocator> 00398 inline _ForwardIterator 00399 __uninitialized_copy_move(_InputIterator1 __first1, 00400 _InputIterator1 __last1, 00401 _InputIterator2 __first2, 00402 _InputIterator2 __last2, 00403 _ForwardIterator __result, 00404 _Allocator& __alloc) 00405 { 00406 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 00407 __result, 00408 __alloc); 00409 __try 00410 { 00411 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 00412 } 00413 __catch(...) 00414 { 00415 std::_Destroy(__result, __mid, __alloc); 00416 __throw_exception_again; 00417 } 00418 } 00419 00420 // __uninitialized_move_copy 00421 // Moves [first1, last1) into [result, result + (last1 - first1)), and 00422 // copies [first2, last2) into 00423 // [result, result + (last1 - first1) + (last2 - first2)). 00424 template<typename _InputIterator1, typename _InputIterator2, 00425 typename _ForwardIterator, typename _Allocator> 00426 inline _ForwardIterator 00427 __uninitialized_move_copy(_InputIterator1 __first1, 00428 _InputIterator1 __last1, 00429 _InputIterator2 __first2, 00430 _InputIterator2 __last2, 00431 _ForwardIterator __result, 00432 _Allocator& __alloc) 00433 { 00434 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 00435 __result, 00436 __alloc); 00437 __try 00438 { 00439 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 00440 } 00441 __catch(...) 00442 { 00443 std::_Destroy(__result, __mid, __alloc); 00444 __throw_exception_again; 00445 } 00446 } 00447 00448 // __uninitialized_fill_move 00449 // Fills [result, mid) with x, and moves [first, last) into 00450 // [mid, mid + (last - first)). 00451 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 00452 typename _Allocator> 00453 inline _ForwardIterator 00454 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 00455 const _Tp& __x, _InputIterator __first, 00456 _InputIterator __last, _Allocator& __alloc) 00457 { 00458 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 00459 __try 00460 { 00461 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 00462 } 00463 __catch(...) 00464 { 00465 std::_Destroy(__result, __mid, __alloc); 00466 __throw_exception_again; 00467 } 00468 } 00469 00470 // __uninitialized_move_fill 00471 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 00472 // fills [first2 + (last1 - first1), last2) with x. 00473 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 00474 typename _Allocator> 00475 inline void 00476 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 00477 _ForwardIterator __first2, 00478 _ForwardIterator __last2, const _Tp& __x, 00479 _Allocator& __alloc) 00480 { 00481 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 00482 __first2, 00483 __alloc); 00484 __try 00485 { 00486 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 00487 } 00488 __catch(...) 00489 { 00490 std::_Destroy(__first2, __mid2, __alloc); 00491 __throw_exception_again; 00492 } 00493 } 00494 00495 #if __cplusplus >= 201103L 00496 // Extensions: __uninitialized_default, __uninitialized_default_n, 00497 // __uninitialized_default_a, __uninitialized_default_n_a. 00498 00499 template<bool _TrivialValueType> 00500 struct __uninitialized_default_1 00501 { 00502 template<typename _ForwardIterator> 00503 static void 00504 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00505 { 00506 _ForwardIterator __cur = __first; 00507 __try 00508 { 00509 for (; __cur != __last; ++__cur) 00510 std::_Construct(std::__addressof(*__cur)); 00511 } 00512 __catch(...) 00513 { 00514 std::_Destroy(__first, __cur); 00515 __throw_exception_again; 00516 } 00517 } 00518 }; 00519 00520 template<> 00521 struct __uninitialized_default_1<true> 00522 { 00523 template<typename _ForwardIterator> 00524 static void 00525 __uninit_default(_ForwardIterator __first, _ForwardIterator __last) 00526 { 00527 typedef typename iterator_traits<_ForwardIterator>::value_type 00528 _ValueType; 00529 00530 std::fill(__first, __last, _ValueType()); 00531 } 00532 }; 00533 00534 template<bool _TrivialValueType> 00535 struct __uninitialized_default_n_1 00536 { 00537 template<typename _ForwardIterator, typename _Size> 00538 static _ForwardIterator 00539 __uninit_default_n(_ForwardIterator __first, _Size __n) 00540 { 00541 _ForwardIterator __cur = __first; 00542 __try 00543 { 00544 for (; __n > 0; --__n, (void) ++__cur) 00545 std::_Construct(std::__addressof(*__cur)); 00546 return __cur; 00547 } 00548 __catch(...) 00549 { 00550 std::_Destroy(__first, __cur); 00551 __throw_exception_again; 00552 } 00553 } 00554 }; 00555 00556 template<> 00557 struct __uninitialized_default_n_1<true> 00558 { 00559 template<typename _ForwardIterator, typename _Size> 00560 static _ForwardIterator 00561 __uninit_default_n(_ForwardIterator __first, _Size __n) 00562 { 00563 typedef typename iterator_traits<_ForwardIterator>::value_type 00564 _ValueType; 00565 00566 return std::fill_n(__first, __n, _ValueType()); 00567 } 00568 }; 00569 00570 // __uninitialized_default 00571 // Fills [first, last) with std::distance(first, last) default 00572 // constructed value_types(s). 00573 template<typename _ForwardIterator> 00574 inline void 00575 __uninitialized_default(_ForwardIterator __first, 00576 _ForwardIterator __last) 00577 { 00578 typedef typename iterator_traits<_ForwardIterator>::value_type 00579 _ValueType; 00580 // trivial types can have deleted assignment 00581 const bool __assignable = is_copy_assignable<_ValueType>::value; 00582 00583 std::__uninitialized_default_1<__is_trivial(_ValueType) 00584 && __assignable>:: 00585 __uninit_default(__first, __last); 00586 } 00587 00588 // __uninitialized_default_n 00589 // Fills [first, first + n) with n default constructed value_type(s). 00590 template<typename _ForwardIterator, typename _Size> 00591 inline _ForwardIterator 00592 __uninitialized_default_n(_ForwardIterator __first, _Size __n) 00593 { 00594 typedef typename iterator_traits<_ForwardIterator>::value_type 00595 _ValueType; 00596 // trivial types can have deleted assignment 00597 const bool __assignable = is_copy_assignable<_ValueType>::value; 00598 00599 return __uninitialized_default_n_1<__is_trivial(_ValueType) 00600 && __assignable>:: 00601 __uninit_default_n(__first, __n); 00602 } 00603 00604 00605 // __uninitialized_default_a 00606 // Fills [first, last) with std::distance(first, last) default 00607 // constructed value_types(s), constructed with the allocator alloc. 00608 template<typename _ForwardIterator, typename _Allocator> 00609 void 00610 __uninitialized_default_a(_ForwardIterator __first, 00611 _ForwardIterator __last, 00612 _Allocator& __alloc) 00613 { 00614 _ForwardIterator __cur = __first; 00615 __try 00616 { 00617 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00618 for (; __cur != __last; ++__cur) 00619 __traits::construct(__alloc, std::__addressof(*__cur)); 00620 } 00621 __catch(...) 00622 { 00623 std::_Destroy(__first, __cur, __alloc); 00624 __throw_exception_again; 00625 } 00626 } 00627 00628 template<typename _ForwardIterator, typename _Tp> 00629 inline void 00630 __uninitialized_default_a(_ForwardIterator __first, 00631 _ForwardIterator __last, 00632 allocator<_Tp>&) 00633 { std::__uninitialized_default(__first, __last); } 00634 00635 00636 // __uninitialized_default_n_a 00637 // Fills [first, first + n) with n default constructed value_types(s), 00638 // constructed with the allocator alloc. 00639 template<typename _ForwardIterator, typename _Size, typename _Allocator> 00640 _ForwardIterator 00641 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00642 _Allocator& __alloc) 00643 { 00644 _ForwardIterator __cur = __first; 00645 __try 00646 { 00647 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; 00648 for (; __n > 0; --__n, (void) ++__cur) 00649 __traits::construct(__alloc, std::__addressof(*__cur)); 00650 return __cur; 00651 } 00652 __catch(...) 00653 { 00654 std::_Destroy(__first, __cur, __alloc); 00655 __throw_exception_again; 00656 } 00657 } 00658 00659 template<typename _ForwardIterator, typename _Size, typename _Tp> 00660 inline _ForwardIterator 00661 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 00662 allocator<_Tp>&) 00663 { return std::__uninitialized_default_n(__first, __n); } 00664 00665 template<bool _TrivialValueType> 00666 struct __uninitialized_default_novalue_1 00667 { 00668 template<typename _ForwardIterator> 00669 static void 00670 __uninit_default_novalue(_ForwardIterator __first, 00671 _ForwardIterator __last) 00672 { 00673 _ForwardIterator __cur = __first; 00674 __try 00675 { 00676 for (; __cur != __last; ++__cur) 00677 std::_Construct_novalue(std::__addressof(*__cur)); 00678 } 00679 __catch(...) 00680 { 00681 std::_Destroy(__first, __cur); 00682 __throw_exception_again; 00683 } 00684 } 00685 }; 00686 00687 template<> 00688 struct __uninitialized_default_novalue_1<true> 00689 { 00690 template<typename _ForwardIterator> 00691 static void 00692 __uninit_default_novalue(_ForwardIterator __first, 00693 _ForwardIterator __last) 00694 { 00695 } 00696 }; 00697 00698 template<bool _TrivialValueType> 00699 struct __uninitialized_default_novalue_n_1 00700 { 00701 template<typename _ForwardIterator, typename _Size> 00702 static _ForwardIterator 00703 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 00704 { 00705 _ForwardIterator __cur = __first; 00706 __try 00707 { 00708 for (; __n > 0; --__n, (void) ++__cur) 00709 std::_Construct_novalue(std::__addressof(*__cur)); 00710 return __cur; 00711 } 00712 __catch(...) 00713 { 00714 std::_Destroy(__first, __cur); 00715 __throw_exception_again; 00716 } 00717 } 00718 }; 00719 00720 template<> 00721 struct __uninitialized_default_novalue_n_1<true> 00722 { 00723 template<typename _ForwardIterator, typename _Size> 00724 static _ForwardIterator 00725 __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) 00726 { return std::next(__first, __n); } 00727 }; 00728 00729 // __uninitialized_default_novalue 00730 // Fills [first, last) with std::distance(first, last) default-initialized 00731 // value_types(s). 00732 template<typename _ForwardIterator> 00733 inline void 00734 __uninitialized_default_novalue(_ForwardIterator __first, 00735 _ForwardIterator __last) 00736 { 00737 typedef typename iterator_traits<_ForwardIterator>::value_type 00738 _ValueType; 00739 00740 std::__uninitialized_default_novalue_1< 00741 is_trivially_default_constructible<_ValueType>::value>:: 00742 __uninit_default_novalue(__first, __last); 00743 } 00744 00745 // __uninitialized_default_n 00746 // Fills [first, first + n) with n default-initialized value_type(s). 00747 template<typename _ForwardIterator, typename _Size> 00748 inline _ForwardIterator 00749 __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) 00750 { 00751 typedef typename iterator_traits<_ForwardIterator>::value_type 00752 _ValueType; 00753 00754 return __uninitialized_default_novalue_n_1< 00755 is_trivially_default_constructible<_ValueType>::value>:: 00756 __uninit_default_novalue_n(__first, __n); 00757 } 00758 00759 template<typename _InputIterator, typename _Size, 00760 typename _ForwardIterator> 00761 _ForwardIterator 00762 __uninitialized_copy_n(_InputIterator __first, _Size __n, 00763 _ForwardIterator __result, input_iterator_tag) 00764 { 00765 _ForwardIterator __cur = __result; 00766 __try 00767 { 00768 for (; __n > 0; --__n, (void) ++__first, ++__cur) 00769 std::_Construct(std::__addressof(*__cur), *__first); 00770 return __cur; 00771 } 00772 __catch(...) 00773 { 00774 std::_Destroy(__result, __cur); 00775 __throw_exception_again; 00776 } 00777 } 00778 00779 template<typename _RandomAccessIterator, typename _Size, 00780 typename _ForwardIterator> 00781 inline _ForwardIterator 00782 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 00783 _ForwardIterator __result, 00784 random_access_iterator_tag) 00785 { return std::uninitialized_copy(__first, __first + __n, __result); } 00786 00787 template<typename _InputIterator, typename _Size, 00788 typename _ForwardIterator> 00789 pair<_InputIterator, _ForwardIterator> 00790 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 00791 _ForwardIterator __result, input_iterator_tag) 00792 { 00793 _ForwardIterator __cur = __result; 00794 __try 00795 { 00796 for (; __n > 0; --__n, (void) ++__first, ++__cur) 00797 std::_Construct(std::__addressof(*__cur), *__first); 00798 return {__first, __cur}; 00799 } 00800 __catch(...) 00801 { 00802 std::_Destroy(__result, __cur); 00803 __throw_exception_again; 00804 } 00805 } 00806 00807 template<typename _RandomAccessIterator, typename _Size, 00808 typename _ForwardIterator> 00809 inline pair<_RandomAccessIterator, _ForwardIterator> 00810 __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, 00811 _ForwardIterator __result, 00812 random_access_iterator_tag) 00813 { 00814 auto __second_res = uninitialized_copy(__first, __first + __n, __result); 00815 auto __first_res = std::next(__first, __n); 00816 return {__first_res, __second_res}; 00817 } 00818 00819 /** 00820 * @brief Copies the range [first,first+n) into result. 00821 * @param __first An input iterator. 00822 * @param __n The number of elements to copy. 00823 * @param __result An output iterator. 00824 * @return __result + __n 00825 * 00826 * Like copy_n(), but does not require an initialized output range. 00827 */ 00828 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 00829 inline _ForwardIterator 00830 uninitialized_copy_n(_InputIterator __first, _Size __n, 00831 _ForwardIterator __result) 00832 { return std::__uninitialized_copy_n(__first, __n, __result, 00833 std::__iterator_category(__first)); } 00834 00835 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 00836 inline pair<_InputIterator, _ForwardIterator> 00837 __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, 00838 _ForwardIterator __result) 00839 { 00840 return 00841 std::__uninitialized_copy_n_pair(__first, __n, __result, 00842 std::__iterator_category(__first)); 00843 } 00844 00845 #endif 00846 00847 #if __cplusplus >= 201703L 00848 # define __cpp_lib_raw_memory_algorithms 201606L 00849 00850 template <typename _ForwardIterator> 00851 inline void 00852 uninitialized_default_construct(_ForwardIterator __first, 00853 _ForwardIterator __last) 00854 { 00855 __uninitialized_default_novalue(__first, __last); 00856 } 00857 00858 template <typename _ForwardIterator, typename _Size> 00859 inline _ForwardIterator 00860 uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) 00861 { 00862 return __uninitialized_default_novalue_n(__first, __count); 00863 } 00864 00865 template <typename _ForwardIterator> 00866 inline void 00867 uninitialized_value_construct(_ForwardIterator __first, 00868 _ForwardIterator __last) 00869 { 00870 return __uninitialized_default(__first, __last); 00871 } 00872 00873 template <typename _ForwardIterator, typename _Size> 00874 inline _ForwardIterator 00875 uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) 00876 { 00877 return __uninitialized_default_n(__first, __count); 00878 } 00879 00880 template <typename _InputIterator, typename _ForwardIterator> 00881 inline _ForwardIterator 00882 uninitialized_move(_InputIterator __first, _InputIterator __last, 00883 _ForwardIterator __result) 00884 { 00885 return std::uninitialized_copy 00886 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00887 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); 00888 } 00889 00890 template <typename _InputIterator, typename _Size, typename _ForwardIterator> 00891 inline pair<_InputIterator, _ForwardIterator> 00892 uninitialized_move_n(_InputIterator __first, _Size __count, 00893 _ForwardIterator __result) 00894 { 00895 auto __res = std::__uninitialized_copy_n_pair 00896 (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00897 __count, __result); 00898 return {__res.first.base(), __res.second}; 00899 } 00900 #endif // C++17 00901 00902 #if __cplusplus >= 201103L 00903 template<typename _Tp, typename _Up, typename _Allocator> 00904 inline void 00905 __relocate_object_a(_Tp* __dest, _Up* __orig, _Allocator& __alloc) 00906 noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, 00907 __dest, std::move(*__orig))) 00908 && noexcept(std::allocator_traits<_Allocator>::destroy( 00909 __alloc, std::__addressof(*__orig)))) 00910 { 00911 typedef std::allocator_traits<_Allocator> __traits; 00912 __traits::construct(__alloc, __dest, std::move(*__orig)); 00913 __traits::destroy(__alloc, std::__addressof(*__orig)); 00914 } 00915 00916 // This class may be specialized for specific types. 00917 // Also known as is_trivially_relocatable. 00918 template<typename _Tp, typename = void> 00919 struct __is_bitwise_relocatable 00920 : is_trivial<_Tp> { }; 00921 00922 template <typename _Tp, typename _Up> 00923 inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*> 00924 __relocate_a_1(_Tp* __first, _Tp* __last, 00925 _Tp* __result, allocator<_Up>&) noexcept 00926 { 00927 ptrdiff_t __count = __last - __first; 00928 if (__count > 0) 00929 __builtin_memmove(__result, __first, __count * sizeof(_Tp)); 00930 return __result + __count; 00931 } 00932 00933 template <typename _InputIterator, typename _ForwardIterator, 00934 typename _Allocator> 00935 inline _ForwardIterator 00936 __relocate_a_1(_InputIterator __first, _InputIterator __last, 00937 _ForwardIterator __result, _Allocator& __alloc) 00938 noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result), 00939 std::addressof(*__first), 00940 __alloc))) 00941 { 00942 typedef typename iterator_traits<_InputIterator>::value_type 00943 _ValueType; 00944 typedef typename iterator_traits<_ForwardIterator>::value_type 00945 _ValueType2; 00946 static_assert(std::is_same<_ValueType, _ValueType2>::value, 00947 "relocation is only possible for values of the same type"); 00948 _ForwardIterator __cur = __result; 00949 for (; __first != __last; ++__first, (void)++__cur) 00950 std::__relocate_object_a(std::__addressof(*__cur), 00951 std::__addressof(*__first), __alloc); 00952 return __cur; 00953 } 00954 00955 template <typename _InputIterator, typename _ForwardIterator, 00956 typename _Allocator> 00957 inline _ForwardIterator 00958 __relocate_a(_InputIterator __first, _InputIterator __last, 00959 _ForwardIterator __result, _Allocator& __alloc) 00960 noexcept(noexcept(__relocate_a_1(std::__niter_base(__first), 00961 std::__niter_base(__last), 00962 std::__niter_base(__result), __alloc))) 00963 { 00964 return __relocate_a_1(std::__niter_base(__first), 00965 std::__niter_base(__last), 00966 std::__niter_base(__result), __alloc); 00967 } 00968 #endif 00969 00970 _GLIBCXX_END_NAMESPACE_VERSION 00971 } // namespace 00972 00973 #endif /* _STL_UNINITIALIZED_H */