Line data Source code
1 : // Raw memory manipulators -*- C++ -*-
2 :
3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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 3, 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 : // Under Section 7 of GPL version 3, you are granted additional
18 : // permissions described in the GCC Runtime Library Exception, version
19 : // 3.1, as published by the Free Software Foundation.
20 :
21 : // You should have received a copy of the GNU General Public License and
22 : // a copy of the GCC Runtime Library Exception along with this program;
23 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 : // <http://www.gnu.org/licenses/>.
25 :
26 : /*
27 : *
28 : * Copyright (c) 1994
29 : * Hewlett-Packard Company
30 : *
31 : * Permission to use, copy, modify, distribute and sell this software
32 : * and its documentation for any purpose is hereby granted without fee,
33 : * provided that the above copyright notice appear in all copies and
34 : * that both that copyright notice and this permission notice appear
35 : * in supporting documentation. Hewlett-Packard Company makes no
36 : * representations about the suitability of this software for any
37 : * purpose. It is provided "as is" without express or implied warranty.
38 : *
39 : *
40 : * Copyright (c) 1996,1997
41 : * Silicon Graphics Computer Systems, Inc.
42 : *
43 : * Permission to use, copy, modify, distribute and sell this software
44 : * and its documentation for any purpose is hereby granted without fee,
45 : * provided that the above copyright notice appear in all copies and
46 : * that both that copyright notice and this permission notice appear
47 : * in supporting documentation. Silicon Graphics makes no
48 : * representations about the suitability of this software for any
49 : * purpose. It is provided "as is" without express or implied warranty.
50 : */
51 :
52 : /** @file stl_uninitialized.h
53 : * This is an internal header file, included by other library headers.
54 : * You should not attempt to use it directly.
55 : */
56 :
57 : #ifndef _STL_UNINITIALIZED_H
58 : #define _STL_UNINITIALIZED_H 1
59 :
60 : _GLIBCXX_BEGIN_NAMESPACE(std)
61 :
62 : template<bool>
63 : struct __uninitialized_copy
64 : {
65 : template<typename _InputIterator, typename _ForwardIterator>
66 : static _ForwardIterator
67 100620 : uninitialized_copy(_InputIterator __first, _InputIterator __last,
68 : _ForwardIterator __result)
69 : {
70 100620 : _ForwardIterator __cur = __result;
71 : __try
72 : {
73 930701 : for (; __first != __last; ++__first, ++__cur)
74 830081 : ::new(static_cast<void*>(&*__cur)) typename
75 : iterator_traits<_ForwardIterator>::value_type(*__first);
76 100620 : return __cur;
77 : }
78 0 : __catch(...)
79 : {
80 0 : std::_Destroy(__result, __cur);
81 0 : __throw_exception_again;
82 : }
83 : }
84 : };
85 :
86 : template<>
87 : struct __uninitialized_copy<true>
88 : {
89 : template<typename _InputIterator, typename _ForwardIterator>
90 : static _ForwardIterator
91 3055892 : uninitialized_copy(_InputIterator __first, _InputIterator __last,
92 : _ForwardIterator __result)
93 3055892 : { return std::copy(__first, __last, __result); }
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 3156503 : uninitialized_copy(_InputIterator __first, _InputIterator __last,
108 : _ForwardIterator __result)
109 : {
110 : typedef typename iterator_traits<_InputIterator>::value_type
111 : _ValueType1;
112 : typedef typename iterator_traits<_ForwardIterator>::value_type
113 : _ValueType2;
114 :
115 : return std::__uninitialized_copy<(__is_pod(_ValueType1)
116 : && __is_pod(_ValueType2))>::
117 3156503 : uninitialized_copy(__first, __last, __result);
118 : }
119 :
120 :
121 : template<bool>
122 : struct __uninitialized_fill
123 : {
124 : template<typename _ForwardIterator, typename _Tp>
125 : static void
126 : uninitialized_fill(_ForwardIterator __first,
127 : _ForwardIterator __last, const _Tp& __x)
128 : {
129 : _ForwardIterator __cur = __first;
130 : __try
131 : {
132 : for (; __cur != __last; ++__cur)
133 : std::_Construct(&*__cur, __x);
134 : }
135 : __catch(...)
136 : {
137 : std::_Destroy(__first, __cur);
138 : __throw_exception_again;
139 : }
140 : }
141 : };
142 :
143 : template<>
144 : struct __uninitialized_fill<true>
145 : {
146 : template<typename _ForwardIterator, typename _Tp>
147 : static void
148 : uninitialized_fill(_ForwardIterator __first,
149 : _ForwardIterator __last, const _Tp& __x)
150 : { std::fill(__first, __last, __x); }
151 : };
152 :
153 : /**
154 : * @brief Copies the value x into the range [first,last).
155 : * @param first An input iterator.
156 : * @param last An input iterator.
157 : * @param x The source value.
158 : * @return Nothing.
159 : *
160 : * Like fill(), but does not require an initialized output range.
161 : */
162 : template<typename _ForwardIterator, typename _Tp>
163 : inline void
164 : uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
165 : const _Tp& __x)
166 : {
167 : typedef typename iterator_traits<_ForwardIterator>::value_type
168 : _ValueType;
169 :
170 : std::__uninitialized_fill<__is_pod(_ValueType)>::
171 : uninitialized_fill(__first, __last, __x);
172 : }
173 :
174 :
175 : template<bool>
176 : struct __uninitialized_fill_n
177 : {
178 : template<typename _ForwardIterator, typename _Size, typename _Tp>
179 : static void
180 : uninitialized_fill_n(_ForwardIterator __first, _Size __n,
181 : const _Tp& __x)
182 : {
183 : _ForwardIterator __cur = __first;
184 : __try
185 : {
186 : for (; __n > 0; --__n, ++__cur)
187 : std::_Construct(&*__cur, __x);
188 : }
189 : __catch(...)
190 : {
191 : std::_Destroy(__first, __cur);
192 : __throw_exception_again;
193 : }
194 : }
195 : };
196 :
197 : template<>
198 : struct __uninitialized_fill_n<true>
199 : {
200 : template<typename _ForwardIterator, typename _Size, typename _Tp>
201 : static void
202 : uninitialized_fill_n(_ForwardIterator __first, _Size __n,
203 : const _Tp& __x)
204 : { std::fill_n(__first, __n, __x); }
205 : };
206 :
207 : /**
208 : * @brief Copies the value x into the range [first,first+n).
209 : * @param first An input iterator.
210 : * @param n The number of copies to make.
211 : * @param x The source value.
212 : * @return Nothing.
213 : *
214 : * Like fill_n(), but does not require an initialized output range.
215 : */
216 : template<typename _ForwardIterator, typename _Size, typename _Tp>
217 : inline void
218 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
219 : {
220 : typedef typename iterator_traits<_ForwardIterator>::value_type
221 : _ValueType;
222 :
223 : std::__uninitialized_fill_n<__is_pod(_ValueType)>::
224 : uninitialized_fill_n(__first, __n, __x);
225 : }
226 :
227 : // Extensions: versions of uninitialized_copy, uninitialized_fill,
228 : // and uninitialized_fill_n that take an allocator parameter.
229 : // We dispatch back to the standard versions when we're given the
230 : // default allocator. For nondefault allocators we do not use
231 : // any of the POD optimizations.
232 :
233 : template<typename _InputIterator, typename _ForwardIterator,
234 : typename _Allocator>
235 : _ForwardIterator
236 0 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
237 : _ForwardIterator __result, _Allocator& __alloc)
238 : {
239 0 : _ForwardIterator __cur = __result;
240 : __try
241 : {
242 0 : for (; __first != __last; ++__first, ++__cur)
243 0 : __alloc.construct(&*__cur, *__first);
244 0 : return __cur;
245 : }
246 0 : __catch(...)
247 : {
248 0 : std::_Destroy(__result, __cur, __alloc);
249 0 : __throw_exception_again;
250 : }
251 : }
252 :
253 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
254 : inline _ForwardIterator
255 3156470 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
256 : _ForwardIterator __result, allocator<_Tp>&)
257 3156470 : { return std::uninitialized_copy(__first, __last, __result); }
258 :
259 : template<typename _InputIterator, typename _ForwardIterator,
260 : typename _Allocator>
261 : inline _ForwardIterator
262 3056838 : __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
263 : _ForwardIterator __result, _Allocator& __alloc)
264 : {
265 : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
266 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
267 3056838 : __result, __alloc);
268 : }
269 :
270 : template<typename _ForwardIterator, typename _Tp, typename _Allocator>
271 : void
272 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
273 : const _Tp& __x, _Allocator& __alloc)
274 : {
275 : _ForwardIterator __cur = __first;
276 : __try
277 : {
278 : for (; __cur != __last; ++__cur)
279 : __alloc.construct(&*__cur, __x);
280 : }
281 : __catch(...)
282 : {
283 : std::_Destroy(__first, __cur, __alloc);
284 : __throw_exception_again;
285 : }
286 : }
287 :
288 : template<typename _ForwardIterator, typename _Tp, typename _Tp2>
289 : inline void
290 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
291 : const _Tp& __x, allocator<_Tp2>&)
292 : { std::uninitialized_fill(__first, __last, __x); }
293 :
294 : template<typename _ForwardIterator, typename _Size, typename _Tp,
295 : typename _Allocator>
296 : void
297 0 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
298 : const _Tp& __x, _Allocator& __alloc)
299 : {
300 0 : _ForwardIterator __cur = __first;
301 : __try
302 : {
303 0 : for (; __n > 0; --__n, ++__cur)
304 0 : __alloc.construct(&*__cur, __x);
305 : }
306 0 : __catch(...)
307 : {
308 0 : std::_Destroy(__first, __cur, __alloc);
309 0 : __throw_exception_again;
310 : }
311 0 : }
312 :
313 : template<typename _ForwardIterator, typename _Size, typename _Tp,
314 : typename _Tp2>
315 : inline void
316 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
317 : const _Tp& __x, allocator<_Tp2>&)
318 : { std::uninitialized_fill_n(__first, __n, __x); }
319 :
320 :
321 : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
322 : // __uninitialized_fill_move, __uninitialized_move_fill.
323 : // All of these algorithms take a user-supplied allocator, which is used
324 : // for construction and destruction.
325 :
326 : // __uninitialized_copy_move
327 : // Copies [first1, last1) into [result, result + (last1 - first1)), and
328 : // move [first2, last2) into
329 : // [result, result + (last1 - first1) + (last2 - first2)).
330 : template<typename _InputIterator1, typename _InputIterator2,
331 : typename _ForwardIterator, typename _Allocator>
332 : inline _ForwardIterator
333 : __uninitialized_copy_move(_InputIterator1 __first1,
334 : _InputIterator1 __last1,
335 : _InputIterator2 __first2,
336 : _InputIterator2 __last2,
337 : _ForwardIterator __result,
338 : _Allocator& __alloc)
339 : {
340 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
341 : __result,
342 : __alloc);
343 : __try
344 : {
345 : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
346 : }
347 : __catch(...)
348 : {
349 : std::_Destroy(__result, __mid, __alloc);
350 : __throw_exception_again;
351 : }
352 : }
353 :
354 : // __uninitialized_move_copy
355 : // Moves [first1, last1) into [result, result + (last1 - first1)), and
356 : // copies [first2, last2) into
357 : // [result, result + (last1 - first1) + (last2 - first2)).
358 : template<typename _InputIterator1, typename _InputIterator2,
359 : typename _ForwardIterator, typename _Allocator>
360 : inline _ForwardIterator
361 : __uninitialized_move_copy(_InputIterator1 __first1,
362 : _InputIterator1 __last1,
363 : _InputIterator2 __first2,
364 : _InputIterator2 __last2,
365 : _ForwardIterator __result,
366 : _Allocator& __alloc)
367 : {
368 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
369 : __result,
370 : __alloc);
371 : __try
372 : {
373 : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
374 : }
375 : __catch(...)
376 : {
377 : std::_Destroy(__result, __mid, __alloc);
378 : __throw_exception_again;
379 : }
380 : }
381 :
382 : // __uninitialized_fill_move
383 : // Fills [result, mid) with x, and moves [first, last) into
384 : // [mid, mid + (last - first)).
385 : template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
386 : typename _Allocator>
387 : inline _ForwardIterator
388 : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
389 : const _Tp& __x, _InputIterator __first,
390 : _InputIterator __last, _Allocator& __alloc)
391 : {
392 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
393 : __try
394 : {
395 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
396 : }
397 : __catch(...)
398 : {
399 : std::_Destroy(__result, __mid, __alloc);
400 : __throw_exception_again;
401 : }
402 : }
403 :
404 : // __uninitialized_move_fill
405 : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
406 : // fills [first2 + (last1 - first1), last2) with x.
407 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
408 : typename _Allocator>
409 : inline void
410 : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
411 : _ForwardIterator __first2,
412 : _ForwardIterator __last2, const _Tp& __x,
413 : _Allocator& __alloc)
414 : {
415 : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
416 : __first2,
417 : __alloc);
418 : __try
419 : {
420 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
421 : }
422 : __catch(...)
423 : {
424 : std::_Destroy(__first2, __mid2, __alloc);
425 : __throw_exception_again;
426 : }
427 : }
428 :
429 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
430 : template<typename _InputIterator, typename _Size,
431 : typename _ForwardIterator>
432 : _ForwardIterator
433 : __uninitialized_copy_n(_InputIterator __first, _Size __n,
434 : _ForwardIterator __result, input_iterator_tag)
435 : {
436 : _ForwardIterator __cur = __result;
437 : __try
438 : {
439 : for (; __n > 0; --__n, ++__first, ++__cur)
440 : ::new(static_cast<void*>(&*__cur)) typename
441 : iterator_traits<_ForwardIterator>::value_type(*__first);
442 : return __cur;
443 : }
444 : __catch(...)
445 : {
446 : std::_Destroy(__result, __cur);
447 : __throw_exception_again;
448 : }
449 : }
450 :
451 : template<typename _RandomAccessIterator, typename _Size,
452 : typename _ForwardIterator>
453 : inline _ForwardIterator
454 : __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
455 : _ForwardIterator __result,
456 : random_access_iterator_tag)
457 : { return std::uninitialized_copy(__first, __first + __n, __result); }
458 :
459 : /**
460 : * @brief Copies the range [first,first+n) into result.
461 : * @param first An input iterator.
462 : * @param n The number of elements to copy.
463 : * @param result An output iterator.
464 : * @return result + n
465 : *
466 : * Like copy_n(), but does not require an initialized output range.
467 : */
468 : template<typename _InputIterator, typename _Size, typename _ForwardIterator>
469 : inline _ForwardIterator
470 : uninitialized_copy_n(_InputIterator __first, _Size __n,
471 : _ForwardIterator __result)
472 : { return std::__uninitialized_copy_n(__first, __n, __result,
473 : std::__iterator_category(__first)); }
474 : #endif
475 :
476 : _GLIBCXX_END_NAMESPACE
477 :
478 : #endif /* _STL_UNINITIALIZED_H */
|