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 36673 : _ForwardIterator __result)
74 : {
75 36673 : _ForwardIterator __cur = __result;
76 : try
77 : {
78 84888 : for (; __first != __last; ++__first, ++__cur)
79 48215 : ::new(static_cast<void*>(&*__cur)) typename
80 : iterator_traits<_ForwardIterator>::value_type(*__first);
81 36660 : return __cur;
82 : }
83 0 : catch(...)
84 : {
85 0 : std::_Destroy(__result, __cur);
86 0 : __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 27152 : _ForwardIterator __result)
98 27152 : { 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 63825 : _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 63825 : 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 22443 : const _Tp& __x)
187 : {
188 22443 : _ForwardIterator __cur = __first;
189 : try
190 : {
191 46138 : for (; __n > 0; --__n, ++__cur)
192 23695 : std::_Construct(&*__cur, __x);
193 : }
194 0 : catch(...)
195 : {
196 0 : std::_Destroy(__first, __cur);
197 0 : __throw_exception_again;
198 : }
199 22443 : }
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 9 : const _Tp& __x)
209 9 : { 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 22452 : uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x)
224 : {
225 : typedef typename iterator_traits<_ForwardIterator>::value_type
226 : _ValueType;
227 :
228 22452 : std::__uninitialized_fill_n<__is_pod(_ValueType)>::
229 : uninitialized_fill_n(__first, __n, __x);
230 22452 : }
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 63825 : _ForwardIterator __result, allocator<_Tp>&)
262 63825 : { 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 63802 : _ForwardIterator __result, _Allocator& __alloc)
269 : {
270 : return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first),
271 : _GLIBCXX_MAKE_MOVE_ITERATOR(__last),
272 63802 : __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 22452 : const _Tp& __x, allocator<_Tp2>&)
323 22452 : { std::uninitialized_fill_n(__first, __n, __x); }
324 :
325 :
326 : // Extensions: __uninitialized_copy_move, __uninitialized_move_copy,
327 : // __uninitialized_fill_move, __uninitialized_move_fill.
328 : // All of these algorithms take a user-supplied allocator, which is used
329 : // for construction and destruction.
330 :
331 : // __uninitialized_copy_move
332 : // Copies [first1, last1) into [result, result + (last1 - first1)), and
333 : // move [first2, last2) into
334 : // [result, result + (last1 - first1) + (last2 - first2)).
335 : template<typename _InputIterator1, typename _InputIterator2,
336 : typename _ForwardIterator, typename _Allocator>
337 : inline _ForwardIterator
338 : __uninitialized_copy_move(_InputIterator1 __first1,
339 : _InputIterator1 __last1,
340 : _InputIterator2 __first2,
341 : _InputIterator2 __last2,
342 : _ForwardIterator __result,
343 0 : _Allocator& __alloc)
344 : {
345 : _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1,
346 : __result,
347 0 : __alloc);
348 : try
349 : {
350 0 : return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc);
351 : }
352 0 : catch(...)
353 : {
354 0 : std::_Destroy(__result, __mid, __alloc);
355 0 : __throw_exception_again;
356 : }
357 : }
358 :
359 : // __uninitialized_move_copy
360 : // Moves [first1, last1) into [result, result + (last1 - first1)), and
361 : // copies [first2, last2) into
362 : // [result, result + (last1 - first1) + (last2 - first2)).
363 : template<typename _InputIterator1, typename _InputIterator2,
364 : typename _ForwardIterator, typename _Allocator>
365 : inline _ForwardIterator
366 : __uninitialized_move_copy(_InputIterator1 __first1,
367 : _InputIterator1 __last1,
368 : _InputIterator2 __first2,
369 : _InputIterator2 __last2,
370 : _ForwardIterator __result,
371 0 : _Allocator& __alloc)
372 : {
373 : _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1,
374 : __result,
375 0 : __alloc);
376 : try
377 : {
378 0 : return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc);
379 : }
380 0 : catch(...)
381 : {
382 0 : std::_Destroy(__result, __mid, __alloc);
383 0 : __throw_exception_again;
384 : }
385 : }
386 :
387 : // __uninitialized_fill_move
388 : // Fills [result, mid) with x, and moves [first, last) into
389 : // [mid, mid + (last - first)).
390 : template<typename _ForwardIterator, typename _Tp, typename _InputIterator,
391 : typename _Allocator>
392 : inline _ForwardIterator
393 : __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid,
394 : const _Tp& __x, _InputIterator __first,
395 : _InputIterator __last, _Allocator& __alloc)
396 : {
397 : std::__uninitialized_fill_a(__result, __mid, __x, __alloc);
398 : try
399 : {
400 : return std::__uninitialized_move_a(__first, __last, __mid, __alloc);
401 : }
402 : catch(...)
403 : {
404 : std::_Destroy(__result, __mid, __alloc);
405 : __throw_exception_again;
406 : }
407 : }
408 :
409 : // __uninitialized_move_fill
410 : // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and
411 : // fills [first2 + (last1 - first1), last2) with x.
412 : template<typename _InputIterator, typename _ForwardIterator, typename _Tp,
413 : typename _Allocator>
414 : inline void
415 : __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1,
416 : _ForwardIterator __first2,
417 : _ForwardIterator __last2, const _Tp& __x,
418 : _Allocator& __alloc)
419 : {
420 : _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1,
421 : __first2,
422 : __alloc);
423 : try
424 : {
425 : std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc);
426 : }
427 : catch(...)
428 : {
429 : std::_Destroy(__first2, __mid2, __alloc);
430 : __throw_exception_again;
431 : }
432 : }
433 :
434 : _GLIBCXX_END_NAMESPACE
435 :
436 : #endif /* _STL_UNINITIALIZED_H */
|