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