libstdc++
|
00001 // Raw memory manipulators -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /* 00027 * 00028 * Copyright (c) 1994 00029 * Hewlett-Packard Company 00030 * 00031 * Permission to use, copy, modify, distribute and sell this software 00032 * and its documentation for any purpose is hereby granted without fee, 00033 * provided that the above copyright notice appear in all copies and 00034 * that both that copyright notice and this permission notice appear 00035 * in supporting documentation. Hewlett-Packard Company makes no 00036 * representations about the suitability of this software for any 00037 * purpose. It is provided "as is" without express or implied warranty. 00038 * 00039 * 00040 * Copyright (c) 1996,1997 00041 * Silicon Graphics Computer Systems, Inc. 00042 * 00043 * Permission to use, copy, modify, distribute and sell this software 00044 * and its documentation for any purpose is hereby granted without fee, 00045 * provided that the above copyright notice appear in all copies and 00046 * that both that copyright notice and this permission notice appear 00047 * in supporting documentation. Silicon Graphics makes no 00048 * representations about the suitability of this software for any 00049 * purpose. It is provided "as is" without express or implied warranty. 00050 */ 00051 00052 /** @file stl_uninitialized.h 00053 * This is an internal header file, included by other library headers. 00054 * You should not attempt to use it directly. 00055 */ 00056 00057 #ifndef _STL_UNINITIALIZED_H 00058 #define _STL_UNINITIALIZED_H 1 00059 00060 _GLIBCXX_BEGIN_NAMESPACE(std) 00061 00062 template<bool> 00063 struct __uninitialized_copy 00064 { 00065 template<typename _InputIterator, typename _ForwardIterator> 00066 static _ForwardIterator 00067 uninitialized_copy(_InputIterator __first, _InputIterator __last, 00068 _ForwardIterator __result) 00069 { 00070 _ForwardIterator __cur = __result; 00071 __try 00072 { 00073 for (; __first != __last; ++__first, ++__cur) 00074 ::new(static_cast<void*>(&*__cur)) typename 00075 iterator_traits<_ForwardIterator>::value_type(*__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 uninitialized_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_pod(_ValueType1) 00116 && __is_pod(_ValueType2))>:: 00117 uninitialized_copy(__first, __last, __result); 00118 } 00119 00120 00121 template<bool> 00122 struct __uninitialized_fill 00123 { 00124 template<typename _ForwardIterator, typename _Tp> 00125 static void 00126 uninitialized_fill(_ForwardIterator __first, 00127 _ForwardIterator __last, const _Tp& __x) 00128 { 00129 _ForwardIterator __cur = __first; 00130 __try 00131 { 00132 for (; __cur != __last; ++__cur) 00133 std::_Construct(&*__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 uninitialized_fill(_ForwardIterator __first, 00149 _ForwardIterator __last, 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_pod(_ValueType)>:: 00171 uninitialized_fill(__first, __last, __x); 00172 } 00173 00174 00175 template<bool> 00176 struct __uninitialized_fill_n 00177 { 00178 template<typename _ForwardIterator, typename _Size, typename _Tp> 00179 static void 00180 uninitialized_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(&*__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 uninitialized_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_pod(_ValueType)>:: 00224 uninitialized_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 for (; __first != __last; ++__first, ++__cur) 00243 __alloc.construct(&*__cur, *__first); 00244 return __cur; 00245 } 00246 __catch(...) 00247 { 00248 std::_Destroy(__result, __cur, __alloc); 00249 __throw_exception_again; 00250 } 00251 } 00252 00253 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 00254 inline _ForwardIterator 00255 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 00256 _ForwardIterator __result, allocator<_Tp>&) 00257 { return std::uninitialized_copy(__first, __last, __result); } 00258 00259 template<typename _InputIterator, typename _ForwardIterator, 00260 typename _Allocator> 00261 inline _ForwardIterator 00262 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 00263 _ForwardIterator __result, _Allocator& __alloc) 00264 { 00265 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 00266 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 00267 __result, __alloc); 00268 } 00269 00270 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 00271 void 00272 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00273 const _Tp& __x, _Allocator& __alloc) 00274 { 00275 _ForwardIterator __cur = __first; 00276 __try 00277 { 00278 for (; __cur != __last; ++__cur) 00279 __alloc.construct(&*__cur, __x); 00280 } 00281 __catch(...) 00282 { 00283 std::_Destroy(__first, __cur, __alloc); 00284 __throw_exception_again; 00285 } 00286 } 00287 00288 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 00289 inline void 00290 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 00291 const _Tp& __x, allocator<_Tp2>&) 00292 { std::uninitialized_fill(__first, __last, __x); } 00293 00294 template<typename _ForwardIterator, typename _Size, typename _Tp, 00295 typename _Allocator> 00296 void 00297 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00298 const _Tp& __x, _Allocator& __alloc) 00299 { 00300 _ForwardIterator __cur = __first; 00301 __try 00302 { 00303 for (; __n > 0; --__n, ++__cur) 00304 __alloc.construct(&*__cur, __x); 00305 } 00306 __catch(...) 00307 { 00308 std::_Destroy(__first, __cur, __alloc); 00309 __throw_exception_again; 00310 } 00311 } 00312 00313 template<typename _ForwardIterator, typename _Size, typename _Tp, 00314 typename _Tp2> 00315 inline void 00316 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 00317 const _Tp& __x, allocator<_Tp2>&) 00318 { std::uninitialized_fill_n(__first, __n, __x); } 00319 00320 00321 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 00322 // __uninitialized_fill_move, __uninitialized_move_fill. 00323 // All of these algorithms take a user-supplied allocator, which is used 00324 // for construction and destruction. 00325 00326 // __uninitialized_copy_move 00327 // Copies [first1, last1) into [result, result + (last1 - first1)), and 00328 // move [first2, last2) into 00329 // [result, result + (last1 - first1) + (last2 - first2)). 00330 template<typename _InputIterator1, typename _InputIterator2, 00331 typename _ForwardIterator, typename _Allocator> 00332 inline _ForwardIterator 00333 __uninitialized_copy_move(_InputIterator1 __first1, 00334 _InputIterator1 __last1, 00335 _InputIterator2 __first2, 00336 _InputIterator2 __last2, 00337 _ForwardIterator __result, 00338 _Allocator& __alloc) 00339 { 00340 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 00341 __result, 00342 __alloc); 00343 __try 00344 { 00345 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 00346 } 00347 __catch(...) 00348 { 00349 std::_Destroy(__result, __mid, __alloc); 00350 __throw_exception_again; 00351 } 00352 } 00353 00354 // __uninitialized_move_copy 00355 // Moves [first1, last1) into [result, result + (last1 - first1)), and 00356 // copies [first2, last2) into 00357 // [result, result + (last1 - first1) + (last2 - first2)). 00358 template<typename _InputIterator1, typename _InputIterator2, 00359 typename _ForwardIterator, typename _Allocator> 00360 inline _ForwardIterator 00361 __uninitialized_move_copy(_InputIterator1 __first1, 00362 _InputIterator1 __last1, 00363 _InputIterator2 __first2, 00364 _InputIterator2 __last2, 00365 _ForwardIterator __result, 00366 _Allocator& __alloc) 00367 { 00368 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 00369 __result, 00370 __alloc); 00371 __try 00372 { 00373 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 00374 } 00375 __catch(...) 00376 { 00377 std::_Destroy(__result, __mid, __alloc); 00378 __throw_exception_again; 00379 } 00380 } 00381 00382 // __uninitialized_fill_move 00383 // Fills [result, mid) with x, and moves [first, last) into 00384 // [mid, mid + (last - first)). 00385 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 00386 typename _Allocator> 00387 inline _ForwardIterator 00388 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 00389 const _Tp& __x, _InputIterator __first, 00390 _InputIterator __last, _Allocator& __alloc) 00391 { 00392 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 00393 __try 00394 { 00395 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 00396 } 00397 __catch(...) 00398 { 00399 std::_Destroy(__result, __mid, __alloc); 00400 __throw_exception_again; 00401 } 00402 } 00403 00404 // __uninitialized_move_fill 00405 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 00406 // fills [first2 + (last1 - first1), last2) with x. 00407 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 00408 typename _Allocator> 00409 inline void 00410 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 00411 _ForwardIterator __first2, 00412 _ForwardIterator __last2, const _Tp& __x, 00413 _Allocator& __alloc) 00414 { 00415 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 00416 __first2, 00417 __alloc); 00418 __try 00419 { 00420 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 00421 } 00422 __catch(...) 00423 { 00424 std::_Destroy(__first2, __mid2, __alloc); 00425 __throw_exception_again; 00426 } 00427 } 00428 00429 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00430 template<typename _InputIterator, typename _Size, 00431 typename _ForwardIterator> 00432 _ForwardIterator 00433 __uninitialized_copy_n(_InputIterator __first, _Size __n, 00434 _ForwardIterator __result, input_iterator_tag) 00435 { 00436 _ForwardIterator __cur = __result; 00437 __try 00438 { 00439 for (; __n > 0; --__n, ++__first, ++__cur) 00440 ::new(static_cast<void*>(&*__cur)) typename 00441 iterator_traits<_ForwardIterator>::value_type(*__first); 00442 return __cur; 00443 } 00444 __catch(...) 00445 { 00446 std::_Destroy(__result, __cur); 00447 __throw_exception_again; 00448 } 00449 } 00450 00451 template<typename _RandomAccessIterator, typename _Size, 00452 typename _ForwardIterator> 00453 inline _ForwardIterator 00454 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 00455 _ForwardIterator __result, 00456 random_access_iterator_tag) 00457 { return std::uninitialized_copy(__first, __first + __n, __result); } 00458 00459 /** 00460 * @brief Copies the range [first,first+n) into result. 00461 * @param first An input iterator. 00462 * @param n The number of elements to copy. 00463 * @param result An output iterator. 00464 * @return result + n 00465 * 00466 * Like copy_n(), but does not require an initialized output range. 00467 */ 00468 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 00469 inline _ForwardIterator 00470 uninitialized_copy_n(_InputIterator __first, _Size __n, 00471 _ForwardIterator __result) 00472 { return std::__uninitialized_copy_n(__first, __n, __result, 00473 std::__iterator_category(__first)); } 00474 #endif 00475 00476 _GLIBCXX_END_NAMESPACE 00477 00478 #endif /* _STL_UNINITIALIZED_H */