stl_uninitialized.h revision 132720
195643Smarkm// Raw memory manipulators -*- C++ -*-
295643Smarkm
395643Smarkm// Copyright (C) 2001, 2004 Free Software Foundation, Inc.
495643Smarkm//
595643Smarkm// This file is part of the GNU ISO C++ Library.  This library is free
695643Smarkm// software; you can redistribute it and/or modify it under the
795643Smarkm// terms of the GNU General Public License as published by the
895643Smarkm// Free Software Foundation; either version 2, or (at your option)
995643Smarkm// any later version.
1095643Smarkm
1195643Smarkm// This library is distributed in the hope that it will be useful,
1295643Smarkm// but WITHOUT ANY WARRANTY; without even the implied warranty of
1395643Smarkm// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1495643Smarkm// GNU General Public License for more details.
1595643Smarkm
1695643Smarkm// You should have received a copy of the GNU General Public License along
1795643Smarkm// with this library; see the file COPYING.  If not, write to the Free
1895643Smarkm// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
1995643Smarkm// USA.
2095643Smarkm
2195643Smarkm// As a special exception, you may use this file as part of a free software
2295643Smarkm// library without restriction.  Specifically, if other files instantiate
2395643Smarkm// templates or use macros or inline functions from this file, or you compile
2495643Smarkm// this file and link it with other files to produce an executable, this
2595643Smarkm// file does not by itself cause the resulting executable to be covered by
2695643Smarkm// the GNU General Public License.  This exception does not however
2795643Smarkm// invalidate any other reasons why the executable file might be covered by
2895643Smarkm// the GNU General Public License.
2995643Smarkm
3095643Smarkm/*
3195643Smarkm *
3295643Smarkm * Copyright (c) 1994
3395643Smarkm * Hewlett-Packard Company
3495643Smarkm *
3595643Smarkm * Permission to use, copy, modify, distribute and sell this software
3695643Smarkm * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation.  Hewlett-Packard Company makes no
40 * representations about the suitability of this software for any
41 * purpose.  It is provided "as is" without express or implied warranty.
42 *
43 *
44 * Copyright (c) 1996,1997
45 * Silicon Graphics Computer Systems, Inc.
46 *
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation.  Silicon Graphics makes no
52 * representations about the suitability of this software for any
53 * purpose.  It is provided "as is" without express or implied warranty.
54 */
55
56/** @file stl_uninitialized.h
57 *  This is an internal header file, included by other library headers.
58 *  You should not attempt to use it directly.
59 */
60
61#ifndef _STL_UNINITIALIZED_H
62#define _STL_UNINITIALIZED_H 1
63
64#include <cstring>
65
66namespace std
67{
68  // uninitialized_copy
69  template<typename _InputIterator, typename _ForwardIterator>
70    inline _ForwardIterator
71    __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last,
72			     _ForwardIterator __result,
73			     __true_type)
74    { return std::copy(__first, __last, __result); }
75
76  template<typename _InputIterator, typename _ForwardIterator>
77    inline _ForwardIterator
78    __uninitialized_copy_aux(_InputIterator __first, _InputIterator __last,
79			     _ForwardIterator __result,
80			     __false_type)
81    {
82      _ForwardIterator __cur = __result;
83      try
84	{
85	  for ( ; __first != __last; ++__first, ++__cur)
86	    std::_Construct(&*__cur, *__first);
87	  return __cur;
88	}
89      catch(...)
90	{
91	  std::_Destroy(__result, __cur);
92	  __throw_exception_again;
93	}
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<_ForwardIterator>::value_type _ValueType;
111      typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
112      return std::__uninitialized_copy_aux(__first, __last, __result,
113					   _Is_POD());
114    }
115
116  inline char*
117  uninitialized_copy(const char* __first, const char* __last, char* __result)
118  {
119    std::memmove(__result, __first, __last - __first);
120    return __result + (__last - __first);
121  }
122
123  inline wchar_t*
124  uninitialized_copy(const wchar_t* __first, const wchar_t* __last,
125		     wchar_t* __result)
126  {
127    std::memmove(__result, __first, sizeof(wchar_t) * (__last - __first));
128    return __result + (__last - __first);
129  }
130
131  // Valid if copy construction is equivalent to assignment, and if the
132  // destructor is trivial.
133  template<typename _ForwardIterator, typename _Tp>
134    inline void
135    __uninitialized_fill_aux(_ForwardIterator __first,
136			     _ForwardIterator __last,
137			     const _Tp& __x, __true_type)
138    { std::fill(__first, __last, __x); }
139
140  template<typename _ForwardIterator, typename _Tp>
141    void
142    __uninitialized_fill_aux(_ForwardIterator __first, _ForwardIterator __last,
143			     const _Tp& __x, __false_type)
144    {
145      _ForwardIterator __cur = __first;
146      try
147	{
148	  for ( ; __cur != __last; ++__cur)
149	    std::_Construct(&*__cur, __x);
150	}
151      catch(...)
152	{
153	  std::_Destroy(__first, __cur);
154	  __throw_exception_again;
155	}
156    }
157
158  /**
159   *  @brief Copies the value x into the range [first,last).
160   *  @param  first  An input iterator.
161   *  @param  last   An input iterator.
162   *  @param  x      The source value.
163   *  @return   Nothing.
164   *
165   *  Like fill(), but does not require an initialized output range.
166  */
167  template<typename _ForwardIterator, typename _Tp>
168    inline void
169    uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last,
170		       const _Tp& __x)
171    {
172      typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
173      typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
174      std::__uninitialized_fill_aux(__first, __last, __x, _Is_POD());
175    }
176
177  // Valid if copy construction is equivalent to assignment, and if the
178  //  destructor is trivial.
179  template<typename _ForwardIterator, typename _Size, typename _Tp>
180    inline _ForwardIterator
181    __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
182			       const _Tp& __x, __true_type)
183    { return std::fill_n(__first, __n, __x); }
184
185  template<typename _ForwardIterator, typename _Size, typename _Tp>
186    _ForwardIterator
187    __uninitialized_fill_n_aux(_ForwardIterator __first, _Size __n,
188			       const _Tp& __x, __false_type)
189    {
190      _ForwardIterator __cur = __first;
191      try
192	{
193	  for ( ; __n > 0; --__n, ++__cur)
194	    std::_Construct(&*__cur, __x);
195	  return __cur;
196	}
197      catch(...)
198	{
199	  std::_Destroy(__first, __cur);
200	  __throw_exception_again;
201	}
202    }
203
204  /**
205   *  @brief Copies the value x into the range [first,first+n).
206   *  @param  first  An input iterator.
207   *  @param  n      The number of copies to make.
208   *  @param  x      The source value.
209   *  @return   first+n
210   *
211   *  Like fill_n(), but does not require an initialized output range.
212  */
213  template<typename _ForwardIterator, typename _Size, typename _Tp>
214    inline _ForwardIterator
215    uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
216    {
217      typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
218      typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD;
219      return std::__uninitialized_fill_n_aux(__first, __n, __x, _Is_POD());
220    }
221
222  // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill,
223  // __uninitialized_fill_copy.
224
225  // __uninitialized_copy_copy
226  // Copies [first1, last1) into [result, result + (last1 - first1)), and
227  //  copies [first2, last2) into
228  //  [result, result + (last1 - first1) + (last2 - first2)).
229
230  template<typename _InputIterator1, typename _InputIterator2,
231	   typename _ForwardIterator>
232    inline _ForwardIterator
233    __uninitialized_copy_copy(_InputIterator1 __first1,
234			      _InputIterator1 __last1,
235			      _InputIterator2 __first2,
236			      _InputIterator2 __last2,
237			      _ForwardIterator __result)
238    {
239      _ForwardIterator __mid = std::uninitialized_copy(__first1, __last1,
240						       __result);
241      try
242	{
243	  return std::uninitialized_copy(__first2, __last2, __mid);
244	}
245      catch(...)
246	{
247	  std::_Destroy(__result, __mid);
248	  __throw_exception_again;
249	}
250    }
251
252  // __uninitialized_fill_copy
253  // Fills [result, mid) with x, and copies [first, last) into
254  //  [mid, mid + (last - first)).
255  template<typename _ForwardIterator, typename _Tp, typename _InputIterator>
256    inline _ForwardIterator
257    __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid,
258			      const _Tp& __x, _InputIterator __first,
259			      _InputIterator __last)
260    {
261      std::uninitialized_fill(__result, __mid, __x);
262      try
263	{
264	  return std::uninitialized_copy(__first, __last, __mid);
265	}
266      catch(...)
267	{
268	  std::_Destroy(__result, __mid);
269	  __throw_exception_again;
270	}
271    }
272
273  // __uninitialized_copy_fill
274  // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
275  //  fills [first2 + (last1 - first1), last2) with x.
276  template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
277    inline void
278    __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1,
279			      _ForwardIterator __first2,
280			      _ForwardIterator __last2, const _Tp& __x)
281    {
282      _ForwardIterator __mid2 = std::uninitialized_copy(__first1, __last1,
283							__first2);
284      try
285	{
286	  std::uninitialized_fill(__mid2, __last2, __x);
287	}
288      catch(...)
289	{
290	  std::_Destroy(__first2, __mid2);
291	  __throw_exception_again;
292	}
293    }
294
295} // namespace std
296
297#endif /* _STL_UNINITIALIZED_H */
298