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