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