246d5c36d80284498baf754c3719b3572f332e64
[platform/upstream/gcc.git] / libstdc++-v3 / include / bits / stl_uninitialized.h
1 // Raw memory manipulators -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
4 // 2009, 2010
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         __uninit_copy(_InputIterator __first, _InputIterator __last,
71                       _ForwardIterator __result)
72         {
73           _ForwardIterator __cur = __result;
74           __try
75             {
76               for (; __first != __last; ++__first, ++__cur)
77                 std::_Construct(std::__addressof(*__cur), *__first);
78               return __cur;
79             }
80           __catch(...)
81             {
82               std::_Destroy(__result, __cur);
83               __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         __uninit_copy(_InputIterator __first, _InputIterator __last,
94                       _ForwardIterator __result)
95         { 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     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         __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         __uninit_fill_n(_ForwardIterator __first, _Size __n,
183                         const _Tp& __x)
184         {
185           _ForwardIterator __cur = __first;
186           __try
187             {
188               for (; __n > 0; --__n, ++__cur)
189                 std::_Construct(std::__addressof(*__cur), __x);
190             }
191           __catch(...)
192             {
193               std::_Destroy(__first, __cur);
194               __throw_exception_again;
195             }
196         }
197     };
198
199   template<>
200     struct __uninitialized_fill_n<true>
201     {
202       template<typename _ForwardIterator, typename _Size, typename _Tp>
203         static void
204         __uninit_fill_n(_ForwardIterator __first, _Size __n,
205                         const _Tp& __x)
206         { 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     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
221     {
222       typedef typename iterator_traits<_ForwardIterator>::value_type
223         _ValueType;
224
225       std::__uninitialized_fill_n<__is_trivial(_ValueType)>::
226         __uninit_fill_n(__first, __n, __x);
227     }
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     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
258                            _ForwardIterator __result, allocator<_Tp>&)
259     { return std::uninitialized_copy(__first, __last, __result); }
260
261   template<typename _InputIterator, typename _ForwardIterator,
262            typename _Allocator>
263     inline _ForwardIterator
264     __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                                          __result, __alloc);
270     }
271
272   template<typename _InputIterator, typename _ForwardIterator,
273            typename _Allocator>
274     inline _ForwardIterator
275     __uninitialized_move_if_noexcept_a(_InputIterator __first,
276                                        _InputIterator __last,
277                                        _ForwardIterator __result,
278                                        _Allocator& __alloc)
279     {
280       return std::__uninitialized_copy_a
281         (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first),
282          _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc);
283     }
284
285   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
286     void
287     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
288                            const _Tp& __x, _Allocator& __alloc)
289     {
290       _ForwardIterator __cur = __first;
291       __try
292         {
293           for (; __cur != __last; ++__cur)
294             __alloc.construct(std::__addressof(*__cur), __x);
295         }
296       __catch(...)
297         {
298           std::_Destroy(__first, __cur, __alloc);
299           __throw_exception_again;
300         }
301     }
302
303   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
304     inline void
305     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
306                            const _Tp& __x, allocator<_Tp2>&)
307     { std::uninitialized_fill(__first, __last, __x); }
308
309   template<typename _ForwardIterator, typename _Size, typename _Tp,
310            typename _Allocator>
311     void
312     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
313                              const _Tp& __x, _Allocator& __alloc)
314     {
315       _ForwardIterator __cur = __first;
316       __try
317         {
318           for (; __n > 0; --__n, ++__cur)
319             __alloc.construct(std::__addressof(*__cur), __x);
320         }
321       __catch(...)
322         {
323           std::_Destroy(__first, __cur, __alloc);
324           __throw_exception_again;
325         }
326     }
327
328   template<typename _ForwardIterator, typename _Size, typename _Tp,
329            typename _Tp2>
330     inline void
331     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
332                              const _Tp& __x, allocator<_Tp2>&)
333     { std::uninitialized_fill_n(__first, __n, __x); }
334
335
336   // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
337   // __uninitialized_fill_move, __uninitialized_move_fill.
338   // All of these algorithms take a user-supplied allocator, which is used
339   // for construction and destruction.
340
341   // __uninitialized_copy_move
342   // Copies [first1, last1) into [result, result + (last1 - first1)), and
343   //  move [first2, last2) into
344   //  [result, result + (last1 - first1) + (last2 - first2)).
345   template<typename _InputIterator1, typename _InputIterator2,
346            typename _ForwardIterator, typename _Allocator>
347     inline _ForwardIterator
348     __uninitialized_copy_move(_InputIterator1 __first1,
349                               _InputIterator1 __last1,
350                               _InputIterator2 __first2,
351                               _InputIterator2 __last2,
352                               _ForwardIterator __result,
353                               _Allocator& __alloc)
354     {
355       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
356                                                            __result,
357                                                            __alloc);
358       __try
359         {
360           return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
361         }
362       __catch(...)
363         {
364           std::_Destroy(__result, __mid, __alloc);
365           __throw_exception_again;
366         }
367     }
368
369   // __uninitialized_move_copy
370   // Moves [first1, last1) into [result, result + (last1 - first1)), and
371   //  copies [first2, last2) into
372   //  [result, result + (last1 - first1) + (last2 - first2)).
373   template<typename _InputIterator1, typename _InputIterator2,
374            typename _ForwardIterator, typename _Allocator>
375     inline _ForwardIterator
376     __uninitialized_move_copy(_InputIterator1 __first1,
377                               _InputIterator1 __last1,
378                               _InputIterator2 __first2,
379                               _InputIterator2 __last2,
380                               _ForwardIterator __result,
381                               _Allocator& __alloc)
382     {
383       _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
384                                                            __result,
385                                                            __alloc);
386       __try
387         {
388           return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
389         }
390       __catch(...)
391         {
392           std::_Destroy(__result, __mid, __alloc);
393           __throw_exception_again;
394         }
395     }
396   
397   // __uninitialized_fill_move
398   // Fills [result, mid) with x, and moves [first, last) into
399   //  [mid, mid + (last - first)).
400   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
401            typename _Allocator>
402     inline _ForwardIterator
403     __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
404                               const _Tp& __x, _InputIterator __first,
405                               _InputIterator __last, _Allocator& __alloc)
406     {
407       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
408       __try
409         {
410           return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
411         }
412       __catch(...)
413         {
414           std::_Destroy(__result, __mid, __alloc);
415           __throw_exception_again;
416         }
417     }
418
419   // __uninitialized_move_fill
420   // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
421   //  fills [first2 + (last1 - first1), last2) with x.
422   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
423            typename _Allocator>
424     inline void
425     __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
426                               _ForwardIterator __first2,
427                               _ForwardIterator __last2, const _Tp& __x,
428                               _Allocator& __alloc)
429     {
430       _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
431                                                             __first2,
432                                                             __alloc);
433       __try
434         {
435           std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
436         }
437       __catch(...)
438         {
439           std::_Destroy(__first2, __mid2, __alloc);
440           __throw_exception_again;
441         }
442     }
443
444 #ifdef __GXX_EXPERIMENTAL_CXX0X__
445   // Extensions: __uninitialized_default, __uninitialized_default_n,
446   // __uninitialized_default_a, __uninitialized_default_n_a.
447
448   template<bool _TrivialValueType>
449     struct __uninitialized_default_1
450     {
451       template<typename _ForwardIterator>
452         static void
453         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
454         {
455           _ForwardIterator __cur = __first;
456           __try
457             {
458               for (; __cur != __last; ++__cur)
459                 std::_Construct(std::__addressof(*__cur));
460             }
461           __catch(...)
462             {
463               std::_Destroy(__first, __cur);
464               __throw_exception_again;
465             }
466         }
467     };
468
469   template<>
470     struct __uninitialized_default_1<true>
471     {
472       template<typename _ForwardIterator>
473         static void
474         __uninit_default(_ForwardIterator __first, _ForwardIterator __last)
475         {
476           typedef typename iterator_traits<_ForwardIterator>::value_type
477             _ValueType;
478
479           std::fill(__first, __last, _ValueType());
480         }
481     };
482
483   template<bool _TrivialValueType>
484     struct __uninitialized_default_n_1
485     {
486       template<typename _ForwardIterator, typename _Size>
487         static void
488         __uninit_default_n(_ForwardIterator __first, _Size __n)
489         {
490           _ForwardIterator __cur = __first;
491           __try
492             {
493               for (; __n > 0; --__n, ++__cur)
494                 std::_Construct(std::__addressof(*__cur));
495             }
496           __catch(...)
497             {
498               std::_Destroy(__first, __cur);
499               __throw_exception_again;
500             }
501         }
502     };
503
504   template<>
505     struct __uninitialized_default_n_1<true>
506     {
507       template<typename _ForwardIterator, typename _Size>
508         static void
509         __uninit_default_n(_ForwardIterator __first, _Size __n)
510         {
511           typedef typename iterator_traits<_ForwardIterator>::value_type
512             _ValueType;
513
514           std::fill_n(__first, __n, _ValueType());
515         }
516     };
517
518   // __uninitialized_default
519   // Fills [first, last) with std::distance(first, last) default
520   // constructed value_types(s).
521   template<typename _ForwardIterator>
522     inline void
523     __uninitialized_default(_ForwardIterator __first,
524                             _ForwardIterator __last)
525     {
526       typedef typename iterator_traits<_ForwardIterator>::value_type
527         _ValueType;
528
529       std::__uninitialized_default_1<__is_trivial(_ValueType)>::
530         __uninit_default(__first, __last);
531     }
532
533   // __uninitialized_default_n
534   // Fills [first, first + n) with n default constructed value_type(s).
535   template<typename _ForwardIterator, typename _Size>
536     inline void
537     __uninitialized_default_n(_ForwardIterator __first, _Size __n)
538     {
539       typedef typename iterator_traits<_ForwardIterator>::value_type
540         _ValueType;
541
542       std::__uninitialized_default_n_1<__is_trivial(_ValueType)>::
543         __uninit_default_n(__first, __n);
544     }
545
546
547   // __uninitialized_default_a
548   // Fills [first, last) with std::distance(first, last) default
549   // constructed value_types(s), constructed with the allocator alloc.
550   template<typename _ForwardIterator, typename _Allocator>
551     void
552     __uninitialized_default_a(_ForwardIterator __first,
553                               _ForwardIterator __last,
554                               _Allocator& __alloc)
555     {
556       _ForwardIterator __cur = __first;
557       __try
558         {
559           for (; __cur != __last; ++__cur)
560             __alloc.construct(std::__addressof(*__cur));
561         }
562       __catch(...)
563         {
564           std::_Destroy(__first, __cur, __alloc);
565           __throw_exception_again;
566         }
567     }
568
569   template<typename _ForwardIterator, typename _Tp>
570     inline void
571     __uninitialized_default_a(_ForwardIterator __first,
572                               _ForwardIterator __last,
573                               allocator<_Tp>&)
574     { std::__uninitialized_default(__first, __last); }
575
576
577   // __uninitialized_default_n_a
578   // Fills [first, first + n) with n default constructed value_types(s),
579   // constructed with the allocator alloc.
580   template<typename _ForwardIterator, typename _Size, typename _Allocator>
581     void
582     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
583                                 _Allocator& __alloc)
584     {
585       _ForwardIterator __cur = __first;
586       __try
587         {
588           for (; __n > 0; --__n, ++__cur)
589             __alloc.construct(std::__addressof(*__cur));
590         }
591       __catch(...)
592         {
593           std::_Destroy(__first, __cur, __alloc);
594           __throw_exception_again;
595         }
596     }
597
598   template<typename _ForwardIterator, typename _Size, typename _Tp>
599     inline void
600     __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, 
601                                 allocator<_Tp>&)
602     { std::__uninitialized_default_n(__first, __n); }
603
604
605   template<typename _InputIterator, typename _Size,
606            typename _ForwardIterator>
607     _ForwardIterator
608     __uninitialized_copy_n(_InputIterator __first, _Size __n,
609                            _ForwardIterator __result, input_iterator_tag)
610     {
611       _ForwardIterator __cur = __result;
612       __try
613         {
614           for (; __n > 0; --__n, ++__first, ++__cur)
615             std::_Construct(std::__addressof(*__cur), *__first);
616           return __cur;
617         }
618       __catch(...)
619         {
620           std::_Destroy(__result, __cur);
621           __throw_exception_again;
622         }
623     }
624
625   template<typename _RandomAccessIterator, typename _Size,
626            typename _ForwardIterator>
627     inline _ForwardIterator
628     __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
629                            _ForwardIterator __result,
630                            random_access_iterator_tag)
631     { return std::uninitialized_copy(__first, __first + __n, __result); }
632
633   /**
634    *  @brief Copies the range [first,first+n) into result.
635    *  @param  first  An input iterator.
636    *  @param  n      The number of elements to copy.
637    *  @param  result An output iterator.
638    *  @return  result + n
639    *
640    *  Like copy_n(), but does not require an initialized output range.
641   */
642   template<typename _InputIterator, typename _Size, typename _ForwardIterator>
643     inline _ForwardIterator
644     uninitialized_copy_n(_InputIterator __first, _Size __n,
645                          _ForwardIterator __result)
646     { return std::__uninitialized_copy_n(__first, __n, __result,
647                                          std::__iterator_category(__first)); }
648 #endif
649
650 _GLIBCXX_END_NAMESPACE_VERSION
651 } // namespace
652
653 #endif /* _STL_UNINITIALIZED_H */