1 : // Raw memory manipulators -*- C++ -*-
2 :
3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4 : // 2009, 2010, 2011
5 : // Free Software Foundation, Inc.
6 : //
7 : // This file is part of the GNU ISO C++ Library. This library is free
8 : // software; you can redistribute it and/or modify it under the
9 : // terms of the GNU General Public License as published by the
10 : // Free Software Foundation; either version 3, or (at your option)
11 : // any later version.
12 :
13 : // This library is distributed in the hope that it will be useful,
14 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : // GNU General Public License for more details.
17 :
18 : // Under Section 7 of GPL version 3, you are granted additional
19 : // permissions described in the GCC Runtime Library Exception, version
20 : // 3.1, as published by the Free Software Foundation.
21 :
22 : // You should have received a copy of the GNU General Public License and
23 : // a copy of the GCC Runtime Library Exception along with this program;
24 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 : // <http://www.gnu.org/licenses/>.
26 :
27 : /*
28 : *
29 : * Copyright (c) 1994
30 : * Hewlett-Packard Company
31 : *
32 : * Permission to use, copy, modify, distribute and sell this software
33 : * and its documentation for any purpose is hereby granted without fee,
34 : * provided that the above copyright notice appear in all copies and
35 : * that both that copyright notice and this permission notice appear
36 : * in supporting documentation. Hewlett-Packard Company makes no
37 : * representations about the suitability of this software for any
38 : * purpose. It is provided "as is" without express or implied warranty.
39 : *
40 : *
41 : * Copyright (c) 1996,1997
42 : * Silicon Graphics Computer Systems, Inc.
43 : *
44 : * Permission to use, copy, modify, distribute and sell this software
45 : * and its documentation for any purpose is hereby granted without fee,
46 : * provided that the above copyright notice appear in all copies and
47 : * that both that copyright notice and this permission notice appear
48 : * in supporting documentation. Silicon Graphics makes no
49 : * representations about the suitability of this software for any
50 : * purpose. It is provided "as is" without express or implied warranty.
51 : */
52 :
53 : /** @file bits/stl_uninitialized.h
54 : * This is an internal header file, included by other library headers.
55 : * Do not attempt to use it directly. @headername{memory}
56 : */
57 :
58 : #ifndef _STL_UNINITIALIZED_H
59 : #define _STL_UNINITIALIZED_H 1
60 :
61 : namespace std _GLIBCXX_VISIBILITY(default)
62 : {
63 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
64 :
65 : template<bool _TrivialValueTypes>
66 : struct __uninitialized_copy
67 : {
68 : template<typename _InputIterator, typename _ForwardIterator>
69 : static _ForwardIterator
70 1287789 : __uninit_copy(_InputIterator __first, _InputIterator __last,
71 : _ForwardIterator __result)
72 : {
73 1287789 : _ForwardIterator __cur = __result;
74 : __try
75 : {
76 1358203 : for (; __first != __last; ++__first, ++__cur)
77 70414 : std::_Construct(std::__addressof(*__cur), *__first);
78 1287789 : return __cur;
79 : }
80 0 : __catch(...)
81 : {
82 0 : std::_Destroy(__result, __cur);
83 0 : __throw_exception_again;
84 : }
85 : }
86 : };
87 :
88 : template<>
89 : struct __uninitialized_copy<true>
90 : {
91 : template<typename _InputIterator, typename _ForwardIterator>
92 : static _ForwardIterator
93 16092 : __uninit_copy(_InputIterator __first, _InputIterator __last,
94 : _ForwardIterator __result)
95 16092 : { return std::copy(__first, __last, __result); }
96 : };
97 :
98 : /**
99 : * @brief Copies the range [first,last) into result.
100 : * @param first An input iterator.
101 : * @param last An input iterator.
102 : * @param result An output iterator.
103 : * @return result + (first - last)
104 : *
105 : * Like copy(), but does not require an initialized output range.
106 : */
107 : template<typename _InputIterator, typename _ForwardIterator>
108 : inline _ForwardIterator
109 1303881 : uninitialized_copy(_InputIterator __first, _InputIterator __last,
110 : _ForwardIterator __result)
111 : {
112 : typedef typename iterator_traits<_InputIterator>::value_type
113 : _ValueType1;
114 : typedef typename iterator_traits<_ForwardIterator>::value_type
115 : _ValueType2;
116 :
117 : return std::__uninitialized_copy<(__is_trivial(_ValueType1)
118 : && __is_trivial(_ValueType2))>::
119 1303881 : __uninit_copy(__first, __last, __result);
120 : }
121 :
122 :
123 : template<bool _TrivialValueType>
124 : struct __uninitialized_fill
125 : {
126 : template<typename _ForwardIterator, typename _Tp>
127 : static void
128 : __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
129 : const _Tp& __x)
130 : {
131 : _ForwardIterator __cur = __first;
132 : __try
133 : {
134 : for (; __cur != __last; ++__cur)
135 : std::_Construct(std::__addressof(*__cur), __x);
136 : }
137 : __catch(...)
138 : {
139 : std::_Destroy(__first, __cur);
140 : __throw_exception_again;
141 : }
142 : }
143 : };
144 :
145 : template<>
146 : struct __uninitialized_fill<true>
147 : {
148 : template<typename _ForwardIterator, typename _Tp>
149 : static void
150 : __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
151 : const _Tp& __x)
152 : { std::fill(__first, __last, __x); }
153 : };
154 :
155 : /**
156 : * @brief Copies the value x into the range [first,last).
157 : * @param first An input iterator.
158 : * @param last An input iterator.
159 : * @param x The source value.
160 : * @return Nothing.
161 : *
162 : * Like fill(), but does not require an initialized output range.
163 : */
164 : template<typename _ForwardIterator, typename _Tp>
165 : inline void
166 : uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
167 : const _Tp& __x)
168 : {
169 : typedef typename iterator_traits<_ForwardIterator>::value_type
170 : _ValueType;
171 :
172 : std::__uninitialized_fill<__is_trivial(_ValueType)>::
173 : __uninit_fill(__first, __last, __x);
174 : }
175 :
176 :
177 : template<bool _TrivialValueType>
178 : struct __uninitialized_fill_n
179 : {
180 : template<typename _ForwardIterator, typename _Size, typename _Tp>
181 : static void
182 443 : __uninit_fill_n(_ForwardIterator __first, _Size __n,
183 : const _Tp& __x)
184 : {
185 443 : _ForwardIterator __cur = __first;
186 : __try
187 : {
188 886 : for (; __n > 0; --__n, ++__cur)
189 443 : std::_Construct(std::__addressof(*__cur), __x);
190 : }
191 0 : __catch(...)
192 : {
193 0 : std::_Destroy(__first, __cur);
194 0 : __throw_exception_again;
195 : }
196 443 : }
197 : };
198 :
199 : template<>
200 : struct __uninitialized_fill_n<true>
201 : {
202 : template<typename _ForwardIterator, typename _Size, typename _Tp>
203 : static void
204 11856 : __uninit_fill_n(_ForwardIterator __first, _Size __n,
205 : const _Tp& __x)
206 11856 : { std::fill_n(__first, __n, __x); }
207 : };
208 :
209 : /**
210 : * @brief Copies the value x into the range [first,first+n).
211 : * @param first An input iterator.
212 : * @param n The number of copies to make.
213 : * @param x The source value.
214 : * @return Nothing.
215 : *
216 : * Like fill_n(), but does not require an initialized output range.
217 : */
218 : template<typename _ForwardIterator, typename _Size, typename _Tp>
219 : inline void
220 12299 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
221 : {
222 : typedef typename iterator_traits<_ForwardIterator>::value_type
223 : _ValueType;
224 :
225 12299 : std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
226 : __uninit_fill_n(__first, __n, __x);
227 12299 : }
228 :
229 : // Extensions: versions of uninitialized_copy, uninitialized_fill,
230 : // and uninitialized_fill_n that take an allocator parameter.
231 : // We dispatch back to the standard versions when we're given the
232 : // default allocator. For nondefault allocators we do not use
233 : // any of the POD optimizations.
234 :
235 : template<typename _InputIterator, typename _ForwardIterator,
236 : typename _Allocator>
237 : _ForwardIterator
238 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
239 : _ForwardIterator __result, _Allocator& __alloc)
240 : {
241 : _ForwardIterator __cur = __result;
242 : __try
243 : {
244 : for (; __first != __last; ++__first, ++__cur)
245 : __alloc.construct(std::__addressof(*__cur), *__first);
246 : return __cur;
247 : }
248 : __catch(...)
249 : {
250 : std::_Destroy(__result, __cur, __alloc);
251 : __throw_exception_again;
252 : }
253 : }
254 :
255 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
256 : inline _ForwardIterator
257 1303881 : __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
258 : _ForwardIterator __result, allocator<_Tp>&)
259 1303881 : { return std::uninitialized_copy(__first, __last, __result); }
260 :
261 : template<typename _InputIterator, typename _ForwardIterator,
262 : typename _Allocator>
263 : inline _ForwardIterator
264 1301972 : __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
265 : _ForwardIterator __result, _Allocator& __alloc)
266 : {
267 : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
268 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
269 1301972 : __result, __alloc);
270 : }
271 :
272 : template<typename _ForwardIterator, typename _Tp, typename _Allocator>
273 : void
274 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
275 : const _Tp& __x, _Allocator& __alloc)
276 : {
277 : _ForwardIterator __cur = __first;
278 : __try
279 : {
280 : for (; __cur != __last; ++__cur)
281 : __alloc.construct(std::__addressof(*__cur), __x);
282 : }
283 : __catch(...)
284 : {
285 : std::_Destroy(__first, __cur, __alloc);
286 : __throw_exception_again;
287 : }
288 : }
289 :
290 : template<typename _ForwardIterator, typename _Tp, typename _Tp2>
291 : inline void
292 : __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
293 : const _Tp& __x, allocator<_Tp2>&)
294 : { std::uninitialized_fill(__first, __last, __x); }
295 :
296 : template<typename _ForwardIterator, typename _Size, typename _Tp,
297 : typename _Allocator>
298 : void
299 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
300 : const _Tp& __x, _Allocator& __alloc)
301 : {
302 : _ForwardIterator __cur = __first;
303 : __try
304 : {
305 : for (; __n > 0; --__n, ++__cur)
306 : __alloc.construct(std::__addressof(*__cur), __x);
307 : }
308 : __catch(...)
309 : {
310 : std::_Destroy(__first, __cur, __alloc);
311 : __throw_exception_again;
312 : }
313 : }
314 :
315 : template<typename _ForwardIterator, typename _Size, typename _Tp,
316 : typename _Tp2>
317 : inline void
318 12299 : __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
319 : const _Tp& __x, allocator<_Tp2>&)
320 12299 : { std::uninitialized_fill_n(__first, __n, __x); }
321 :
322 :
323 : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
324 : // __uninitialized_fill_move, __uninitialized_move_fill.
325 : // All of these algorithms take a user-supplied allocator, which is used
326 : // for construction and destruction.
327 :
328 : // __uninitialized_copy_move
329 : // Copies [first1, last1) into [result, result + (last1 - first1)), and
330 : // move [first2, last2) into
331 : // [result, result + (last1 - first1) + (last2 - first2)).
332 : template<typename _InputIterator1, typename _InputIterator2,
333 : typename _ForwardIterator, typename _Allocator>
334 : inline _ForwardIterator
335 : __uninitialized_copy_move(_InputIterator1 __first1,
336 : _InputIterator1 __last1,
337 : _InputIterator2 __first2,
338 : _InputIterator2 __last2,
339 : _ForwardIterator __result,
340 : _Allocator& __alloc)
341 : {
342 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
343 : __result,
344 : __alloc);
345 : __try
346 : {
347 : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
348 : }
349 : __catch(...)
350 : {
351 : std::_Destroy(__result, __mid, __alloc);
352 : __throw_exception_again;
353 : }
354 : }
355 :
356 : // __uninitialized_move_copy
357 : // Moves [first1, last1) into [result, result + (last1 - first1)), and
358 : // copies [first2, last2) into
359 : // [result, result + (last1 - first1) + (last2 - first2)).
360 : template<typename _InputIterator1, typename _InputIterator2,
361 : typename _ForwardIterator, typename _Allocator>
362 : inline _ForwardIterator
363 : __uninitialized_move_copy(_InputIterator1 __first1,
364 : _InputIterator1 __last1,
365 : _InputIterator2 __first2,
366 : _InputIterator2 __last2,
367 : _ForwardIterator __result,
368 : _Allocator& __alloc)
369 : {
370 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
371 : __result,
372 : __alloc);
373 : __try
374 : {
375 : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
376 : }
377 : __catch(...)
378 : {
379 : std::_Destroy(__result, __mid, __alloc);
380 : __throw_exception_again;
381 : }
382 : }
383 :
384 : // __uninitialized_fill_move
385 : // Fills [result, mid) with x, and moves [first, last) into
386 : // [mid, mid + (last - first)).
387 : template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
388 : typename _Allocator>
389 : inline _ForwardIterator
390 : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
391 : const _Tp& __x, _InputIterator __first,
392 : _InputIterator __last, _Allocator& __alloc)
393 : {
394 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
395 : __try
396 : {
397 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
398 : }
399 : __catch(...)
400 : {
401 : std::_Destroy(__result, __mid, __alloc);
402 : __throw_exception_again;
403 : }
404 : }
405 :
406 : // __uninitialized_move_fill
407 : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
408 : // fills [first2 + (last1 - first1), last2) with x.
409 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
410 : typename _Allocator>
411 : inline void
412 : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
413 : _ForwardIterator __first2,
414 : _ForwardIterator __last2, const _Tp& __x,
415 : _Allocator& __alloc)
416 : {
417 : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
418 : __first2,
419 : __alloc);
420 : __try
421 : {
422 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
423 : }
424 : __catch(...)
425 : {
426 : std::_Destroy(__first2, __mid2, __alloc);
427 : __throw_exception_again;
428 : }
429 : }
430 :
431 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
432 : // Extensions: __uninitialized_default, __uninitialized_default_n,
433 : // __uninitialized_default_a, __uninitialized_default_n_a.
434 :
435 : template<bool _TrivialValueType>
436 : struct __uninitialized_default_1
437 : {
438 : template<typename _ForwardIterator>
439 : static void
440 : __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
441 : {
442 : _ForwardIterator __cur = __first;
443 : __try
444 : {
445 : for (; __cur != __last; ++__cur)
446 : std::_Construct(std::__addressof(*__cur));
447 : }
448 : __catch(...)
449 : {
450 : std::_Destroy(__first, __cur);
451 : __throw_exception_again;
452 : }
453 : }
454 : };
455 :
456 : template<>
457 : struct __uninitialized_default_1<true>
458 : {
459 : template<typename _ForwardIterator>
460 : static void
461 : __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
462 : {
463 : typedef typename iterator_traits<_ForwardIterator>::value_type
464 : _ValueType;
465 :
466 : std::fill(__first, __last, _ValueType());
467 : }
468 : };
469 :
470 : template<bool _TrivialValueType>
471 : struct __uninitialized_default_n_1
472 : {
473 : template<typename _ForwardIterator, typename _Size>
474 : static void
475 : __uninit_default_n(_ForwardIterator __first, _Size __n)
476 : {
477 : _ForwardIterator __cur = __first;
478 : __try
479 : {
480 : for (; __n > 0; --__n, ++__cur)
481 : std::_Construct(std::__addressof(*__cur));
482 : }
483 : __catch(...)
484 : {
485 : std::_Destroy(__first, __cur);
486 : __throw_exception_again;
487 : }
488 : }
489 : };
490 :
491 : template<>
492 : struct __uninitialized_default_n_1<true>
493 : {
494 : template<typename _ForwardIterator, typename _Size>
495 : static void
496 : __uninit_default_n(_ForwardIterator __first, _Size __n)
497 : {
498 : typedef typename iterator_traits<_ForwardIterator>::value_type
499 : _ValueType;
500 :
501 : std::fill_n(__first, __n, _ValueType());
502 : }
503 : };
504 :
505 : // __uninitialized_default
506 : // Fills [first, last) with std::distance(first, last) default
507 : // constructed value_types(s).
508 : template<typename _ForwardIterator>
509 : inline void
510 : __uninitialized_default(_ForwardIterator __first,
511 : _ForwardIterator __last)
512 : {
513 : typedef typename iterator_traits<_ForwardIterator>::value_type
514 : _ValueType;
515 :
516 : std::__uninitialized_default_1<__is_trivial(_ValueType)>::
517 : __uninit_default(__first, __last);
518 : }
519 :
520 : // __uninitialized_default_n
521 : // Fills [first, first + n) with n default constructed value_type(s).
522 : template<typename _ForwardIterator, typename _Size>
523 : inline void
524 : __uninitialized_default_n(_ForwardIterator __first, _Size __n)
525 : {
526 : typedef typename iterator_traits<_ForwardIterator>::value_type
527 : _ValueType;
528 :
529 : std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
530 : __uninit_default_n(__first, __n);
531 : }
532 :
533 : template<typename _Tp, typename _Allocator>
534 : inline auto
535 : _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, void*)
536 : -> decltype(__alloc.construct(__ptr))
537 : { return __alloc.construct(__ptr); }
538 :
539 : template<typename _Tp, typename _Allocator>
540 : inline void
541 : _Construct_default_a_impl(_Tp* __ptr, _Allocator& __alloc, ...)
542 : { _Construct(__ptr); }
543 :
544 : template<typename _Tp, typename _Allocator>
545 : inline void
546 : _Construct_default_a(_Tp* __ptr, _Allocator& __alloc)
547 : { _Construct_default_a_impl(__ptr, __alloc, nullptr); }
548 :
549 : // __uninitialized_default_a
550 : // Fills [first, last) with std::distance(first, last) default
551 : // constructed value_types(s), constructed with the allocator alloc.
552 : template<typename _ForwardIterator, typename _Allocator>
553 : void
554 : __uninitialized_default_a(_ForwardIterator __first,
555 : _ForwardIterator __last,
556 : _Allocator& __alloc)
557 : {
558 : _ForwardIterator __cur = __first;
559 : __try
560 : {
561 : for (; __cur != __last; ++__cur)
562 : _Construct_default_a(std::__addressof(*__cur), __alloc);
563 : }
564 : __catch(...)
565 : {
566 : std::_Destroy(__first, __cur, __alloc);
567 : __throw_exception_again;
568 : }
569 : }
570 :
571 : template<typename _ForwardIterator, typename _Tp>
572 : inline void
573 : __uninitialized_default_a(_ForwardIterator __first,
574 : _ForwardIterator __last,
575 : allocator<_Tp>&)
576 : { std::__uninitialized_default(__first, __last); }
577 :
578 :
579 : // __uninitialized_default_n_a
580 : // Fills [first, first + n) with n default constructed value_types(s),
581 : // constructed with the allocator alloc.
582 : template<typename _ForwardIterator, typename _Size, typename _Allocator>
583 : void
584 : __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
585 : _Allocator& __alloc)
586 : {
587 : _ForwardIterator __cur = __first;
588 : __try
589 : {
590 : for (; __n > 0; --__n, ++__cur)
591 : _Construct_default_a(std::__addressof(*__cur), __alloc);
592 : }
593 : __catch(...)
594 : {
595 : std::_Destroy(__first, __cur, __alloc);
596 : __throw_exception_again;
597 : }
598 : }
599 :
600 : template<typename _ForwardIterator, typename _Size, typename _Tp>
601 : inline void
602 : __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
603 : allocator<_Tp>&)
604 : { std::__uninitialized_default_n(__first, __n); }
605 :
606 :
607 : template<typename _InputIterator, typename _Size,
608 : typename _ForwardIterator>
609 : _ForwardIterator
610 : __uninitialized_copy_n(_InputIterator __first, _Size __n,
611 : _ForwardIterator __result, input_iterator_tag)
612 : {
613 : _ForwardIterator __cur = __result;
614 : __try
615 : {
616 : for (; __n > 0; --__n, ++__first, ++__cur)
617 : std::_Construct(std::__addressof(*__cur), *__first);
618 : return __cur;
619 : }
620 : __catch(...)
621 : {
622 : std::_Destroy(__result, __cur);
623 : __throw_exception_again;
624 : }
625 : }
626 :
627 : template<typename _RandomAccessIterator, typename _Size,
628 : typename _ForwardIterator>
629 : inline _ForwardIterator
630 : __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
631 : _ForwardIterator __result,
632 : random_access_iterator_tag)
633 : { return std::uninitialized_copy(__first, __first + __n, __result); }
634 :
635 : /**
636 : * @brief Copies the range [first,first+n) into result.
637 : * @param first An input iterator.
638 : * @param n The number of elements to copy.
639 : * @param result An output iterator.
640 : * @return result + n
641 : *
642 : * Like copy_n(), but does not require an initialized output range.
643 : */
644 : template<typename _InputIterator, typename _Size, typename _ForwardIterator>
645 : inline _ForwardIterator
646 : uninitialized_copy_n(_InputIterator __first, _Size __n,
647 : _ForwardIterator __result)
648 : { return std::__uninitialized_copy_n(__first, __n, __result,
649 : std::__iterator_category(__first)); }
650 : #endif
651 :
652 : _GLIBCXX_END_NAMESPACE_VERSION
653 : } // namespace
654 :
655 : #endif /* _STL_UNINITIALIZED_H */
|