OSDN Git Service

2007-11-05 Chris Jefferson <chris@bubblescope.net>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / bits / stl_uninitialized.h
1 // Raw memory manipulators -*- C++ -*-
2
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
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 2, 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 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 /*
32  *
33  * Copyright (c) 1994
34  * Hewlett-Packard Company
35  *
36  * Permission to use, copy, modify, distribute and sell this software
37  * and its documentation for any purpose is hereby granted without fee,
38  * provided that the above copyright notice appear in all copies and
39  * that both that copyright notice and this permission notice appear
40  * in supporting documentation.  Hewlett-Packard Company makes no
41  * representations about the suitability of this software for any
42  * purpose.  It is provided "as is" without express or implied warranty.
43  *
44  *
45  * Copyright (c) 1996,1997
46  * Silicon Graphics Computer Systems, Inc.
47  *
48  * Permission to use, copy, modify, distribute and sell this software
49  * and its documentation for any purpose is hereby granted without fee,
50  * provided that the above copyright notice appear in all copies and
51  * that both that copyright notice and this permission notice appear
52  * in supporting documentation.  Silicon Graphics makes no
53  * representations about the suitability of this software for any
54  * purpose.  It is provided "as is" without express or implied warranty.
55  */
56
57 /** @file stl_uninitialized.h
58  *  This is an internal header file, included by other library headers.
59  *  You should not attempt to use it directly.
60  */
61
62 #ifndef _STL_UNINITIALIZED_H
63 #define _STL_UNINITIALIZED_H 1
64
65 _GLIBCXX_BEGIN_NAMESPACE(std)
66
67   template<bool>
68     struct __uninitialized_copy
69     {
70       template<typename _InputIterator, typename _ForwardIterator>
71         static _ForwardIterator
72         uninitialized_copy(_InputIterator __first, _InputIterator __last,
73                            _ForwardIterator __result)
74         {
75           _ForwardIterator __cur = __result;
76           try
77             {
78               for (; __first != __last; ++__first, ++__cur)
79                 ::new(static_cast<void*>(&*__cur)) typename
80                     iterator_traits<_ForwardIterator>::value_type(*__first);
81               return __cur;
82             }
83           catch(...)
84             {
85               std::_Destroy(__result, __cur);
86               __throw_exception_again;
87             }
88         }
89     };
90
91   template<>
92     struct __uninitialized_copy<true>
93     {
94       template<typename _InputIterator, typename _ForwardIterator>
95         static _ForwardIterator
96         uninitialized_copy(_InputIterator __first, _InputIterator __last,
97                            _ForwardIterator __result)
98         { return std::copy(__first, __last, __result); }
99     };
100
101   /**
102    *  @brief Copies the range [first,last) into result.
103    *  @param  first  An input iterator.
104    *  @param  last   An input iterator.
105    *  @param  result An output iterator.
106    *  @return   result + (first - last)
107    *
108    *  Like copy(), but does not require an initialized output range.
109   */
110   template<typename _InputIterator, typename _ForwardIterator>
111     inline _ForwardIterator
112     uninitialized_copy(_InputIterator __first, _InputIterator __last,
113                        _ForwardIterator __result)
114     {
115       typedef typename iterator_traits<_InputIterator>::value_type
116         _ValueType1;
117       typedef typename iterator_traits<_ForwardIterator>::value_type
118         _ValueType2;
119
120       return std::__uninitialized_copy<(__is_pod(_ValueType1)
121                                         && __is_pod(_ValueType2))>::
122         uninitialized_copy(__first, __last, __result);
123     }
124
125
126   template<bool>
127     struct __uninitialized_fill
128     {
129       template<typename _ForwardIterator, typename _Tp>
130         static void
131         uninitialized_fill(_ForwardIterator __first,
132                            _ForwardIterator __last, const _Tp& __x)
133         {
134           _ForwardIterator __cur = __first;
135           try
136             {
137               for (; __cur != __last; ++__cur)
138                 std::_Construct(&*__cur, __x);
139             }
140           catch(...)
141             {
142               std::_Destroy(__first, __cur);
143               __throw_exception_again;
144             }
145         }
146     };
147
148   template<>
149     struct __uninitialized_fill<true>
150     {
151       template<typename _ForwardIterator, typename _Tp>
152         static void
153         uninitialized_fill(_ForwardIterator __first,
154                            _ForwardIterator __last, const _Tp& __x)
155         { std::fill(__first, __last, __x); }
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
173         _ValueType;
174
175       std::__uninitialized_fill<__is_pod(_ValueType)>::
176         uninitialized_fill(__first, __last, __x);
177     }
178
179
180   template<bool>
181     struct __uninitialized_fill_n
182     {
183       template<typename _ForwardIterator, typename _Size, typename _Tp>
184         static void
185         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
186                              const _Tp& __x)
187         {
188           _ForwardIterator __cur = __first;
189           try
190             {
191               for (; __n > 0; --__n, ++__cur)
192                 std::_Construct(&*__cur, __x);
193             }
194           catch(...)
195             {
196               std::_Destroy(__first, __cur);
197               __throw_exception_again;
198             }
199         }
200     };
201
202   template<>
203     struct __uninitialized_fill_n<true>
204     {
205       template<typename _ForwardIterator, typename _Size, typename _Tp>
206         static void
207         uninitialized_fill_n(_ForwardIterator __first, _Size __n,
208                              const _Tp& __x)
209         { std::fill_n(__first, __n, __x); }
210     };
211
212   /**
213    *  @brief Copies the value x into the range [first,first+n).
214    *  @param  first  An input iterator.
215    *  @param  n      The number of copies to make.
216    *  @param  x      The source value.
217    *  @return   Nothing.
218    *
219    *  Like fill_n(), but does not require an initialized output range.
220   */
221   template<typename _ForwardIterator, typename _Size, typename _Tp>
222     inline void
223     uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
224     {
225       typedef typename iterator_traits<_ForwardIterator>::value_type
226         _ValueType;
227
228       std::__uninitialized_fill_n<__is_pod(_ValueType)>::
229         uninitialized_fill_n(__first, __n, __x);
230     }
231
232   // Extensions: versions of uninitialized_copy, uninitialized_fill,
233   //  and uninitialized_fill_n that take an allocator parameter.
234   //  We dispatch back to the standard versions when we're given the
235   //  default allocator.  For nondefault allocators we do not use 
236   //  any of the POD optimizations.
237
238   template<typename _InputIterator, typename _ForwardIterator,
239            typename _Allocator>
240     _ForwardIterator
241     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
242                            _ForwardIterator __result, _Allocator& __alloc)
243     {
244       _ForwardIterator __cur = __result;
245       try
246         {
247           for (; __first != __last; ++__first, ++__cur)
248             __alloc.construct(&*__cur, *__first);
249           return __cur;
250         }
251       catch(...)
252         {
253           std::_Destroy(__result, __cur, __alloc);
254           __throw_exception_again;
255         }
256     }
257
258   template<typename _InputIterator, typename _ForwardIterator, typename _Tp>
259     inline _ForwardIterator
260     __uninitialized_copy_a(_InputIterator __first, _InputIterator __last,
261                            _ForwardIterator __result, allocator<_Tp>&)
262     { return std::uninitialized_copy(__first, __last, __result); }
263
264   template<typename _InputIterator, typename _ForwardIterator,
265            typename _Allocator>
266     inline _ForwardIterator
267     __uninitialized_move_a(_InputIterator __first, _InputIterator __last,
268                            _ForwardIterator __result, _Allocator& __alloc)
269     {
270       return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
271                                          _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
272                                          __result, __alloc);
273     }
274
275   template<typename _ForwardIterator, typename _Tp, typename _Allocator>
276     void
277     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
278                            const _Tp& __x, _Allocator& __alloc)
279     {
280       _ForwardIterator __cur = __first;
281       try
282         {
283           for (; __cur != __last; ++__cur)
284             __alloc.construct(&*__cur, __x);
285         }
286       catch(...)
287         {
288           std::_Destroy(__first, __cur, __alloc);
289           __throw_exception_again;
290         }
291     }
292
293   template<typename _ForwardIterator, typename _Tp, typename _Tp2>
294     inline void
295     __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last,
296                            const _Tp& __x, allocator<_Tp2>&)
297     { std::uninitialized_fill(__first, __last, __x); }
298
299   template<typename _ForwardIterator, typename _Size, typename _Tp,
300            typename _Allocator>
301     void
302     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
303                              const _Tp& __x, _Allocator& __alloc)
304     {
305       _ForwardIterator __cur = __first;
306       try
307         {
308           for (; __n > 0; --__n, ++__cur)
309             __alloc.construct(&*__cur, __x);
310         }
311       catch(...)
312         {
313           std::_Destroy(__first, __cur, __alloc);
314           __throw_exception_again;
315         }
316     }
317
318   template<typename _ForwardIterator, typename _Size, typename _Tp,
319            typename _Tp2>
320     inline void
321     __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, 
322                              const _Tp& __x, allocator<_Tp2>&)
323     { std::uninitialized_fill_n(__first, __n, __x); }
324
325
326   // Extensions: __uninitialized_copy_copy, __uninitialized_copy_fill,
327   // __uninitialized_fill_copy.  All of these algorithms take a user-
328   // supplied allocator, which is used for construction and destruction.
329
330   // __uninitialized_copy_copy
331   // Copies [first1, last1) into [result, result + (last1 - first1)), and
332   //  copies [first2, last2) into
333   //  [result, result + (last1 - first1) + (last2 - first2)).
334
335   template<typename _InputIterator1, typename _InputIterator2,
336            typename _ForwardIterator, typename _Allocator>
337     inline _ForwardIterator
338     __uninitialized_copy_copy(_InputIterator1 __first1,
339                               _InputIterator1 __last1,
340                               _InputIterator2 __first2,
341                               _InputIterator2 __last2,
342                               _ForwardIterator __result,
343                               _Allocator& __alloc)
344     {
345       _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
346                                                            __result,
347                                                            __alloc);
348       try
349         {
350           return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
351         }
352       catch(...)
353         {
354           std::_Destroy(__result, __mid, __alloc);
355           __throw_exception_again;
356         }
357     }
358
359   // __uninitialized_fill_copy
360   // Fills [result, mid) with x, and copies [first, last) into
361   //  [mid, mid + (last - first)).
362   template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
363            typename _Allocator>
364     inline _ForwardIterator
365     __uninitialized_fill_copy(_ForwardIterator __result, _ForwardIterator __mid,
366                               const _Tp& __x, _InputIterator __first,
367                               _InputIterator __last, _Allocator& __alloc)
368     {
369       std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
370       try
371         {
372           return std::__uninitialized_copy_a(__first, __last, __mid, __alloc);
373         }
374       catch(...)
375         {
376           std::_Destroy(__result, __mid, __alloc);
377           __throw_exception_again;
378         }
379     }
380
381   // __uninitialized_copy_fill
382   // Copies [first1, last1) into [first2, first2 + (last1 - first1)), and
383   //  fills [first2 + (last1 - first1), last2) with x.
384   template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
385            typename _Allocator>
386     inline void
387     __uninitialized_copy_fill(_InputIterator __first1, _InputIterator __last1,
388                               _ForwardIterator __first2,
389                               _ForwardIterator __last2, const _Tp& __x,
390                               _Allocator& __alloc)
391     {
392       _ForwardIterator __mid2 = std::__uninitialized_copy_a(__first1, __last1,
393                                                             __first2,
394                                                             __alloc);
395       try
396         {
397           std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
398         }
399       catch(...)
400         {
401           std::_Destroy(__first2, __mid2, __alloc);
402           __throw_exception_again;
403         }
404     }
405
406 _GLIBCXX_END_NAMESPACE
407
408 #endif /* _STL_UNINITIALIZED_H */