DR 1339
[official-gcc.git] / libstdc++-v3 / include / bits / stl_uninitialized.h
blobc864fa14bd3c2ae4bbec0ce2b595153d2eb4131f
1 // Raw memory manipulators -*- C++ -*-
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.
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.
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.
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/>.
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
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.
39 * Copyright (c) 1996,1997
40 * Silicon Graphics Computer Systems, Inc.
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.
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}
56 #ifndef _STL_UNINITIALIZED_H
57 #define _STL_UNINITIALIZED_H 1
59 namespace std _GLIBCXX_VISIBILITY(default)
61 _GLIBCXX_BEGIN_NAMESPACE_VERSION
63 template<bool _TrivialValueTypes>
64 struct __uninitialized_copy
66 template<typename _InputIterator, typename _ForwardIterator>
67 static _ForwardIterator
68 __uninit_copy(_InputIterator __first, _InputIterator __last,
69 _ForwardIterator __result)
71 _ForwardIterator __cur = __result;
72 __try
74 for (; __first != __last; ++__first, ++__cur)
75 std::_Construct(std::__addressof(*__cur), *__first);
76 return __cur;
78 __catch(...)
80 std::_Destroy(__result, __cur);
81 __throw_exception_again;
86 template<>
87 struct __uninitialized_copy<true>
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); }
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)
103 * Like copy(), but does not require an initialized output range.
105 template<typename _InputIterator, typename _ForwardIterator>
106 inline _ForwardIterator
107 uninitialized_copy(_InputIterator __first, _InputIterator __last,
108 _ForwardIterator __result)
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
122 return std::__uninitialized_copy<__is_trivial(_ValueType1)
123 && __is_trivial(_ValueType2)
124 && __assignable>::
125 __uninit_copy(__first, __last, __result);
129 template<bool _TrivialValueType>
130 struct __uninitialized_fill
132 template<typename _ForwardIterator, typename _Tp>
133 static void
134 __uninit_fill(_ForwardIterator __first, _ForwardIterator __last,
135 const _Tp& __x)
137 _ForwardIterator __cur = __first;
138 __try
140 for (; __cur != __last; ++__cur)
141 std::_Construct(std::__addressof(*__cur), __x);
143 __catch(...)
145 std::_Destroy(__first, __cur);
146 __throw_exception_again;
151 template<>
152 struct __uninitialized_fill<true>
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); }
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.
168 * Like fill(), but does not require an initialized output range.
170 template<typename _ForwardIterator, typename _Tp>
171 inline void
172 uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
173 const _Tp& __x)
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
184 std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>::
185 __uninit_fill(__first, __last, __x);
189 template<bool _TrivialValueType>
190 struct __uninitialized_fill_n
192 template<typename _ForwardIterator, typename _Size, typename _Tp>
193 static _ForwardIterator
194 __uninit_fill_n(_ForwardIterator __first, _Size __n,
195 const _Tp& __x)
197 _ForwardIterator __cur = __first;
198 __try
200 for (; __n > 0; --__n, ++__cur)
201 std::_Construct(std::__addressof(*__cur), __x);
202 return __cur;
204 __catch(...)
206 std::_Destroy(__first, __cur);
207 __throw_exception_again;
212 template<>
213 struct __uninitialized_fill_n<true>
215 template<typename _ForwardIterator, typename _Size, typename _Tp>
216 static _ForwardIterator
217 __uninit_fill_n(_ForwardIterator __first, _Size __n,
218 const _Tp& __x)
219 { return std::fill_n(__first, __n, __x); }
222 // _GLIBCXX_RESOLVE_LIB_DEFECTS
223 // DR 1339. uninitialized_fill_n should return the end of its range
225 * @brief Copies the value x into the range [first,first+n).
226 * @param __first An input iterator.
227 * @param __n The number of copies to make.
228 * @param __x The source value.
229 * @return Nothing.
231 * Like fill_n(), but does not require an initialized output range.
233 template<typename _ForwardIterator, typename _Size, typename _Tp>
234 inline _ForwardIterator
235 uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
237 typedef typename iterator_traits<_ForwardIterator>::value_type
238 _ValueType;
239 #if __cplusplus < 201103L
240 const bool __assignable = true;
241 #else
242 // trivial types can have deleted assignment
243 const bool __assignable = is_copy_assignable<_ValueType>::value;
244 #endif
245 return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>::
246 __uninit_fill_n(__first, __n, __x);
249 // Extensions: versions of uninitialized_copy, uninitialized_fill,
250 // and uninitialized_fill_n that take an allocator parameter.
251 // We dispatch back to the standard versions when we're given the
252 // default allocator. For nondefault allocators we do not use
253 // any of the POD optimizations.
255 template<typename _InputIterator, typename _ForwardIterator,
256 typename _Allocator>
257 _ForwardIterator
258 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
259 _ForwardIterator __result, _Allocator& __alloc)
261 _ForwardIterator __cur = __result;
262 __try
264 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
265 for (; __first != __last; ++__first, ++__cur)
266 __traits::construct(__alloc, std::__addressof(*__cur), *__first);
267 return __cur;
269 __catch(...)
271 std::_Destroy(__result, __cur, __alloc);
272 __throw_exception_again;
276 template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
277 inline _ForwardIterator
278 __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
279 _ForwardIterator __result, allocator<_Tp>&)
280 { return std::uninitialized_copy(__first, __last, __result); }
282 template<typename _InputIterator, typename _ForwardIterator,
283 typename _Allocator>
284 inline _ForwardIterator
285 __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
286 _ForwardIterator __result, _Allocator& __alloc)
288 return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
289 _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
290 __result, __alloc);
293 template<typename _InputIterator, typename _ForwardIterator,
294 typename _Allocator>
295 inline _ForwardIterator
296 __uninitialized_move_if_noexcept_a(_InputIterator __first,
297 _InputIterator __last,
298 _ForwardIterator __result,
299 _Allocator& __alloc)
301 return std::__uninitialized_copy_a
302 (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
303 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
306 template<typename _ForwardIterator, typename _Tp, typename _Allocator>
307 void
308 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
309 const _Tp& __x, _Allocator& __alloc)
311 _ForwardIterator __cur = __first;
312 __try
314 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
315 for (; __cur != __last; ++__cur)
316 __traits::construct(__alloc, std::__addressof(*__cur), __x);
318 __catch(...)
320 std::_Destroy(__first, __cur, __alloc);
321 __throw_exception_again;
325 template<typename _ForwardIterator, typename _Tp, typename _Tp2>
326 inline void
327 __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
328 const _Tp& __x, allocator<_Tp2>&)
329 { std::uninitialized_fill(__first, __last, __x); }
331 template<typename _ForwardIterator, typename _Size, typename _Tp,
332 typename _Allocator>
333 _ForwardIterator
334 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
335 const _Tp& __x, _Allocator& __alloc)
337 _ForwardIterator __cur = __first;
338 __try
340 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
341 for (; __n > 0; --__n, ++__cur)
342 __traits::construct(__alloc, std::__addressof(*__cur), __x);
343 return __cur;
345 __catch(...)
347 std::_Destroy(__first, __cur, __alloc);
348 __throw_exception_again;
352 template<typename _ForwardIterator, typename _Size, typename _Tp,
353 typename _Tp2>
354 inline _ForwardIterator
355 __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
356 const _Tp& __x, allocator<_Tp2>&)
357 { return std::uninitialized_fill_n(__first, __n, __x); }
360 // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
361 // __uninitialized_fill_move, __uninitialized_move_fill.
362 // All of these algorithms take a user-supplied allocator, which is used
363 // for construction and destruction.
365 // __uninitialized_copy_move
366 // Copies [first1, last1) into [result, result + (last1 - first1)), and
367 // move [first2, last2) into
368 // [result, result + (last1 - first1) + (last2 - first2)).
369 template<typename _InputIterator1, typename _InputIterator2,
370 typename _ForwardIterator, typename _Allocator>
371 inline _ForwardIterator
372 __uninitialized_copy_move(_InputIterator1 __first1,
373 _InputIterator1 __last1,
374 _InputIterator2 __first2,
375 _InputIterator2 __last2,
376 _ForwardIterator __result,
377 _Allocator& __alloc)
379 _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
380 __result,
381 __alloc);
382 __try
384 return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
386 __catch(...)
388 std::_Destroy(__result, __mid, __alloc);
389 __throw_exception_again;
393 // __uninitialized_move_copy
394 // Moves [first1, last1) into [result, result + (last1 - first1)), and
395 // copies [first2, last2) into
396 // [result, result + (last1 - first1) + (last2 - first2)).
397 template<typename _InputIterator1, typename _InputIterator2,
398 typename _ForwardIterator, typename _Allocator>
399 inline _ForwardIterator
400 __uninitialized_move_copy(_InputIterator1 __first1,
401 _InputIterator1 __last1,
402 _InputIterator2 __first2,
403 _InputIterator2 __last2,
404 _ForwardIterator __result,
405 _Allocator& __alloc)
407 _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
408 __result,
409 __alloc);
410 __try
412 return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
414 __catch(...)
416 std::_Destroy(__result, __mid, __alloc);
417 __throw_exception_again;
421 // __uninitialized_fill_move
422 // Fills [result, mid) with x, and moves [first, last) into
423 // [mid, mid + (last - first)).
424 template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
425 typename _Allocator>
426 inline _ForwardIterator
427 __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
428 const _Tp& __x, _InputIterator __first,
429 _InputIterator __last, _Allocator& __alloc)
431 std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
432 __try
434 return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
436 __catch(...)
438 std::_Destroy(__result, __mid, __alloc);
439 __throw_exception_again;
443 // __uninitialized_move_fill
444 // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
445 // fills [first2 + (last1 - first1), last2) with x.
446 template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
447 typename _Allocator>
448 inline void
449 __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
450 _ForwardIterator __first2,
451 _ForwardIterator __last2, const _Tp& __x,
452 _Allocator& __alloc)
454 _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
455 __first2,
456 __alloc);
457 __try
459 std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
461 __catch(...)
463 std::_Destroy(__first2, __mid2, __alloc);
464 __throw_exception_again;
468 #if __cplusplus >= 201103L
469 // Extensions: __uninitialized_default, __uninitialized_default_n,
470 // __uninitialized_default_a, __uninitialized_default_n_a.
472 template<bool _TrivialValueType>
473 struct __uninitialized_default_1
475 template<typename _ForwardIterator>
476 static void
477 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
479 _ForwardIterator __cur = __first;
480 __try
482 for (; __cur != __last; ++__cur)
483 std::_Construct(std::__addressof(*__cur));
485 __catch(...)
487 std::_Destroy(__first, __cur);
488 __throw_exception_again;
493 template<>
494 struct __uninitialized_default_1<true>
496 template<typename _ForwardIterator>
497 static void
498 __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
500 typedef typename iterator_traits<_ForwardIterator>::value_type
501 _ValueType;
503 std::fill(__first, __last, _ValueType());
507 template<bool _TrivialValueType>
508 struct __uninitialized_default_n_1
510 template<typename _ForwardIterator, typename _Size>
511 static _ForwardIterator
512 __uninit_default_n(_ForwardIterator __first, _Size __n)
514 _ForwardIterator __cur = __first;
515 __try
517 for (; __n > 0; --__n, ++__cur)
518 std::_Construct(std::__addressof(*__cur));
519 return __cur;
521 __catch(...)
523 std::_Destroy(__first, __cur);
524 __throw_exception_again;
529 template<>
530 struct __uninitialized_default_n_1<true>
532 template<typename _ForwardIterator, typename _Size>
533 static _ForwardIterator
534 __uninit_default_n(_ForwardIterator __first, _Size __n)
536 typedef typename iterator_traits<_ForwardIterator>::value_type
537 _ValueType;
539 return std::fill_n(__first, __n, _ValueType());
543 // __uninitialized_default
544 // Fills [first, last) with std::distance(first, last) default
545 // constructed value_types(s).
546 template<typename _ForwardIterator>
547 inline void
548 __uninitialized_default(_ForwardIterator __first,
549 _ForwardIterator __last)
551 typedef typename iterator_traits<_ForwardIterator>::value_type
552 _ValueType;
553 // trivial types can have deleted assignment
554 const bool __assignable = is_copy_assignable<_ValueType>::value;
556 std::__uninitialized_default_1<__is_trivial(_ValueType)
557 && __assignable>::
558 __uninit_default(__first, __last);
561 // __uninitialized_default_n
562 // Fills [first, first + n) with n default constructed value_type(s).
563 template<typename _ForwardIterator, typename _Size>
564 inline _ForwardIterator
565 __uninitialized_default_n(_ForwardIterator __first, _Size __n)
567 typedef typename iterator_traits<_ForwardIterator>::value_type
568 _ValueType;
569 // trivial types can have deleted assignment
570 const bool __assignable = is_copy_assignable<_ValueType>::value;
572 return __uninitialized_default_n_1<__is_trivial(_ValueType)
573 && __assignable>::
574 __uninit_default_n(__first, __n);
578 // __uninitialized_default_a
579 // Fills [first, last) with std::distance(first, last) default
580 // constructed value_types(s), constructed with the allocator alloc.
581 template<typename _ForwardIterator, typename _Allocator>
582 void
583 __uninitialized_default_a(_ForwardIterator __first,
584 _ForwardIterator __last,
585 _Allocator& __alloc)
587 _ForwardIterator __cur = __first;
588 __try
590 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
591 for (; __cur != __last; ++__cur)
592 __traits::construct(__alloc, std::__addressof(*__cur));
594 __catch(...)
596 std::_Destroy(__first, __cur, __alloc);
597 __throw_exception_again;
601 template<typename _ForwardIterator, typename _Tp>
602 inline void
603 __uninitialized_default_a(_ForwardIterator __first,
604 _ForwardIterator __last,
605 allocator<_Tp>&)
606 { std::__uninitialized_default(__first, __last); }
609 // __uninitialized_default_n_a
610 // Fills [first, first + n) with n default constructed value_types(s),
611 // constructed with the allocator alloc.
612 template<typename _ForwardIterator, typename _Size, typename _Allocator>
613 _ForwardIterator
614 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
615 _Allocator& __alloc)
617 _ForwardIterator __cur = __first;
618 __try
620 typedef __gnu_cxx::__alloc_traits<_Allocator> __traits;
621 for (; __n > 0; --__n, ++__cur)
622 __traits::construct(__alloc, std::__addressof(*__cur));
623 return __cur;
625 __catch(...)
627 std::_Destroy(__first, __cur, __alloc);
628 __throw_exception_again;
632 template<typename _ForwardIterator, typename _Size, typename _Tp>
633 inline _ForwardIterator
634 __uninitialized_default_n_a(_ForwardIterator __first, _Size __n,
635 allocator<_Tp>&)
636 { return std::__uninitialized_default_n(__first, __n); }
639 template<typename _InputIterator, typename _Size,
640 typename _ForwardIterator>
641 _ForwardIterator
642 __uninitialized_copy_n(_InputIterator __first, _Size __n,
643 _ForwardIterator __result, input_iterator_tag)
645 _ForwardIterator __cur = __result;
646 __try
648 for (; __n > 0; --__n, ++__first, ++__cur)
649 std::_Construct(std::__addressof(*__cur), *__first);
650 return __cur;
652 __catch(...)
654 std::_Destroy(__result, __cur);
655 __throw_exception_again;
659 template<typename _RandomAccessIterator, typename _Size,
660 typename _ForwardIterator>
661 inline _ForwardIterator
662 __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
663 _ForwardIterator __result,
664 random_access_iterator_tag)
665 { return std::uninitialized_copy(__first, __first + __n, __result); }
668 * @brief Copies the range [first,first+n) into result.
669 * @param __first An input iterator.
670 * @param __n The number of elements to copy.
671 * @param __result An output iterator.
672 * @return __result + __n
674 * Like copy_n(), but does not require an initialized output range.
676 template<typename _InputIterator, typename _Size, typename _ForwardIterator>
677 inline _ForwardIterator
678 uninitialized_copy_n(_InputIterator __first, _Size __n,
679 _ForwardIterator __result)
680 { return std::__uninitialized_copy_n(__first, __n, __result,
681 std::__iterator_category(__first)); }
682 #endif
684 _GLIBCXX_END_NAMESPACE_VERSION
685 } // namespace
687 #endif /* _STL_UNINITIALIZED_H */