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