libstdc++
stl_uninitialized.h
Go to the documentation of this file.
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)
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)
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 */
_OI fill_n(_OI __first, _Size __n, const _Tp &__value)
Fills the range [first,first+n) with copies of value.
Definition: stl_algobase.h:781
void uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp &__x)
Copies the value x into the range [first,first+n).
Uniform interface to C++98 and C++0x allocators.
void uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp &__x)
Copies the value x into the range [first,last).
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition: move.h:47
void _Construct(_T1 *__p, _Args &&...__args)
Definition: stl_construct.h:74
ISO C++ entities toplevel namespace is std.
iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
_ForwardIterator uninitialized_copy(_InputIterator __first, _InputIterator __last, _ForwardIterator __result)
Copies the range [first,last) into result.
void _Destroy(_Tp *__pointer)
Definition: stl_construct.h:92
_ForwardIterator uninitialized_copy_n(_InputIterator __first, _Size __n, _ForwardIterator __result)
Copies the range [first,first+n) into result.