1// Raw memory manipulators -*- C++ -*- 2 3// Copyright (C) 2001, 2004, 2005 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 2, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// You should have received a copy of the GNU General Public License along 17// with this library; see the file COPYING. If not, write to the Free 18// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 19// USA. 20 21// As a special exception, you may use this file as part of a free software 22// library without restriction. Specifically, if other files instantiate 23// templates or use macros or inline functions from this file, or you compile 24// this file and link it with other files to produce an executable, this 25// file does not by itself cause the resulting executable to be covered by 26// the GNU General Public License. This exception does not however 27// invalidate any other reasons why the executable file might be covered by 28// the GNU General Public License. 29 30/* 31 * 32 * Copyright (c) 1994 33 * Hewlett-Packard Company 34 * 35 * Permission to use, copy, modify, distribute and sell this software 36 * and its documentation for any purpose is hereby granted without fee, 37 * provided that the above copyright notice appear in all copies and 38 * that both that copyright notice and this permission notice appear 39 * in supporting documentation. Hewlett-Packard Company makes no 40 * representations about the suitability of this software for any 41 * purpose. It is provided "as is" without express or implied warranty. 42 * 43 * 44 * Copyright (c) 1996,1997 45 * Silicon Graphics Computer Systems, Inc. 46 * 47 * Permission to use, copy, modify, distribute and sell this software 48 * and its documentation for any purpose is hereby granted without fee, 49 * provided that the above copyright notice appear in all copies and 50 * that both that copyright notice and this permission notice appear 51 * in supporting documentation. Silicon Graphics makes no 52 * representations about the suitability of this software for any 53 * purpose. It is provided "as is" without express or implied warranty. 54 */ 55 56/** @file stl_uninitialized.h 57 * This is an internal header file, included by other library headers. 58 * You should not attempt to use it directly. 59 */ 60 61#ifndef _STL_UNINITIALIZED_H 62#define _STL_UNINITIALIZED_H 1 63 64#include <cstring> 65 66namespace std 67{ 68 // uninitialized_copy 69 template<typename _InputIterator, typename _ForwardIterator> 70 inline _ForwardIterator 71 __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, 72 _ForwardIterator __result, 73 __true_type) 74 { return std::copy(__first, __last, __result); } 75 76 template<typename _InputIterator, typename _ForwardIterator> 77 inline _ForwardIterator 78 __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, 79 _ForwardIterator __result, 80 __false_type) 81 { 82 _ForwardIterator __cur = __result; 83 try 84 { 85 for (; __first != __last; ++__first, ++__cur) 86 std::_Construct(&*__cur, *__first); 87 return __cur; 88 } 89 catch(...) 90 { 91 std::_Destroy(__result, __cur); 92 __throw_exception_again; 93 } 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<_ForwardIterator>::value_type _ValueType; 111 typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 112 return std::__uninitialized_copy_aux(__first, __last, __result, 113 _Is_POD()); 114 } 115 116 inline char* 117 uninitialized_copy(const char* __first, const char* __last, char* __result) 118 { 119 std::memmove(__result, __first, __last - __first); 120 return __result + (__last - __first); 121 } 122 123 inline wchar_t* 124 uninitialized_copy(const wchar_t* __first, const wchar_t* __last, 125 wchar_t* __result) 126 { 127 std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); 128 return __result + (__last - __first); 129 } 130 131 // Valid if copy construction is equivalent to assignment, and if the 132 // destructor is trivial. 133 template<typename _ForwardIterator, typename _Tp> 134 inline void 135 __uninitialized_fill_aux(_ForwardIterator __first, 136 _ForwardIterator __last, 137 const _Tp& __x, __true_type) 138 { std::fill(__first, __last, __x); } 139 140 template<typename _ForwardIterator, typename _Tp> 141 void 142 __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, 143 const _Tp& __x, __false_type) 144 { 145 _ForwardIterator __cur = __first; 146 try 147 { 148 for (; __cur != __last; ++__cur) 149 std::_Construct(&*__cur, __x); 150 } 151 catch(...) 152 { 153 std::_Destroy(__first, __cur); 154 __throw_exception_again; 155 } 156 } 157 158 /** 159 * @brief Copies the value x into the range [first,last). 160 * @param first An input iterator. 161 * @param last An input iterator. 162 * @param x The source value. 163 * @return Nothing. 164 * 165 * Like fill(), but does not require an initialized output range. 166 */ 167 template<typename _ForwardIterator, typename _Tp> 168 inline void 169 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 170 const _Tp& __x) 171 { 172 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 173 typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 174 std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); 175 } 176 177 // Valid if copy construction is equivalent to assignment, and if the 178 // destructor is trivial. 179 template<typename _ForwardIterator, typename _Size, typename _Tp> 180 inline void 181 __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, 182 const _Tp& __x, __true_type) 183 { std::fill_n(__first, __n, __x); } 184 185 template<typename _ForwardIterator, typename _Size, typename _Tp> 186 void 187 __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, 188 const _Tp& __x, __false_type) 189 { 190 _ForwardIterator __cur = __first; 191 try 192 { 193 for (; __n > 0; --__n, ++__cur) 194 std::_Construct(&*__cur, __x); 195 } 196 catch(...) 197 { 198 std::_Destroy(__first, __cur); 199 __throw_exception_again; 200 } 201 } 202 203 /** 204 * @brief Copies the value x into the range [first,first+n). 205 * @param first An input iterator. 206 * @param n The number of copies to make. 207 * @param x The source value. 208 * @return Nothing. 209 * 210 * Like fill_n(), but does not require an initialized output range. 211 */ 212 template<typename _ForwardIterator, typename _Size, typename _Tp> 213 inline void 214 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 215 { 216 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 217 typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 218 std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); 219 } 220 221 // Extensions: versions of uninitialized_copy, uninitialized_fill, 222 // and uninitialized_fill_n that take an allocator parameter. 223 // We dispatch back to the standard versions when we're given the 224 // default allocator. For nondefault allocators we do not use 225 // any of the POD optimizations. 226 227 template<typename _InputIterator, typename _ForwardIterator, 228 typename _Allocator> 229 _ForwardIterator 230 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 231 _ForwardIterator __result, 232 _Allocator __alloc) 233 { 234 _ForwardIterator __cur = __result; 235 try 236 { 237 for (; __first != __last; ++__first, ++__cur) 238 __alloc.construct(&*__cur, *__first); 239 return __cur; 240 } 241 catch(...) 242 { 243 std::_Destroy(__result, __cur, __alloc); 244 __throw_exception_again; 245 } 246 } 247 248 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 249 inline _ForwardIterator 250 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 251 _ForwardIterator __result, 252 allocator<_Tp>) 253 { 254 return std::uninitialized_copy(__first, __last, __result); 255 } 256 257 template<typename _ForwardIterator, typename _Tp, typename _Allocator> 258 void 259 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 260 const _Tp& __x, _Allocator __alloc) 261 { 262 _ForwardIterator __cur = __first; 263 try 264 { 265 for (; __cur != __last; ++__cur) 266 __alloc.construct(&*__cur, __x); 267 } 268 catch(...) 269 { 270 std::_Destroy(__first, __cur, __alloc); 271 __throw_exception_again; 272 } 273 } 274 275 template<typename _ForwardIterator, typename _Tp, typename _Tp2> 276 inline void 277 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 278 const _Tp& __x, allocator<_Tp2>) 279 { 280 std::uninitialized_fill(__first, __last, __x); 281 } 282 283 template<typename _ForwardIterator, typename _Size, typename _Tp, 284 typename _Allocator> 285 void 286 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 287 const _Tp& __x, 288 _Allocator __alloc) 289 { 290 _ForwardIterator __cur = __first; 291 try 292 { 293 for (; __n > 0; --__n, ++__cur) 294 __alloc.construct(&*__cur, __x); 295 } 296 catch(...) 297 { 298 std::_Destroy(__first, __cur, __alloc); 299 __throw_exception_again; 300 } 301 } 302 303 template<typename _ForwardIterator, typename _Size, typename _Tp, 304 typename _Tp2> 305 void 306 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 307 const _Tp& __x, 308 allocator<_Tp2>) 309 { 310 std::uninitialized_fill_n(__first, __n, __x); 311 } 312 313 314 // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, 315 // __uninitialized_fill_copy. All of these algorithms take a user- 316 // supplied allocator, which is used for construction and destruction. 317 318 // __uninitialized_copy_copy 319 // Copies [first1, last1) into [result, result + (last1 - first1)), and 320 // copies [first2, last2) into 321 // [result, result + (last1 - first1) + (last2 - first2)). 322 323 template<typename _InputIterator1, typename _InputIterator2, 324 typename _ForwardIterator, typename _Allocator> 325 inline _ForwardIterator 326 __uninitialized_copy_copy(_InputIterator1 __first1, 327 _InputIterator1 __last1, 328 _InputIterator2 __first2, 329 _InputIterator2 __last2, 330 _ForwardIterator __result, 331 _Allocator __alloc) 332 { 333 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 334 __result, 335 __alloc); 336 try 337 { 338 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 339 } 340 catch(...) 341 { 342 std::_Destroy(__result, __mid, __alloc); 343 __throw_exception_again; 344 } 345 } 346 347 // __uninitialized_fill_copy 348 // Fills [result, mid) with x, and copies [first, last) into 349 // [mid, mid + (last - first)). 350 template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 351 typename _Allocator> 352 inline _ForwardIterator 353 __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, 354 const _Tp& __x, _InputIterator __first, 355 _InputIterator __last, 356 _Allocator __alloc) 357 { 358 std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 359 try 360 { 361 return std::__uninitialized_copy_a(__first, __last, __mid, __alloc); 362 } 363 catch(...) 364 { 365 std::_Destroy(__result, __mid, __alloc); 366 __throw_exception_again; 367 } 368 } 369 370 // __uninitialized_copy_fill 371 // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and 372 // fills [first2 + (last1 - first1), last2) with x. 373 template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 374 typename _Allocator> 375 inline void 376 __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, 377 _ForwardIterator __first2, 378 _ForwardIterator __last2, const _Tp& __x, 379 _Allocator __alloc) 380 { 381 _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1, 382 __first2, 383 __alloc); 384 try 385 { 386 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 387 } 388 catch(...) 389 { 390 std::_Destroy(__first2, __mid2, __alloc); 391 __throw_exception_again; 392 } 393 } 394 395} // namespace std 396 397#endif /* _STL_UNINITIALIZED_H */ 398