stl_uninitialized.h revision 132720
195643Smarkm// Raw memory manipulators -*- C++ -*- 295643Smarkm 395643Smarkm// Copyright (C) 2001, 2004 Free Software Foundation, Inc. 495643Smarkm// 595643Smarkm// This file is part of the GNU ISO C++ Library. This library is free 695643Smarkm// software; you can redistribute it and/or modify it under the 795643Smarkm// terms of the GNU General Public License as published by the 895643Smarkm// Free Software Foundation; either version 2, or (at your option) 995643Smarkm// any later version. 1095643Smarkm 1195643Smarkm// This library is distributed in the hope that it will be useful, 1295643Smarkm// but WITHOUT ANY WARRANTY; without even the implied warranty of 1395643Smarkm// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1495643Smarkm// GNU General Public License for more details. 1595643Smarkm 1695643Smarkm// You should have received a copy of the GNU General Public License along 1795643Smarkm// with this library; see the file COPYING. If not, write to the Free 1895643Smarkm// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1995643Smarkm// USA. 2095643Smarkm 2195643Smarkm// As a special exception, you may use this file as part of a free software 2295643Smarkm// library without restriction. Specifically, if other files instantiate 2395643Smarkm// templates or use macros or inline functions from this file, or you compile 2495643Smarkm// this file and link it with other files to produce an executable, this 2595643Smarkm// file does not by itself cause the resulting executable to be covered by 2695643Smarkm// the GNU General Public License. This exception does not however 2795643Smarkm// invalidate any other reasons why the executable file might be covered by 2895643Smarkm// the GNU General Public License. 2995643Smarkm 3095643Smarkm/* 3195643Smarkm * 3295643Smarkm * Copyright (c) 1994 3395643Smarkm * Hewlett-Packard Company 3495643Smarkm * 3595643Smarkm * Permission to use, copy, modify, distribute and sell this software 3695643Smarkm * 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 __type_traits<_ValueType>::is_POD_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 __type_traits<_ValueType>::is_POD_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 _ForwardIterator 181 __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n, 182 const _Tp& __x, __true_type) 183 { return std::fill_n(__first, __n, __x); } 184 185 template<typename _ForwardIterator, typename _Size, typename _Tp> 186 _ForwardIterator 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 return __cur; 196 } 197 catch(...) 198 { 199 std::_Destroy(__first, __cur); 200 __throw_exception_again; 201 } 202 } 203 204 /** 205 * @brief Copies the value x into the range [first,first+n). 206 * @param first An input iterator. 207 * @param n The number of copies to make. 208 * @param x The source value. 209 * @return first+n 210 * 211 * Like fill_n(), but does not require an initialized output range. 212 */ 213 template<typename _ForwardIterator, typename _Size, typename _Tp> 214 inline _ForwardIterator 215 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 216 { 217 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 218 typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; 219 return std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); 220 } 221 222 // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill, 223 // __uninitialized_fill_copy. 224 225 // __uninitialized_copy_copy 226 // Copies [first1, last1) into [result, result + (last1 - first1)), and 227 // copies [first2, last2) into 228 // [result, result + (last1 - first1) + (last2 - first2)). 229 230 template<typename _InputIterator1, typename _InputIterator2, 231 typename _ForwardIterator> 232 inline _ForwardIterator 233 __uninitialized_copy_copy(_InputIterator1 __first1, 234 _InputIterator1 __last1, 235 _InputIterator2 __first2, 236 _InputIterator2 __last2, 237 _ForwardIterator __result) 238 { 239 _ForwardIterator __mid = std::uninitialized_copy(__first1, __last1, 240 __result); 241 try 242 { 243 return std::uninitialized_copy(__first2, __last2, __mid); 244 } 245 catch(...) 246 { 247 std::_Destroy(__result, __mid); 248 __throw_exception_again; 249 } 250 } 251 252 // __uninitialized_fill_copy 253 // Fills [result, mid) with x, and copies [first, last) into 254 // [mid, mid + (last - first)). 255 template<typename _ForwardIterator, typename _Tp, typename _InputIterator> 256 inline _ForwardIterator 257 __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid, 258 const _Tp& __x, _InputIterator __first, 259 _InputIterator __last) 260 { 261 std::uninitialized_fill(__result, __mid, __x); 262 try 263 { 264 return std::uninitialized_copy(__first, __last, __mid); 265 } 266 catch(...) 267 { 268 std::_Destroy(__result, __mid); 269 __throw_exception_again; 270 } 271 } 272 273 // __uninitialized_copy_fill 274 // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and 275 // fills [first2 + (last1 - first1), last2) with x. 276 template<typename _InputIterator, typename _ForwardIterator, typename _Tp> 277 inline void 278 __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1, 279 _ForwardIterator __first2, 280 _ForwardIterator __last2, const _Tp& __x) 281 { 282 _ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1, 283 __first2); 284 try 285 { 286 std::uninitialized_fill(__mid2, __last2, __x); 287 } 288 catch(...) 289 { 290 std::_Destroy(__first2, __mid2); 291 __throw_exception_again; 292 } 293 } 294 295} // namespace std 296 297#endif /* _STL_UNINITIALIZED_H */ 298