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