197403Sobrien// Raw memory manipulators -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 4169691Skan// Free Software Foundation, Inc. 597403Sobrien// 697403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 797403Sobrien// software; you can redistribute it and/or modify it under the 897403Sobrien// terms of the GNU General Public License as published by the 997403Sobrien// Free Software Foundation; either version 2, or (at your option) 1097403Sobrien// any later version. 1197403Sobrien 1297403Sobrien// This library is distributed in the hope that it will be useful, 1397403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1497403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1597403Sobrien// GNU General Public License for more details. 1697403Sobrien 1797403Sobrien// You should have received a copy of the GNU General Public License along 1897403Sobrien// with this library; see the file COPYING. If not, write to the Free 19169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2097403Sobrien// USA. 2197403Sobrien 2297403Sobrien// As a special exception, you may use this file as part of a free software 2397403Sobrien// library without restriction. Specifically, if other files instantiate 2497403Sobrien// templates or use macros or inline functions from this file, or you compile 2597403Sobrien// this file and link it with other files to produce an executable, this 2697403Sobrien// file does not by itself cause the resulting executable to be covered by 2797403Sobrien// the GNU General Public License. This exception does not however 2897403Sobrien// invalidate any other reasons why the executable file might be covered by 2997403Sobrien// the GNU General Public License. 3097403Sobrien 3197403Sobrien/* 3297403Sobrien * 3397403Sobrien * Copyright (c) 1994 3497403Sobrien * Hewlett-Packard Company 3597403Sobrien * 3697403Sobrien * Permission to use, copy, modify, distribute and sell this software 3797403Sobrien * and its documentation for any purpose is hereby granted without fee, 3897403Sobrien * provided that the above copyright notice appear in all copies and 3997403Sobrien * that both that copyright notice and this permission notice appear 4097403Sobrien * in supporting documentation. Hewlett-Packard Company makes no 4197403Sobrien * representations about the suitability of this software for any 4297403Sobrien * purpose. It is provided "as is" without express or implied warranty. 4397403Sobrien * 4497403Sobrien * 4597403Sobrien * Copyright (c) 1996,1997 4697403Sobrien * Silicon Graphics Computer Systems, Inc. 4797403Sobrien * 4897403Sobrien * Permission to use, copy, modify, distribute and sell this software 4997403Sobrien * and its documentation for any purpose is hereby granted without fee, 5097403Sobrien * provided that the above copyright notice appear in all copies and 5197403Sobrien * that both that copyright notice and this permission notice appear 5297403Sobrien * in supporting documentation. Silicon Graphics makes no 5397403Sobrien * representations about the suitability of this software for any 5497403Sobrien * purpose. It is provided "as is" without express or implied warranty. 5597403Sobrien */ 5697403Sobrien 5797403Sobrien/** @file stl_uninitialized.h 5897403Sobrien * This is an internal header file, included by other library headers. 5997403Sobrien * You should not attempt to use it directly. 6097403Sobrien */ 6197403Sobrien 62132720Skan#ifndef _STL_UNINITIALIZED_H 63132720Skan#define _STL_UNINITIALIZED_H 1 6497403Sobrien 6597403Sobrien#include <cstring> 6697403Sobrien 67169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 68169691Skan 6997403Sobrien // uninitialized_copy 70132720Skan template<typename _InputIterator, typename _ForwardIterator> 71132720Skan inline _ForwardIterator 72132720Skan __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, 73132720Skan _ForwardIterator __result, 7497403Sobrien __true_type) 75132720Skan { return std::copy(__first, __last, __result); } 7697403Sobrien 77132720Skan template<typename _InputIterator, typename _ForwardIterator> 78132720Skan inline _ForwardIterator 79132720Skan __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last, 80132720Skan _ForwardIterator __result, 8197403Sobrien __false_type) 8297403Sobrien { 83132720Skan _ForwardIterator __cur = __result; 84132720Skan try 85132720Skan { 86169691Skan for (; __first != __last; ++__first, ++__cur) 87132720Skan std::_Construct(&*__cur, *__first); 88132720Skan return __cur; 89132720Skan } 9097403Sobrien catch(...) 9197403Sobrien { 92132720Skan std::_Destroy(__result, __cur); 93132720Skan __throw_exception_again; 9497403Sobrien } 9597403Sobrien } 9697403Sobrien 9797403Sobrien /** 9897403Sobrien * @brief Copies the range [first,last) into result. 9997403Sobrien * @param first An input iterator. 10097403Sobrien * @param last An input iterator. 10197403Sobrien * @param result An output iterator. 10297403Sobrien * @return result + (first - last) 10397403Sobrien * 10497403Sobrien * Like copy(), but does not require an initialized output range. 10597403Sobrien */ 106132720Skan template<typename _InputIterator, typename _ForwardIterator> 107132720Skan inline _ForwardIterator 108132720Skan uninitialized_copy(_InputIterator __first, _InputIterator __last, 109132720Skan _ForwardIterator __result) 11097403Sobrien { 111132720Skan typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 112169691Skan typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 113132720Skan return std::__uninitialized_copy_aux(__first, __last, __result, 114132720Skan _Is_POD()); 11597403Sobrien } 11697403Sobrien 11797403Sobrien inline char* 11897403Sobrien uninitialized_copy(const char* __first, const char* __last, char* __result) 11997403Sobrien { 120132720Skan std::memmove(__result, __first, __last - __first); 12197403Sobrien return __result + (__last - __first); 12297403Sobrien } 12397403Sobrien 124132720Skan inline wchar_t* 12597403Sobrien uninitialized_copy(const wchar_t* __first, const wchar_t* __last, 12697403Sobrien wchar_t* __result) 12797403Sobrien { 128132720Skan std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first)); 12997403Sobrien return __result + (__last - __first); 13097403Sobrien } 13197403Sobrien 13297403Sobrien // Valid if copy construction is equivalent to assignment, and if the 13397403Sobrien // destructor is trivial. 134132720Skan template<typename _ForwardIterator, typename _Tp> 13597403Sobrien inline void 136132720Skan __uninitialized_fill_aux(_ForwardIterator __first, 137132720Skan _ForwardIterator __last, 13897403Sobrien const _Tp& __x, __true_type) 139132720Skan { std::fill(__first, __last, __x); } 14097403Sobrien 141132720Skan template<typename _ForwardIterator, typename _Tp> 14297403Sobrien void 143132720Skan __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last, 14497403Sobrien const _Tp& __x, __false_type) 14597403Sobrien { 146132720Skan _ForwardIterator __cur = __first; 147132720Skan try 148132720Skan { 149169691Skan for (; __cur != __last; ++__cur) 150132720Skan std::_Construct(&*__cur, __x); 151132720Skan } 15297403Sobrien catch(...) 15397403Sobrien { 154132720Skan std::_Destroy(__first, __cur); 155132720Skan __throw_exception_again; 15697403Sobrien } 15797403Sobrien } 15897403Sobrien 15997403Sobrien /** 16097403Sobrien * @brief Copies the value x into the range [first,last). 16197403Sobrien * @param first An input iterator. 16297403Sobrien * @param last An input iterator. 16397403Sobrien * @param x The source value. 16497403Sobrien * @return Nothing. 16597403Sobrien * 16697403Sobrien * Like fill(), but does not require an initialized output range. 16797403Sobrien */ 168132720Skan template<typename _ForwardIterator, typename _Tp> 16997403Sobrien inline void 170132720Skan uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, 171132720Skan const _Tp& __x) 17297403Sobrien { 173132720Skan typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 174169691Skan typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 175132720Skan std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD()); 17697403Sobrien } 17797403Sobrien 17897403Sobrien // Valid if copy construction is equivalent to assignment, and if the 17997403Sobrien // destructor is trivial. 180132720Skan template<typename _ForwardIterator, typename _Size, typename _Tp> 181169691Skan inline void 182132720Skan __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, 18397403Sobrien const _Tp& __x, __true_type) 184169691Skan { std::fill_n(__first, __n, __x); } 18597403Sobrien 186132720Skan template<typename _ForwardIterator, typename _Size, typename _Tp> 187169691Skan void 188132720Skan __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, 18997403Sobrien const _Tp& __x, __false_type) 19097403Sobrien { 191132720Skan _ForwardIterator __cur = __first; 192132720Skan try 193132720Skan { 194169691Skan for (; __n > 0; --__n, ++__cur) 195132720Skan std::_Construct(&*__cur, __x); 196132720Skan } 19797403Sobrien catch(...) 198132720Skan { 199132720Skan std::_Destroy(__first, __cur); 200132720Skan __throw_exception_again; 20197403Sobrien } 20297403Sobrien } 20397403Sobrien 20497403Sobrien /** 20597403Sobrien * @brief Copies the value x into the range [first,first+n). 20697403Sobrien * @param first An input iterator. 20797403Sobrien * @param n The number of copies to make. 20897403Sobrien * @param x The source value. 209169691Skan * @return Nothing. 21097403Sobrien * 21197403Sobrien * Like fill_n(), but does not require an initialized output range. 21297403Sobrien */ 213132720Skan template<typename _ForwardIterator, typename _Size, typename _Tp> 214169691Skan inline void 215132720Skan uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 21697403Sobrien { 217132720Skan typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 218169691Skan typedef typename std::__is_scalar<_ValueType>::__type _Is_POD; 219169691Skan std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); 22097403Sobrien } 22197403Sobrien 222169691Skan // Extensions: versions of uninitialized_copy, uninitialized_fill, 223169691Skan // and uninitialized_fill_n that take an allocator parameter. 224169691Skan // We dispatch back to the standard versions when we're given the 225169691Skan // default allocator. For nondefault allocators we do not use 226169691Skan // any of the POD optimizations. 227169691Skan 228169691Skan template<typename _InputIterator, typename _ForwardIterator, 229169691Skan typename _Allocator> 230169691Skan _ForwardIterator 231169691Skan __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 232169691Skan _ForwardIterator __result, 233169691Skan _Allocator __alloc) 234169691Skan { 235169691Skan _ForwardIterator __cur = __result; 236169691Skan try 237169691Skan { 238169691Skan for (; __first != __last; ++__first, ++__cur) 239169691Skan __alloc.construct(&*__cur, *__first); 240169691Skan return __cur; 241169691Skan } 242169691Skan catch(...) 243169691Skan { 244169691Skan std::_Destroy(__result, __cur, __alloc); 245169691Skan __throw_exception_again; 246169691Skan } 247169691Skan } 248169691Skan 249169691Skan template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 250169691Skan inline _ForwardIterator 251169691Skan __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, 252169691Skan _ForwardIterator __result, 253169691Skan allocator<_Tp>) 254169691Skan { return std::uninitialized_copy(__first, __last, __result); } 255169691Skan 256169691Skan template<typename _ForwardIterator, typename _Tp, typename _Allocator> 257169691Skan void 258169691Skan __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 259169691Skan const _Tp& __x, _Allocator __alloc) 260169691Skan { 261169691Skan _ForwardIterator __cur = __first; 262169691Skan try 263169691Skan { 264169691Skan for (; __cur != __last; ++__cur) 265169691Skan __alloc.construct(&*__cur, __x); 266169691Skan } 267169691Skan catch(...) 268169691Skan { 269169691Skan std::_Destroy(__first, __cur, __alloc); 270169691Skan __throw_exception_again; 271169691Skan } 272169691Skan } 273169691Skan 274169691Skan template<typename _ForwardIterator, typename _Tp, typename _Tp2> 275169691Skan inline void 276169691Skan __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, 277169691Skan const _Tp& __x, allocator<_Tp2>) 278169691Skan { std::uninitialized_fill(__first, __last, __x); } 279169691Skan 280169691Skan template<typename _ForwardIterator, typename _Size, typename _Tp, 281169691Skan typename _Allocator> 282169691Skan void 283169691Skan __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 284169691Skan const _Tp& __x, 285169691Skan _Allocator __alloc) 286169691Skan { 287169691Skan _ForwardIterator __cur = __first; 288169691Skan try 289169691Skan { 290169691Skan for (; __n > 0; --__n, ++__cur) 291169691Skan __alloc.construct(&*__cur, __x); 292169691Skan } 293169691Skan catch(...) 294169691Skan { 295169691Skan std::_Destroy(__first, __cur, __alloc); 296169691Skan __throw_exception_again; 297169691Skan } 298169691Skan } 299169691Skan 300169691Skan template<typename _ForwardIterator, typename _Size, typename _Tp, 301169691Skan typename _Tp2> 302169691Skan inline void 303169691Skan __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 304169691Skan const _Tp& __x, 305169691Skan allocator<_Tp2>) 306169691Skan { std::uninitialized_fill_n(__first, __n, __x); } 307169691Skan 308169691Skan 309132720Skan // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, 310169691Skan // __uninitialized_fill_copy. All of these algorithms take a user- 311169691Skan // supplied allocator, which is used for construction and destruction. 31297403Sobrien 31397403Sobrien // __uninitialized_copy_copy 31497403Sobrien // Copies [first1, last1) into [result, result + (last1 - first1)), and 31597403Sobrien // copies [first2, last2) into 31697403Sobrien // [result, result + (last1 - first1) + (last2 - first2)). 31797403Sobrien 318132720Skan template<typename _InputIterator1, typename _InputIterator2, 319169691Skan typename _ForwardIterator, typename _Allocator> 320132720Skan inline _ForwardIterator 321132720Skan __uninitialized_copy_copy(_InputIterator1 __first1, 322132720Skan _InputIterator1 __last1, 323132720Skan _InputIterator2 __first2, 324132720Skan _InputIterator2 __last2, 325169691Skan _ForwardIterator __result, 326169691Skan _Allocator __alloc) 32797403Sobrien { 328169691Skan _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, 329169691Skan __result, 330169691Skan __alloc); 331132720Skan try 332132720Skan { 333169691Skan return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); 334132720Skan } 33597403Sobrien catch(...) 336132720Skan { 337169691Skan std::_Destroy(__result, __mid, __alloc); 338132720Skan __throw_exception_again; 33997403Sobrien } 34097403Sobrien } 34197403Sobrien 34297403Sobrien // __uninitialized_fill_copy 34397403Sobrien // Fills [result, mid) with x, and copies [first, last) into 34497403Sobrien // [mid, mid + (last - first)). 345169691Skan template<typename _ForwardIterator, typename _Tp, typename _InputIterator, 346169691Skan typename _Allocator> 347132720Skan inline _ForwardIterator 348132720Skan __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, 349132720Skan const _Tp& __x, _InputIterator __first, 350169691Skan _InputIterator __last, 351169691Skan _Allocator __alloc) 35297403Sobrien { 353169691Skan std::__uninitialized_fill_a(__result, __mid, __x, __alloc); 354132720Skan try 355132720Skan { 356169691Skan return std::__uninitialized_copy_a(__first, __last, __mid, __alloc); 357132720Skan } 35897403Sobrien catch(...) 35997403Sobrien { 360169691Skan std::_Destroy(__result, __mid, __alloc); 361132720Skan __throw_exception_again; 36297403Sobrien } 36397403Sobrien } 36497403Sobrien 36597403Sobrien // __uninitialized_copy_fill 36697403Sobrien // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and 36797403Sobrien // fills [first2 + (last1 - first1), last2) with x. 368169691Skan template<typename _InputIterator, typename _ForwardIterator, typename _Tp, 369169691Skan typename _Allocator> 37097403Sobrien inline void 371132720Skan __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, 372132720Skan _ForwardIterator __first2, 373169691Skan _ForwardIterator __last2, const _Tp& __x, 374169691Skan _Allocator __alloc) 37597403Sobrien { 376169691Skan _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1, 377169691Skan __first2, 378169691Skan __alloc); 379132720Skan try 380132720Skan { 381169691Skan std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); 382132720Skan } 38397403Sobrien catch(...) 38497403Sobrien { 385169691Skan std::_Destroy(__first2, __mid2, __alloc); 386132720Skan __throw_exception_again; 38797403Sobrien } 38897403Sobrien } 38997403Sobrien 390169691Skan_GLIBCXX_END_NAMESPACE 39197403Sobrien 392132720Skan#endif /* _STL_UNINITIALIZED_H */ 393