1// Raw memory manipulators -*- C++ -*- 2 3// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// Under Section 7 of GPL version 3, you are granted additional 18// permissions described in the GCC Runtime Library Exception, version 19// 3.1, as published by the Free Software Foundation. 20 21// You should have received a copy of the GNU General Public License and 22// a copy of the GCC Runtime Library Exception along with this program; 23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24// <http://www.gnu.org/licenses/>. 25 26/* 27 * 28 * Copyright (c) 1994 29 * Hewlett-Packard Company 30 * 31 * Permission to use, copy, modify, distribute and sell this software 32 * and its documentation for any purpose is hereby granted without fee, 33 * provided that the above copyright notice appear in all copies and 34 * that both that copyright notice and this permission notice appear 35 * in supporting documentation. Hewlett-Packard Company makes no 36 * representations about the suitability of this software for any 37 * purpose. It is provided "as is" without express or implied warranty. 38 * 39 * 40 * Copyright (c) 1996,1997 41 * Silicon Graphics Computer Systems, Inc. 42 * 43 * Permission to use, copy, modify, distribute and sell this software 44 * and its documentation for any purpose is hereby granted without fee, 45 * provided that the above copyright notice appear in all copies and 46 * that both that copyright notice and this permission notice appear 47 * in supporting documentation. Silicon Graphics makes no 48 * representations about the suitability of this software for any 49 * purpose. It is provided "as is" without express or implied warranty. 50 */ 51 52/** @file stl_uninitialized.h 53 * This is an internal header file, included by other library headers. 54 * You should not attempt to use it directly. 55 */ 56 57#ifndef _STL_UNINITIALIZED_H 58#define _STL_UNINITIALIZED_H 1 59 60_GLIBCXX_BEGIN_NAMESPACE(std) 61 62 template<bool> 63 struct __uninitialized_copy 64 { 65 template<typename _InputIterator, typename _ForwardIterator> 66 static _ForwardIterator 67 uninitialized_copy(_InputIterator __first, _InputIterator __last, 68 _ForwardIterator __result) 69 { 70 _ForwardIterator __cur = __result; 71 __try 72 { 73 for (; __first != __last; ++__first, ++__cur) 74 ::new(static_cast<void*>(&*__cur)) typename 75 iterator_traits<_ForwardIterator>::value_type(*__first); 76 return __cur; 77 } 78 __catch(...) 79 { 80 std::_Destroy(__result, __cur); 81 __throw_exception_again; 82 } 83 } 84 }; 85 86 template<> 87 struct __uninitialized_copy<true> 88 { 89 template<typename _InputIterator, typename _ForwardIterator> 90 static _ForwardIterator 91 uninitialized_copy(_InputIterator __first, _InputIterator __last, 92 _ForwardIterator __result) 93 { return std::copy(__first, __last, __result); } 94 }; 95 96 /** 97 * @brief Copies the range [first,last) into result. 98 * @param first An input iterator. 99 * @param last An input iterator. 100 * @param result An output iterator. 101 * @return result + (first - last) 102 * 103 * Like copy(), but does not require an initialized output range. 104 */ 105 template<typename _InputIterator, typename _ForwardIterator> 106 inline _ForwardIterator 107 uninitialized_copy(_InputIterator __first, _InputIterator __last, 108 _ForwardIterator __result) 109 { 110 typedef typename iterator_traits<_InputIterator>::value_type 111 _ValueType1; 112 typedef typename iterator_traits<_ForwardIterator>::value_type 113 _ValueType2; 114 115 return std::__uninitialized_copy<(__is_pod(_ValueType1) 116 && __is_pod(_ValueType2))>:: 117 uninitialized_copy(__first, __last, __result); 118 } 119 120 121 template<bool> 122 struct __uninitialized_fill 123 { 124 template<typename _ForwardIterator, typename _Tp> 125 static void 126 uninitialized_fill(_ForwardIterator __first, 127 _ForwardIterator __last, const _Tp& __x) 128 { 129 _ForwardIterator __cur = __first; 130 __try 131 { 132 for (; __cur != __last; ++__cur) 133 std::_Construct(&*__cur, __x); 134 } 135 __catch(...) 136 { 137 std::_Destroy(__first, __cur); 138 __throw_exception_again; 139 } 140 } 141 }; 142 143 template<> 144 struct __uninitialized_fill<true> 145 { 146 template<typename _ForwardIterator, typename _Tp> 147 static void 148 uninitialized_fill(_ForwardIterator __first, 149 _ForwardIterator __last, const _Tp& __x) 150 { std::fill(__first, __last, __x); } 151 }; 152 153 /** 154 * @brief Copies the value x into the range [first,last). 155 * @param first An input iterator. 156 * @param last An input iterator. 157 * @param x The source value. 158 * @return Nothing. 159 * 160 * Like fill(), but does not require an initialized output range. 161 */ 162 template<typename _ForwardIterator, typename _Tp> 163 inline void 164 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 165 const _Tp& __x) 166 { 167 typedef typename iterator_traits<_ForwardIterator>::value_type 168 _ValueType; 169 170 std::__uninitialized_fill<__is_pod(_ValueType)>:: 171 uninitialized_fill(__first, __last, __x); 172 } 173 174 175 template<bool> 176 struct __uninitialized_fill_n 177 { 178 template<typename _ForwardIterator, typename _Size, typename _Tp> 179 static void 180 uninitialized_fill_n(_ForwardIterator __first, _Size __n, 181 const _Tp& __x) 182 { 183 _ForwardIterator __cur = __first; 184 __try 185 { 186 for (; __n > 0; --__n, ++__cur) 187 std::_Construct(&*__cur, __x); 188 } 189 __catch(...) 190 { 191 std::_Destroy(__first, __cur); 192 __throw_exception_again; 193 } 194 } 195 }; 196 197 template<> 198 struct __uninitialized_fill_n<true> 199 { 200 template<typename _ForwardIterator, typename _Size, typename _Tp> 201 static void 202 uninitialized_fill_n(_ForwardIterator __first, _Size __n, 203 const _Tp& __x) 204 { std::fill_n(__first, __n, __x); } 205 }; 206 207 /** 208 * @brief Copies the value x into the range [first,first+n). 209 * @param first An input iterator. 210 * @param n The number of copies to make. 211 * @param x The source value. 212 * @return Nothing. 213 * 214 * Like fill_n(), but does not require an initialized output range. 215 */ 216 template<typename _ForwardIterator, typename _Size, typename _Tp> 217 inline void 218 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 219 { 220 typedef typename iterator_traits<_ForwardIterator>::value_type 221 _ValueType; 222 223 std::__uninitialized_fill_n<__is_pod(_ValueType)>:: 224 uninitialized_fill_n(__first, __n, __x); 225 } 226 227 // Extensions: versions of uninitialized_copy, uninitialized_fill, 228 // and uninitialized_fill_n that take an allocator parameter. 229 // We dispatch back to the standard versions when we're given the 230 // default allocator. For nondefault allocators we do not use 231 // any of the POD optimizations. 232 233 template<typename _InputIterator, typename _ForwardIterator, 234 typename _Allocator> 235 _ForwardIterator 236 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 237 _ForwardIterator __result, _Allocator& __alloc) 238 { 239 _ForwardIterator __cur = __result; 240 __try 241 { 242 for (; __first != __last; ++__first, ++__cur) 243 __alloc.construct(&*__cur, *__first); 244 return __cur; 245 } 246 __catch(...) 247 { 248 std::_Destroy(__result, __cur, __alloc); 249 __throw_exception_again; 250 } 251 } 252 253 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 254 inline _ForwardIterator 255 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 256 _ForwardIterator __result, allocator<_Tp>&) 257 { return std::uninitialized_copy(__first, __last, __result); } 258 259 template<typename _InputIterator, typename _ForwardIterator, 260 typename _Allocator> 261 inline _ForwardIterator 262 __uninitialized_move_a(_InputIterator __first, _InputIterator __last, 263 _ForwardIterator __result, _Allocator& __alloc) 264 { 265 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), 266 _GLIBCXX_MAKE_MOVE_ITERATOR(__last), 267 __result, __alloc); 268 } 269 270 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 271 void 272 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 273 const _Tp& __x, _Allocator& __alloc) 274 { 275 _ForwardIterator __cur = __first; 276 __try 277 { 278 for (; __cur != __last; ++__cur) 279 __alloc.construct(&*__cur, __x); 280 } 281 __catch(...) 282 { 283 std::_Destroy(__first, __cur, __alloc); 284 __throw_exception_again; 285 } 286 } 287 288 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 289 inline void 290 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 291 const _Tp& __x, allocator<_Tp2>&) 292 { std::uninitialized_fill(__first, __last, __x); } 293 294 template<typename _ForwardIterator, typename _Size, typename _Tp, 295 typename _Allocator> 296 void 297 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 298 const _Tp& __x, _Allocator& __alloc) 299 { 300 _ForwardIterator __cur = __first; 301 __try 302 { 303 for (; __n > 0; --__n, ++__cur) 304 __alloc.construct(&*__cur, __x); 305 } 306 __catch(...) 307 { 308 std::_Destroy(__first, __cur, __alloc); 309 __throw_exception_again; 310 } 311 } 312 313 template<typename _ForwardIterator, typename _Size, typename _Tp, 314 typename _Tp2> 315 inline void 316 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 317 const _Tp& __x, allocator<_Tp2>&) 318 { std::uninitialized_fill_n(__first, __n, __x); } 319 320 321 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, 322 // __uninitialized_fill_move, __uninitialized_move_fill. 323 // All of these algorithms take a user-supplied allocator, which is used 324 // for construction and destruction. 325 326 // __uninitialized_copy_move 327 // Copies [first1, last1) into [result, result + (last1 - first1)), and 328 // move [first2, last2) into 329 // [result, result + (last1 - first1) + (last2 - first2)). 330 template<typename _InputIterator1, typename _InputIterator2, 331 typename _ForwardIterator, typename _Allocator> 332 inline _ForwardIterator 333 __uninitialized_copy_move(_InputIterator1 __first1, 334 _InputIterator1 __last1, 335 _InputIterator2 __first2, 336 _InputIterator2 __last2, 337 _ForwardIterator __result, 338 _Allocator& __alloc) 339 { 340 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 341 __result, 342 __alloc); 343 __try 344 { 345 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); 346 } 347 __catch(...) 348 { 349 std::_Destroy(__result, __mid, __alloc); 350 __throw_exception_again; 351 } 352 } 353 354 // __uninitialized_move_copy 355 // Moves [first1, last1) into [result, result + (last1 - first1)), and 356 // copies [first2, last2) into 357 // [result, result + (last1 - first1) + (last2 - first2)). 358 template<typename _InputIterator1, typename _InputIterator2, 359 typename _ForwardIterator, typename _Allocator> 360 inline _ForwardIterator 361 __uninitialized_move_copy(_InputIterator1 __first1, 362 _InputIterator1 __last1, 363 _InputIterator2 __first2, 364 _InputIterator2 __last2, 365 _ForwardIterator __result, 366 _Allocator& __alloc) 367 { 368 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, 369 __result, 370 __alloc); 371 __try 372 { 373 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 374 } 375 __catch(...) 376 { 377 std::_Destroy(__result, __mid, __alloc); 378 __throw_exception_again; 379 } 380 } 381 382 // __uninitialized_fill_move 383 // Fills [result, mid) with x, and moves [first, last) into 384 // [mid, mid + (last - first)). 385 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 386 typename _Allocator> 387 inline _ForwardIterator 388 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, 389 const _Tp& __x, _InputIterator __first, 390 _InputIterator __last, _Allocator& __alloc) 391 { 392 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 393 __try 394 { 395 return std::__uninitialized_move_a(__first, __last, __mid, __alloc); 396 } 397 __catch(...) 398 { 399 std::_Destroy(__result, __mid, __alloc); 400 __throw_exception_again; 401 } 402 } 403 404 // __uninitialized_move_fill 405 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and 406 // fills [first2 + (last1 - first1), last2) with x. 407 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 408 typename _Allocator> 409 inline void 410 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, 411 _ForwardIterator __first2, 412 _ForwardIterator __last2, const _Tp& __x, 413 _Allocator& __alloc) 414 { 415 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, 416 __first2, 417 __alloc); 418 __try 419 { 420 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 421 } 422 __catch(...) 423 { 424 std::_Destroy(__first2, __mid2, __alloc); 425 __throw_exception_again; 426 } 427 } 428 429#ifdef __GXX_EXPERIMENTAL_CXX0X__ 430 template<typename _InputIterator, typename _Size, 431 typename _ForwardIterator> 432 _ForwardIterator 433 __uninitialized_copy_n(_InputIterator __first, _Size __n, 434 _ForwardIterator __result, input_iterator_tag) 435 { 436 _ForwardIterator __cur = __result; 437 __try 438 { 439 for (; __n > 0; --__n, ++__first, ++__cur) 440 ::new(static_cast<void*>(&*__cur)) typename 441 iterator_traits<_ForwardIterator>::value_type(*__first); 442 return __cur; 443 } 444 __catch(...) 445 { 446 std::_Destroy(__result, __cur); 447 __throw_exception_again; 448 } 449 } 450 451 template<typename _RandomAccessIterator, typename _Size, 452 typename _ForwardIterator> 453 inline _ForwardIterator 454 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, 455 _ForwardIterator __result, 456 random_access_iterator_tag) 457 { return std::uninitialized_copy(__first, __first + __n, __result); } 458 459 /** 460 * @brief Copies the range [first,first+n) into result. 461 * @param first An input iterator. 462 * @param n The number of elements to copy. 463 * @param result An output iterator. 464 * @return result + n 465 * 466 * Like copy_n(), but does not require an initialized output range. 467 */ 468 template<typename _InputIterator, typename _Size, typename _ForwardIterator> 469 inline _ForwardIterator 470 uninitialized_copy_n(_InputIterator __first, _Size __n, 471 _ForwardIterator __result) 472 { return std::__uninitialized_copy_n(__first, __n, __result, 473 std::__iterator_category(__first)); } 474#endif 475 476_GLIBCXX_END_NAMESPACE 477 478#endif /* _STL_UNINITIALIZED_H */ 479