1// Raw memory manipulators -*- C++ -*-
2
3// Copyright (C) 2001-2016 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, (void)++__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 _RefType1;
119 typedef typename iterator_traits<_ForwardIterator>::reference _RefType2;
120 const bool __assignable = is_assignable<_RefType2, _RefType1>::value;
121#endif
122
123 return std::__uninitialized_copy<__is_trivial(_ValueType1)
124 && __is_trivial(_ValueType2)
125 && __assignable>::
126 __uninit_copy(__first, __last, __result);
127 }
128
129
130 template<bool _TrivialValueType>
131 struct __uninitialized_fill
132 {
133 template<typename _ForwardIterator, typename _Tp>
134 static void
135 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
136 const _Tp& __x)
137 {
138 _ForwardIterator __cur = __first;
139 __try
140 {
141 for (; __cur != __last; ++__cur)
142 std::_Construct(std::__addressof(*__cur), __x);
143 }
144 __catch(...)
145 {
146 std::_Destroy(__first, __cur);
147 __throw_exception_again;
148 }
149 }
150 };
151
152 template<>
153 struct __uninitialized_fill<true>
154 {
155 template<typename _ForwardIterator, typename _Tp>
156 static void
157 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
158 const _Tp& __x)
159 { std::fill(__first, __last, __x); }
160 };
161
162 /**
163 * @brief Copies the value x into the range [first,last).
164 * @param __first An input iterator.
165 * @param __last An input iterator.
166 * @param __x The source value.
167 * @return Nothing.
168 *
169 * Like fill(), but does not require an initialized output range.
170 */
171 template<typename _ForwardIterator, typename _Tp>
172 inline void
173 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
174 const _Tp& __x)
175 {
176 typedef typename iterator_traits<_ForwardIterator>::value_type
177 _ValueType;
178#if __cplusplus < 201103L
179 const bool __assignable = true;
180#else
181 // trivial types can have deleted assignment
182 const bool __assignable = is_copy_assignable<_ValueType>::value;
183#endif
184
185 std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
186 __uninit_fill(__first, __last, __x);
187 }
188
189
190 template<bool _TrivialValueType>
191 struct __uninitialized_fill_n
192 {
193 template<typename _ForwardIterator, typename _Size, typename _Tp>
194 static _ForwardIterator
195 __uninit_fill_n(_ForwardIterator __first, _Size __n,
196 const _Tp& __x)
197 {
198 _ForwardIterator __cur = __first;
199 __try
200 {
201 for (; __n > 0; --__n, ++__cur)
202 std::_Construct(std::__addressof(*__cur), __x);
203 return __cur;
204 }
205 __catch(...)
206 {
207 std::_Destroy(__first, __cur);
208 __throw_exception_again;
209 }
210 }
211 };
212
213 template<>
214 struct __uninitialized_fill_n<true>
215 {
216 template<typename _ForwardIterator, typename _Size, typename _Tp>
217 static _ForwardIterator
218 __uninit_fill_n(_ForwardIterator __first, _Size __n,
219 const _Tp& __x)
220 { return std::fill_n(__first, __n, __x); }
221 };
222
223 // _GLIBCXX_RESOLVE_LIB_DEFECTS
224 // DR 1339. uninitialized_fill_n should return the end of its range
225 /**
226 * @brief Copies the value x into the range [first,first+n).
227 * @param __first An input iterator.
228 * @param __n The number of copies to make.
229 * @param __x The source value.
230 * @return Nothing.
231 *
232 * Like fill_n(), but does not require an initialized output range.
233 */
234 template<typename _ForwardIterator, typename _Size, typename _Tp>
235 inline _ForwardIterator
236 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
237 {
238 typedef typename iterator_traits<_ForwardIterator>::value_type
239 _ValueType;
240#if __cplusplus < 201103L
241 const bool __assignable = true;
242#else
243 // trivial types can have deleted assignment
244 const bool __assignable = is_copy_assignable<_ValueType>::value;
245#endif
246 return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
247 __uninit_fill_n(__first, __n, __x);
248 }
249
250 // Extensions: versions of uninitialized_copy, uninitialized_fill,
251 // and uninitialized_fill_n that take an allocator parameter.
252 // We dispatch back to the standard versions when we're given the
253 // default allocator. For nondefault allocators we do not use
254 // any of the POD optimizations.
255
256 template<typename _InputIterator, typename _ForwardIterator,
257 typename _Allocator>
258 _ForwardIterator
259 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
260 _ForwardIterator __result, _Allocator& __alloc)
261 {
262 _ForwardIterator __cur = __result;
263 __try
264 {
265 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
266 for (; __first != __last; ++__first, (void)++__cur)
267 __traits::construct(__alloc, std::__addressof(*__cur), *__first);
268 return __cur;
269 }
270 __catch(...)
271 {
272 std::_Destroy(__result, __cur, __alloc);
273 __throw_exception_again;
274 }
275 }
276
277 template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
278 inline _ForwardIterator
279 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
280 _ForwardIterator __result, allocator<_Tp>&)
281 { return std::uninitialized_copy(__first, __last, __result); }
282
283 template<typename _InputIterator, typename _ForwardIterator,
284 typename _Allocator>
285 inline _ForwardIterator
286 __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
287 _ForwardIterator __result, _Allocator& __alloc)
288 {
289 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
290 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
291 __result, __alloc);
292 }
293
294 template<typename _InputIterator, typename _ForwardIterator,
295 typename _Allocator>
296 inline _ForwardIterator
297 __uninitialized_move_if_noexcept_a(_InputIterator __first,
298 _InputIterator __last,
299 _ForwardIterator __result,
300 _Allocator& __alloc)
301 {
302 return std::__uninitialized_copy_a
303 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
304 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
305 }
306
307 template<typename _ForwardIterator, typename _Tp, typename _Allocator>
308 void
309 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
310 const _Tp& __x, _Allocator& __alloc)
311 {
312 _ForwardIterator __cur = __first;
313 __try
314 {
315 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
316 for (; __cur != __last; ++__cur)
317 __traits::construct(__alloc, std::__addressof(*__cur), __x);
318 }
319 __catch(...)
320 {
321 std::_Destroy(__first, __cur, __alloc);
322 __throw_exception_again;
323 }
324 }
325
326 template<typename _ForwardIterator, typename _Tp, typename _Tp2>
327 inline void
328 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
329 const _Tp& __x, allocator<_Tp2>&)
330 { std::uninitialized_fill(__first, __last, __x); }
331
332 template<typename _ForwardIterator, typename _Size, typename _Tp,
333 typename _Allocator>
334 _ForwardIterator
335 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
336 const _Tp& __x, _Allocator& __alloc)
337 {
338 _ForwardIterator __cur = __first;
339 __try
340 {
341 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
342 for (; __n > 0; --__n, ++__cur)
343 __traits::construct(__alloc, std::__addressof(*__cur), __x);
344 return __cur;
345 }
346 __catch(...)
347 {
348 std::_Destroy(__first, __cur, __alloc);
349 __throw_exception_again;
350 }
351 }
352
353 template<typename _ForwardIterator, typename _Size, typename _Tp,
354 typename _Tp2>
355 inline _ForwardIterator
356 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
357 const _Tp& __x, allocator<_Tp2>&)
358 { return std::uninitialized_fill_n(__first, __n, __x); }
359
360
361 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
362 // __uninitialized_fill_move, __uninitialized_move_fill.
363 // All of these algorithms take a user-supplied allocator, which is used
364 // for construction and destruction.
365
366 // __uninitialized_copy_move
367 // Copies [first1, last1) into [result, result + (last1 - first1)), and
368 // move [first2, last2) into
369 // [result, result + (last1 - first1) + (last2 - first2)).
370 template<typename _InputIterator1, typename _InputIterator2,
371 typename _ForwardIterator, typename _Allocator>
372 inline _ForwardIterator
373 __uninitialized_copy_move(_InputIterator1 __first1,
374 _InputIterator1 __last1,
375 _InputIterator2 __first2,
376 _InputIterator2 __last2,
377 _ForwardIterator __result,
378 _Allocator& __alloc)
379 {
380 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
381 __result,
382 __alloc);
383 __try
384 {
385 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
386 }
387 __catch(...)
388 {
389 std::_Destroy(__result, __mid, __alloc);
390 __throw_exception_again;
391 }
392 }
393
394 // __uninitialized_move_copy
395 // Moves [first1, last1) into [result, result + (last1 - first1)), and
396 // copies [first2, last2) into
397 // [result, result + (last1 - first1) + (last2 - first2)).
398 template<typename _InputIterator1, typename _InputIterator2,
399 typename _ForwardIterator, typename _Allocator>
400 inline _ForwardIterator
401 __uninitialized_move_copy(_InputIterator1 __first1,
402 _InputIterator1 __last1,
403 _InputIterator2 __first2,
404 _InputIterator2 __last2,
405 _ForwardIterator __result,
406 _Allocator& __alloc)
407 {
408 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
409 __result,
410 __alloc);
411 __try
412 {
413 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
414 }
415 __catch(...)
416 {
417 std::_Destroy(__result, __mid, __alloc);
418 __throw_exception_again;
419 }
420 }
421
422 // __uninitialized_fill_move
423 // Fills [result, mid) with x, and moves [first, last) into
424 // [mid, mid + (last - first)).
425 template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
426 typename _Allocator>
427 inline _ForwardIterator
428 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
429 const _Tp& __x, _InputIterator __first,
430 _InputIterator __last, _Allocator& __alloc)
431 {
432 std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
433 __try
434 {
435 return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
436 }
437 __catch(...)
438 {
439 std::_Destroy(__result, __mid, __alloc);
440 __throw_exception_again;
441 }
442 }
443
444 // __uninitialized_move_fill
445 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
446 // fills [first2 + (last1 - first1), last2) with x.
447 template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
448 typename _Allocator>
449 inline void
450 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
451 _ForwardIterator __first2,
452 _ForwardIterator __last2, const _Tp& __x,
453 _Allocator& __alloc)
454 {
455 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
456 __first2,
457 __alloc);
458 __try
459 {
460 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
461 }
462 __catch(...)
463 {
464 std::_Destroy(__first2, __mid2, __alloc);
465 __throw_exception_again;
466 }
467 }
468
469#if __cplusplus >= 201103L
470 // Extensions: __uninitialized_default, __uninitialized_default_n,
471 // __uninitialized_default_a, __uninitialized_default_n_a.
472
473 template<bool _TrivialValueType>
474 struct __uninitialized_default_1
475 {
476 template<typename _ForwardIterator>
477 static void
478 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
479 {
480 _ForwardIterator __cur = __first;
481 __try
482 {
483 for (; __cur != __last; ++__cur)
484 std::_Construct(std::__addressof(*__cur));
485 }
486 __catch(...)
487 {
488 std::_Destroy(__first, __cur);
489 __throw_exception_again;
490 }
491 }
492 };
493
494 template<>
495 struct __uninitialized_default_1<true>
496 {
497 template<typename _ForwardIterator>
498 static void
499 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
500 {
501 typedef typename iterator_traits<_ForwardIterator>::value_type
502 _ValueType;
503
504 std::fill(__first, __last, _ValueType());
505 }
506 };
507
508 template<bool _TrivialValueType>
509 struct __uninitialized_default_n_1
510 {
511 template<typename _ForwardIterator, typename _Size>
512 static _ForwardIterator
513 __uninit_default_n(_ForwardIterator __first, _Size __n)
514 {
515 _ForwardIterator __cur = __first;
516 __try
517 {
518 for (; __n > 0; --__n, ++__cur)
519 std::_Construct(std::__addressof(*__cur));
520 return __cur;
521 }
522 __catch(...)
523 {
524 std::_Destroy(__first, __cur);
525 __throw_exception_again;
526 }
527 }
528 };
529
530 template<>
531 struct __uninitialized_default_n_1<true>
532 {
533 template<typename _ForwardIterator, typename _Size>
534 static _ForwardIterator
535 __uninit_default_n(_ForwardIterator __first, _Size __n)
536 {
537 typedef typename iterator_traits<_ForwardIterator>::value_type
538 _ValueType;
539
540 return std::fill_n(__first, __n, _ValueType());
541 }
542 };
543
544 // __uninitialized_default
545 // Fills [first, last) with std::distance(first, last) default
546 // constructed value_types(s).
547 template<typename _ForwardIterator>
548 inline void
549 __uninitialized_default(_ForwardIterator __first,
550 _ForwardIterator __last)
551 {
552 typedef typename iterator_traits<_ForwardIterator>::value_type
553 _ValueType;
554 // trivial types can have deleted assignment
555 const bool __assignable = is_copy_assignable<_ValueType>::value;
556
557 std::__uninitialized_default_1<__is_trivial(_ValueType)
558 && __assignable>::
559 __uninit_default(__first, __last);
560 }
561
562 // __uninitialized_default_n
563 // Fills [first, first + n) with n default constructed value_type(s).
564 template<typename _ForwardIterator, typename _Size>
565 inline _ForwardIterator
566 __uninitialized_default_n(_ForwardIterator __first, _Size __n)
567 {
568 typedef typename iterator_traits<_ForwardIterator>::value_type
569 _ValueType;
570 // trivial types can have deleted assignment
571 const bool __assignable = is_copy_assignable<_ValueType>::value;
572
573 return __uninitialized_default_n_1<__is_trivial(_ValueType)
574 && __assignable>::
575 __uninit_default_n(__first, __n);
576 }
577
578
579 // __uninitialized_default_a
580 // Fills [first, last) with std::distance(first, last) default
581 // constructed value_types(s), constructed with the allocator alloc.
582 template<typename _ForwardIterator, typename _Allocator>
583 void
584 __uninitialized_default_a(_ForwardIterator __first,
585 _ForwardIterator __last,
586 _Allocator& __alloc)
587 {
588 _ForwardIterator __cur = __first;
589 __try
590 {
591 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
592 for (; __cur != __last; ++__cur)
593 __traits::construct(__alloc, std::__addressof(*__cur));
594 }
595 __catch(...)
596 {
597 std::_Destroy(__first, __cur, __alloc);
598 __throw_exception_again;
599 }
600 }
601
602 template<typename _ForwardIterator, typename _Tp>
603 inline void
604 __uninitialized_default_a(_ForwardIterator __first,
605 _ForwardIterator __last,
606 allocator<_Tp>&)
607 { std::__uninitialized_default(__first, __last); }
608
609
610 // __uninitialized_default_n_a
611 // Fills [first, first + n) with n default constructed value_types(s),
612 // constructed with the allocator alloc.
613 template<typename _ForwardIterator, typename _Size, typename _Allocator>
614 _ForwardIterator
615 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
616 _Allocator& __alloc)
617 {
618 _ForwardIterator __cur = __first;
619 __try
620 {
621 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
622 for (; __n > 0; --__n, ++__cur)
623 __traits::construct(__alloc, std::__addressof(*__cur));
624 return __cur;
625 }
626 __catch(...)
627 {
628 std::_Destroy(__first, __cur, __alloc);
629 __throw_exception_again;
630 }
631 }
632
633 template<typename _ForwardIterator, typename _Size, typename _Tp>
634 inline _ForwardIterator
635 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
636 allocator<_Tp>&)
637 { return std::__uninitialized_default_n(__first, __n); }
638
639
640 template<typename _InputIterator, typename _Size,
641 typename _ForwardIterator>
642 _ForwardIterator
643 __uninitialized_copy_n(_InputIterator __first, _Size __n,
644 _ForwardIterator __result, input_iterator_tag)
645 {
646 _ForwardIterator __cur = __result;
647 __try
648 {
649 for (; __n > 0; --__n, ++__first, ++__cur)
650 std::_Construct(std::__addressof(*__cur), *__first);
651 return __cur;
652 }
653 __catch(...)
654 {
655 std::_Destroy(__result, __cur);
656 __throw_exception_again;
657 }
658 }
659
660 template<typename _RandomAccessIterator, typename _Size,
661 typename _ForwardIterator>
662 inline _ForwardIterator
663 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
664 _ForwardIterator __result,
665 random_access_iterator_tag)
666 { return std::uninitialized_copy(__first, __first + __n, __result); }
667
668 /**
669 * @brief Copies the range [first,first+n) into result.
670 * @param __first An input iterator.
671 * @param __n The number of elements to copy.
672 * @param __result An output iterator.
673 * @return __result + __n
674 *
675 * Like copy_n(), but does not require an initialized output range.
676 */
677 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
678 inline _ForwardIterator
679 uninitialized_copy_n(_InputIterator __first, _Size __n,
680 _ForwardIterator __result)
681 { return std::__uninitialized_copy_n(__first, __n, __result,
682 std::__iterator_category(__first)); }
683#endif
684
685_GLIBCXX_END_NAMESPACE_VERSION
686} // namespace
687
688#endif /* _STL_UNINITIALIZED_H */
689