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, 2009
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20 
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
25 
26 /*
27  *
28  * Copyright (c) 1994
29  * Hewlett-Packard Company
30  *
31  * Permission to use, copy, modify, distribute and sell this software
32  * and its documentation for any purpose is hereby granted without fee,
33  * provided that the above copyright notice appear in all copies and
34  * that both that copyright notice and this permission notice appear
35  * in supporting documentation. Hewlett-Packard Company makes no
36  * representations about the suitability of this software for any
37  * purpose. It is provided "as is" without express or implied warranty.
38  *
39  *
40  * Copyright (c) 1996,1997
41  * Silicon Graphics Computer Systems, Inc.
42  *
43  * Permission to use, copy, modify, distribute and sell this software
44  * and its documentation for any purpose is hereby granted without fee,
45  * provided that the above copyright notice appear in all copies and
46  * that both that copyright notice and this permission notice appear
47  * in supporting documentation. Silicon Graphics makes no
48  * representations about the suitability of this software for any
49  * purpose. It is provided "as is" without express or implied warranty.
50  */
51 
52 /** @file stl_uninitialized.h
53  * This is an internal header file, included by other library headers.
54  * You should not attempt to use it directly.
55  */
56 
57 #ifndef _STL_UNINITIALIZED_H
58 #define _STL_UNINITIALIZED_H 1
59 
60 _GLIBCXX_BEGIN_NAMESPACE(std)
61 
62  template<bool>
63  struct __uninitialized_copy
64  {
65  template<typename _InputIterator, typename _ForwardIterator>
66  static _ForwardIterator
67  uninitialized_copy(_InputIterator __first, _InputIterator __last,
68  _ForwardIterator __result)
69  {
70  _ForwardIterator __cur = __result;
71  __try
72  {
73  for (; __first != __last; ++__first, ++__cur)
74  ::new(static_cast<void*>(&*__cur)) typename
75  iterator_traits<_ForwardIterator>::value_type(*__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  uninitialized_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_pod(_ValueType1)
116  && __is_pod(_ValueType2))>::
117  uninitialized_copy(__first, __last, __result);
118  }
119 
120 
121  template<bool>
122  struct __uninitialized_fill
123  {
124  template<typename _ForwardIterator, typename _Tp>
125  static void
126  uninitialized_fill(_ForwardIterator __first,
127  _ForwardIterator __last, const _Tp& __x)
128  {
129  _ForwardIterator __cur = __first;
130  __try
131  {
132  for (; __cur != __last; ++__cur)
133  std::_Construct(&*__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  uninitialized_fill(_ForwardIterator __first,
149  _ForwardIterator __last, 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_pod(_ValueType)>::
171  uninitialized_fill(__first, __last, __x);
172  }
173 
174 
175  template<bool>
176  struct __uninitialized_fill_n
177  {
178  template<typename _ForwardIterator, typename _Size, typename _Tp>
179  static void
180  uninitialized_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(&*__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  uninitialized_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_pod(_ValueType)>::
224  uninitialized_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  for (; __first != __last; ++__first, ++__cur)
243  __alloc.construct(&*__cur, *__first);
244  return __cur;
245  }
246  __catch(...)
247  {
248  std::_Destroy(__result, __cur, __alloc);
249  __throw_exception_again;
250  }
251  }
252 
253  template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
254  inline _ForwardIterator
255  __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
256  _ForwardIterator __result, allocator<_Tp>&)
257  { return std::uninitialized_copy(__first, __last, __result); }
258 
259  template<typename _InputIterator, typename _ForwardIterator,
260  typename _Allocator>
261  inline _ForwardIterator
262  __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
263  _ForwardIterator __result, _Allocator& __alloc)
264  {
265  return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
266  _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
267  __result, __alloc);
268  }
269 
270  template<typename _ForwardIterator, typename _Tp, typename _Allocator>
271  void
272  __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
273  const _Tp& __x, _Allocator& __alloc)
274  {
275  _ForwardIterator __cur = __first;
276  __try
277  {
278  for (; __cur != __last; ++__cur)
279  __alloc.construct(&*__cur, __x);
280  }
281  __catch(...)
282  {
283  std::_Destroy(__first, __cur, __alloc);
284  __throw_exception_again;
285  }
286  }
287 
288  template<typename _ForwardIterator, typename _Tp, typename _Tp2>
289  inline void
290  __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
291  const _Tp& __x, allocator<_Tp2>&)
292  { std::uninitialized_fill(__first, __last, __x); }
293 
294  template<typename _ForwardIterator, typename _Size, typename _Tp,
295  typename _Allocator>
296  void
297  __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
298  const _Tp& __x, _Allocator& __alloc)
299  {
300  _ForwardIterator __cur = __first;
301  __try
302  {
303  for (; __n > 0; --__n, ++__cur)
304  __alloc.construct(&*__cur, __x);
305  }
306  __catch(...)
307  {
308  std::_Destroy(__first, __cur, __alloc);
309  __throw_exception_again;
310  }
311  }
312 
313  template<typename _ForwardIterator, typename _Size, typename _Tp,
314  typename _Tp2>
315  inline void
316  __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n,
317  const _Tp& __x, allocator<_Tp2>&)
318  { std::uninitialized_fill_n(__first, __n, __x); }
319 
320 
321  // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
322  // __uninitialized_fill_move, __uninitialized_move_fill.
323  // All of these algorithms take a user-supplied allocator, which is used
324  // for construction and destruction.
325 
326  // __uninitialized_copy_move
327  // Copies [first1, last1) into [result, result + (last1 - first1)), and
328  // move [first2, last2) into
329  // [result, result + (last1 - first1) + (last2 - first2)).
330  template<typename _InputIterator1, typename _InputIterator2,
331  typename _ForwardIterator, typename _Allocator>
332  inline _ForwardIterator
333  __uninitialized_copy_move(_InputIterator1 __first1,
334  _InputIterator1 __last1,
335  _InputIterator2 __first2,
336  _InputIterator2 __last2,
337  _ForwardIterator __result,
338  _Allocator& __alloc)
339  {
340  _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
341  __result,
342  __alloc);
343  __try
344  {
345  return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
346  }
347  __catch(...)
348  {
349  std::_Destroy(__result, __mid, __alloc);
350  __throw_exception_again;
351  }
352  }
353 
354  // __uninitialized_move_copy
355  // Moves [first1, last1) into [result, result + (last1 - first1)), and
356  // copies [first2, last2) into
357  // [result, result + (last1 - first1) + (last2 - first2)).
358  template<typename _InputIterator1, typename _InputIterator2,
359  typename _ForwardIterator, typename _Allocator>
360  inline _ForwardIterator
361  __uninitialized_move_copy(_InputIterator1 __first1,
362  _InputIterator1 __last1,
363  _InputIterator2 __first2,
364  _InputIterator2 __last2,
365  _ForwardIterator __result,
366  _Allocator& __alloc)
367  {
368  _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
369  __result,
370  __alloc);
371  __try
372  {
373  return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
374  }
375  __catch(...)
376  {
377  std::_Destroy(__result, __mid, __alloc);
378  __throw_exception_again;
379  }
380  }
381 
382  // __uninitialized_fill_move
383  // Fills [result, mid) with x, and moves [first, last) into
384  // [mid, mid + (last - first)).
385  template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
386  typename _Allocator>
387  inline _ForwardIterator
388  __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
389  const _Tp& __x, _InputIterator __first,
390  _InputIterator __last, _Allocator& __alloc)
391  {
392  std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
393  __try
394  {
395  return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
396  }
397  __catch(...)
398  {
399  std::_Destroy(__result, __mid, __alloc);
400  __throw_exception_again;
401  }
402  }
403 
404  // __uninitialized_move_fill
405  // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
406  // fills [first2 + (last1 - first1), last2) with x.
407  template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
408  typename _Allocator>
409  inline void
410  __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
411  _ForwardIterator __first2,
412  _ForwardIterator __last2, const _Tp& __x,
413  _Allocator& __alloc)
414  {
415  _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
416  __first2,
417  __alloc);
418  __try
419  {
420  std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
421  }
422  __catch(...)
423  {
424  std::_Destroy(__first2, __mid2, __alloc);
425  __throw_exception_again;
426  }
427  }
428 
429 #ifdef __GXX_EXPERIMENTAL_CXX0X__
430  template<typename _InputIterator, typename _Size,
431  typename _ForwardIterator>
432  _ForwardIterator
433  __uninitialized_copy_n(_InputIterator __first, _Size __n,
434  _ForwardIterator __result, input_iterator_tag)
435  {
436  _ForwardIterator __cur = __result;
437  __try
438  {
439  for (; __n > 0; --__n, ++__first, ++__cur)
440  ::new(static_cast<void*>(&*__cur)) typename
441  iterator_traits<_ForwardIterator>::value_type(*__first);
442  return __cur;
443  }
444  __catch(...)
445  {
446  std::_Destroy(__result, __cur);
447  __throw_exception_again;
448  }
449  }
450 
451  template<typename _RandomAccessIterator, typename _Size,
452  typename _ForwardIterator>
453  inline _ForwardIterator
454  __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n,
455  _ForwardIterator __result,
456  random_access_iterator_tag)
457  { return std::uninitialized_copy(__first, __first + __n, __result); }
458 
459  /**
460  * @brief Copies the range [first,first+n) into result.
461  * @param first An input iterator.
462  * @param n The number of elements to copy.
463  * @param result An output iterator.
464  * @return result + n
465  *
466  * Like copy_n(), but does not require an initialized output range.
467  */
468  template<typename _InputIterator, typename _Size, typename _ForwardIterator>
469  inline _ForwardIterator
470  uninitialized_copy_n(_InputIterator __first, _Size __n,
471  _ForwardIterator __result)
472  { return std::__uninitialized_copy_n(__first, __n, __result,
473  std::__iterator_category(__first)); }
474 #endif
475 
476 _GLIBCXX_END_NAMESPACE
477 
478 #endif /* _STL_UNINITIALIZED_H */