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