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