Branch data Line data Source code
1 : : // Raw memory manipulators -*- C++ -*-
2 : :
3 : : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 : : _GLIBCXX_BEGIN_NAMESPACE(std)
66 : :
67 : : template<bool>
68 : : struct __uninitialized_copy
69 : : {
70 : : template<typename _InputIterator, typename _ForwardIterator>
71 : : static _ForwardIterator
72 : : uninitialized_copy(_InputIterator __first, _InputIterator __last,
73 : : _ForwardIterator __result)
74 : : {
75 : 31958 : _ForwardIterator __cur = __result;
76 : : try
77 : : {
78 [ # # ][ # # ]: 137895 : for (; __first != __last; ++__first, ++__cur)
[ # # ][ - + ]
[ # # ][ + + ]
[ + + ][ # # ]
[ # # ][ - + ]
[ + + ]
79 [ + - ][ + - ]: 197051 : ::new(static_cast<void*>(&*__cur)) typename
[ # # ][ # # ]
[ # # ][ + - ]
80 : : iterator_traits<_ForwardIterator>::value_type(*__first);
81 : 31958 : return __cur;
82 : : }
83 : 0 : catch(...)
84 : : {
85 : 0 : std::_Destroy(__result, __cur);
86 : 0 : __throw_exception_again;
87 : : }
88 : : }
89 : : };
90 : :
91 : : template<>
92 : : struct __uninitialized_copy<true>
93 : : {
94 : : template<typename _InputIterator, typename _ForwardIterator>
95 : : static _ForwardIterator
96 : : uninitialized_copy(_InputIterator __first, _InputIterator __last,
97 : : _ForwardIterator __result)
98 : 2984 : { return std::copy(__first, __last, __result); }
99 : : };
100 : :
101 : : /**
102 : : * @brief Copies the range [first,last) into result.
103 : : * @param first An input iterator.
104 : : * @param last An input iterator.
105 : : * @param result An output iterator.
106 : : * @return result + (first - last)
107 : : *
108 : : * Like copy(), but does not require an initialized output range.
109 : : */
110 : : template<typename _InputIterator, typename _ForwardIterator>
111 : : inline _ForwardIterator
112 : : uninitialized_copy(_InputIterator __first, _InputIterator __last,
113 : : _ForwardIterator __result)
114 : : {
115 : : typedef typename iterator_traits<_InputIterator>::value_type
116 : : _ValueType1;
117 : : typedef typename iterator_traits<_ForwardIterator>::value_type
118 : : _ValueType2;
119 : :
120 : : return std::__uninitialized_copy<(__is_pod(_ValueType1)
121 : : && __is_pod(_ValueType2))>::
122 : 39938 : uninitialized_copy(__first, __last, __result);
123 : : }
124 : :
125 : :
126 : : template<bool>
127 : : struct __uninitialized_fill
128 : : {
129 : : template<typename _ForwardIterator, typename _Tp>
130 : : static void
131 : : uninitialized_fill(_ForwardIterator __first,
132 : : _ForwardIterator __last, const _Tp& __x)
133 : : {
134 : : _ForwardIterator __cur = __first;
135 : : try
136 : : {
137 [ + + ][ + + ]: 24 : for (; __cur != __last; ++__cur)
138 : : std::_Construct(&*__cur, __x);
139 : : }
140 : 0 : catch(...)
141 : : {
142 : : std::_Destroy(__first, __cur);
143 : 0 : __throw_exception_again;
144 : : }
145 : : }
146 : : };
147 : :
148 : : template<>
149 : : struct __uninitialized_fill<true>
150 : : {
151 : : template<typename _ForwardIterator, typename _Tp>
152 : : static void
153 : : uninitialized_fill(_ForwardIterator __first,
154 : : _ForwardIterator __last, const _Tp& __x)
155 : : { std::fill(__first, __last, __x); }
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
173 : : _ValueType;
174 : :
175 : : std::__uninitialized_fill<__is_pod(_ValueType)>::
176 : : uninitialized_fill(__first, __last, __x);
177 : : }
178 : :
179 : :
180 : : template<bool>
181 : : struct __uninitialized_fill_n
182 : : {
183 : : template<typename _ForwardIterator, typename _Size, typename _Tp>
184 : : static void
185 : : uninitialized_fill_n(_ForwardIterator __first, _Size __n,
186 : : const _Tp& __x)
187 : : {
188 : : _ForwardIterator __cur = __first;
189 : : try
190 : : {
191 : : for (; __n > 0; --__n, ++__cur)
192 : : std::_Construct(&*__cur, __x);
193 : : }
194 : : catch(...)
195 : : {
196 : : std::_Destroy(__first, __cur);
197 : : __throw_exception_again;
198 : : }
199 : : }
200 : : };
201 : :
202 : : template<>
203 : : struct __uninitialized_fill_n<true>
204 : : {
205 : : template<typename _ForwardIterator, typename _Size, typename _Tp>
206 : : static void
207 : : uninitialized_fill_n(_ForwardIterator __first, _Size __n,
208 : : const _Tp& __x)
209 : : { std::fill_n(__first, __n, __x); }
210 : : };
211 : :
212 : : /**
213 : : * @brief Copies the value x into the range [first,first+n).
214 : : * @param first An input iterator.
215 : : * @param n The number of copies to make.
216 : : * @param x The source value.
217 : : * @return Nothing.
218 : : *
219 : : * Like fill_n(), but does not require an initialized output range.
220 : : */
221 : : template<typename _ForwardIterator, typename _Size, typename _Tp>
222 : : inline void
223 : : uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
224 : : {
225 : : typedef typename iterator_traits<_ForwardIterator>::value_type
226 : : _ValueType;
227 : :
228 : : std::__uninitialized_fill_n<__is_pod(_ValueType)>::
229 : : uninitialized_fill_n(__first, __n, __x);
230 : : }
231 : :
232 : : // Extensions: versions of uninitialized_copy, uninitialized_fill,
233 : : // and uninitialized_fill_n that take an allocator parameter.
234 : : // We dispatch back to the standard versions when we're given the
235 : : // default allocator. For nondefault allocators we do not use
236 : : // any of the POD optimizations.
237 : :
238 : : template<typename _InputIterator, typename _ForwardIterator,
239 : : typename _Allocator>
240 : : _ForwardIterator
241 : : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
242 : : _ForwardIterator __result, _Allocator& __alloc)
243 : : {
244 : : _ForwardIterator __cur = __result;
245 : : try
246 : : {
247 : : for (; __first != __last; ++__first, ++__cur)
248 : : __alloc.construct(&*__cur, *__first);
249 : : return __cur;
250 : : }
251 : : catch(...)
252 : : {
253 : : std::_Destroy(__result, __cur, __alloc);
254 : : __throw_exception_again;
255 : : }
256 : : }
257 : :
258 : : template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
259 : : inline _ForwardIterator
260 : : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
261 : 240 : _ForwardIterator __result, allocator<_Tp>&)
262 : 39468 : { return std::uninitialized_copy(__first, __last, __result); }
263 : :
264 : : template<typename _InputIterator, typename _ForwardIterator,
265 : : typename _Allocator>
266 : : inline _ForwardIterator
267 : : __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
268 : 28928 : _ForwardIterator __result, _Allocator& __alloc)
269 : : {
270 : : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
271 : : _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
272 : 28978 : __result, __alloc);
273 : : }
274 : :
275 : : template<typename _ForwardIterator, typename _Tp, typename _Allocator>
276 : : void
277 : : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
278 : : const _Tp& __x, _Allocator& __alloc)
279 : : {
280 : : _ForwardIterator __cur = __first;
281 : : try
282 : : {
283 : : for (; __cur != __last; ++__cur)
284 : : __alloc.construct(&*__cur, __x);
285 : : }
286 : : catch(...)
287 : : {
288 : : std::_Destroy(__first, __cur, __alloc);
289 : : __throw_exception_again;
290 : : }
291 : : }
292 : :
293 : : template<typename _ForwardIterator, typename _Tp, typename _Tp2>
294 : : inline void
295 : : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
296 : 8 : const _Tp& __x, allocator<_Tp2>&)
297 : 8 : { std::uninitialized_fill(__first, __last, __x); }
298 : :
299 : : template<typename _ForwardIterator, typename _Size, typename _Tp,
300 : : typename _Allocator>
301 : : void
302 : : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
303 : : const _Tp& __x, _Allocator& __alloc)
304 : : {
305 : : _ForwardIterator __cur = __first;
306 : : try
307 : : {
308 : : for (; __n > 0; --__n, ++__cur)
309 : : __alloc.construct(&*__cur, __x);
310 : : }
311 : : catch(...)
312 : : {
313 : : std::_Destroy(__first, __cur, __alloc);
314 : : __throw_exception_again;
315 : : }
316 : : }
317 : :
318 : : template<typename _ForwardIterator, typename _Size, typename _Tp,
319 : : typename _Tp2>
320 : : inline void
321 : : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
322 : : const _Tp& __x, allocator<_Tp2>&)
323 : : { std::uninitialized_fill_n(__first, __n, __x); }
324 : :
325 : :
326 : : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
327 : : // __uninitialized_fill_move, __uninitialized_move_fill.
328 : : // All of these algorithms take a user-supplied allocator, which is used
329 : : // for construction and destruction.
330 : :
331 : : // __uninitialized_copy_move
332 : : // Copies [first1, last1) into [result, result + (last1 - first1)), and
333 : : // move [first2, last2) into
334 : : // [result, result + (last1 - first1) + (last2 - first2)).
335 : : template<typename _InputIterator1, typename _InputIterator2,
336 : : typename _ForwardIterator, typename _Allocator>
337 : : inline _ForwardIterator
338 : : __uninitialized_copy_move(_InputIterator1 __first1,
339 : : _InputIterator1 __last1,
340 : : _InputIterator2 __first2,
341 : : _InputIterator2 __last2,
342 : : _ForwardIterator __result,
343 : : _Allocator& __alloc)
344 : : {
345 : : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
346 : : __result,
347 : : __alloc);
348 : : try
349 : : {
350 : : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
351 : : }
352 : : catch(...)
353 : : {
354 : : std::_Destroy(__result, __mid, __alloc);
355 : : __throw_exception_again;
356 : : }
357 : : }
358 : :
359 : : // __uninitialized_move_copy
360 : : // Moves [first1, last1) into [result, result + (last1 - first1)), and
361 : : // copies [first2, last2) into
362 : : // [result, result + (last1 - first1) + (last2 - first2)).
363 : : template<typename _InputIterator1, typename _InputIterator2,
364 : : typename _ForwardIterator, typename _Allocator>
365 : : inline _ForwardIterator
366 : : __uninitialized_move_copy(_InputIterator1 __first1,
367 : : _InputIterator1 __last1,
368 : : _InputIterator2 __first2,
369 : : _InputIterator2 __last2,
370 : : _ForwardIterator __result,
371 : : _Allocator& __alloc)
372 : : {
373 : : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
374 : : __result,
375 : : __alloc);
376 : : try
377 : : {
378 : : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
379 : : }
380 : : catch(...)
381 : : {
382 : : std::_Destroy(__result, __mid, __alloc);
383 : : __throw_exception_again;
384 : : }
385 : : }
386 : :
387 : : // __uninitialized_fill_move
388 : : // Fills [result, mid) with x, and moves [first, last) into
389 : : // [mid, mid + (last - first)).
390 : : template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
391 : : typename _Allocator>
392 : : inline _ForwardIterator
393 : : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
394 : : const _Tp& __x, _InputIterator __first,
395 : : _InputIterator __last, _Allocator& __alloc)
396 : : {
397 : 0 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
398 : : try
399 : : {
400 : 0 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
401 : : }
402 : 0 : catch(...)
403 : : {
404 : : std::_Destroy(__result, __mid, __alloc);
405 : 0 : __throw_exception_again;
406 : : }
407 : : }
408 : :
409 : : // __uninitialized_move_fill
410 : : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
411 : : // fills [first2 + (last1 - first1), last2) with x.
412 : : template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
413 : : typename _Allocator>
414 : : inline void
415 : : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
416 : : _ForwardIterator __first2,
417 : : _ForwardIterator __last2, const _Tp& __x,
418 : : _Allocator& __alloc)
419 : : {
420 : : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
421 : : __first2,
422 : 0 : __alloc);
423 : : try
424 : : {
425 : 0 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
426 : : }
427 : 0 : catch(...)
428 : : {
429 : : std::_Destroy(__first2, __mid2, __alloc);
430 : 0 : __throw_exception_again;
431 : : }
432 : : }
433 : :
434 : : _GLIBCXX_END_NAMESPACE
435 : :
436 : : #endif /* _STL_UNINITIALIZED_H */
|