]>
Commit | Line | Data |
---|---|---|
42526146 PE |
1 | // Raw memory manipulators -*- C++ -*- |
2 | ||
bc2631e0 | 3 | // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
8072ddb0 | 4 | // Free Software Foundation, Inc. |
42526146 PE |
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 | |
83f51799 | 19 | // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
42526146 PE |
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 | ||
725dc051 BK |
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 | ||
729e3d3f PE |
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. | |
725dc051 BK |
60 | */ |
61 | ||
3d7c150e BK |
62 | #ifndef _STL_UNINITIALIZED_H |
63 | #define _STL_UNINITIALIZED_H 1 | |
725dc051 | 64 | |
3cbc7af0 BK |
65 | _GLIBCXX_BEGIN_NAMESPACE(std) |
66 | ||
f4c5578f PC |
67 | template<bool> |
68 | struct __uninitialized_copy | |
02d92e3b | 69 | { |
f4c5578f PC |
70 | template<typename _InputIterator, typename _ForwardIterator> |
71 | static _ForwardIterator | |
72 | uninitialized_copy(_InputIterator __first, _InputIterator __last, | |
73 | _ForwardIterator __result) | |
74 | { | |
75 | _ForwardIterator __cur = __result; | |
bc2631e0 | 76 | __try |
f4c5578f PC |
77 | { |
78 | for (; __first != __last; ++__first, ++__cur) | |
e85b4fa7 PC |
79 | ::new(static_cast<void*>(&*__cur)) typename |
80 | iterator_traits<_ForwardIterator>::value_type(*__first); | |
f4c5578f PC |
81 | return __cur; |
82 | } | |
bc2631e0 | 83 | __catch(...) |
f4c5578f PC |
84 | { |
85 | std::_Destroy(__result, __cur); | |
86 | __throw_exception_again; | |
87 | } | |
322821b9 | 88 | } |
f4c5578f PC |
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 | }; | |
02d92e3b | 100 | |
82b61df5 PE |
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 | */ | |
08addde6 PE |
110 | template<typename _InputIterator, typename _ForwardIterator> |
111 | inline _ForwardIterator | |
ed6814f7 | 112 | uninitialized_copy(_InputIterator __first, _InputIterator __last, |
917a9fd4 | 113 | _ForwardIterator __result) |
02d92e3b | 114 | { |
f4c5578f PC |
115 | typedef typename iterator_traits<_InputIterator>::value_type |
116 | _ValueType1; | |
ff2ea587 | 117 | typedef typename iterator_traits<_ForwardIterator>::value_type |
f4c5578f PC |
118 | _ValueType2; |
119 | ||
120 | return std::__uninitialized_copy<(__is_pod(_ValueType1) | |
121 | && __is_pod(_ValueType2))>:: | |
122 | uninitialized_copy(__first, __last, __result); | |
02d92e3b SW |
123 | } |
124 | ||
02d92e3b | 125 | |
f4c5578f PC |
126 | template<bool> |
127 | struct __uninitialized_fill | |
02d92e3b | 128 | { |
f4c5578f PC |
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; | |
bc2631e0 | 135 | __try |
f4c5578f PC |
136 | { |
137 | for (; __cur != __last; ++__cur) | |
138 | std::_Construct(&*__cur, __x); | |
139 | } | |
bc2631e0 | 140 | __catch(...) |
f4c5578f PC |
141 | { |
142 | std::_Destroy(__first, __cur); | |
143 | __throw_exception_again; | |
144 | } | |
15d72060 | 145 | } |
f4c5578f PC |
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 | }; | |
02d92e3b | 157 | |
82b61df5 PE |
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 | */ | |
08addde6 | 167 | template<typename _ForwardIterator, typename _Tp> |
02d92e3b | 168 | inline void |
ed6814f7 | 169 | uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, |
917a9fd4 | 170 | const _Tp& __x) |
02d92e3b | 171 | { |
ff2ea587 PC |
172 | typedef typename iterator_traits<_ForwardIterator>::value_type |
173 | _ValueType; | |
f4c5578f PC |
174 | |
175 | std::__uninitialized_fill<__is_pod(_ValueType)>:: | |
176 | uninitialized_fill(__first, __last, __x); | |
02d92e3b SW |
177 | } |
178 | ||
02d92e3b | 179 | |
f4c5578f PC |
180 | template<bool> |
181 | struct __uninitialized_fill_n | |
02d92e3b | 182 | { |
f4c5578f PC |
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; | |
bc2631e0 | 189 | __try |
f4c5578f PC |
190 | { |
191 | for (; __n > 0; --__n, ++__cur) | |
192 | std::_Construct(&*__cur, __x); | |
193 | } | |
bc2631e0 | 194 | __catch(...) |
f4c5578f PC |
195 | { |
196 | std::_Destroy(__first, __cur); | |
197 | __throw_exception_again; | |
198 | } | |
322821b9 | 199 | } |
f4c5578f PC |
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 | }; | |
02d92e3b | 211 | |
82b61df5 PE |
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. | |
368b7a30 | 217 | * @return Nothing. |
82b61df5 PE |
218 | * |
219 | * Like fill_n(), but does not require an initialized output range. | |
220 | */ | |
08addde6 | 221 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
368b7a30 | 222 | inline void |
08addde6 | 223 | uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) |
02d92e3b | 224 | { |
ff2ea587 PC |
225 | typedef typename iterator_traits<_ForwardIterator>::value_type |
226 | _ValueType; | |
f4c5578f PC |
227 | |
228 | std::__uninitialized_fill_n<__is_pod(_ValueType)>:: | |
229 | uninitialized_fill_n(__first, __n, __x); | |
02d92e3b SW |
230 | } |
231 | ||
1985f1cd MA |
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, | |
c531371e | 242 | _ForwardIterator __result, _Allocator& __alloc) |
1985f1cd MA |
243 | { |
244 | _ForwardIterator __cur = __result; | |
bc2631e0 | 245 | __try |
1985f1cd MA |
246 | { |
247 | for (; __first != __last; ++__first, ++__cur) | |
248 | __alloc.construct(&*__cur, *__first); | |
249 | return __cur; | |
250 | } | |
bc2631e0 | 251 | __catch(...) |
1985f1cd MA |
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, | |
c531371e | 261 | _ForwardIterator __result, allocator<_Tp>&) |
8072ddb0 | 262 | { return std::uninitialized_copy(__first, __last, __result); } |
1985f1cd | 263 | |
6eef7402 CJ |
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 | ||
1985f1cd MA |
275 | template<typename _ForwardIterator, typename _Tp, typename _Allocator> |
276 | void | |
277 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, | |
c531371e | 278 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
279 | { |
280 | _ForwardIterator __cur = __first; | |
bc2631e0 | 281 | __try |
1985f1cd MA |
282 | { |
283 | for (; __cur != __last; ++__cur) | |
284 | __alloc.construct(&*__cur, __x); | |
285 | } | |
bc2631e0 | 286 | __catch(...) |
1985f1cd MA |
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, | |
c531371e | 296 | const _Tp& __x, allocator<_Tp2>&) |
8072ddb0 | 297 | { std::uninitialized_fill(__first, __last, __x); } |
1985f1cd MA |
298 | |
299 | template<typename _ForwardIterator, typename _Size, typename _Tp, | |
300 | typename _Allocator> | |
301 | void | |
302 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, | |
c531371e | 303 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
304 | { |
305 | _ForwardIterator __cur = __first; | |
bc2631e0 | 306 | __try |
1985f1cd MA |
307 | { |
308 | for (; __n > 0; --__n, ++__cur) | |
309 | __alloc.construct(&*__cur, __x); | |
310 | } | |
bc2631e0 | 311 | __catch(...) |
1985f1cd MA |
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> | |
8072ddb0 | 320 | inline void |
1985f1cd | 321 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
c531371e | 322 | const _Tp& __x, allocator<_Tp2>&) |
8072ddb0 | 323 | { std::uninitialized_fill_n(__first, __n, __x); } |
1985f1cd MA |
324 | |
325 | ||
7ffec97f CJ |
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. | |
02d92e3b | 330 | |
7ffec97f | 331 | // __uninitialized_copy_move |
02d92e3b | 332 | // Copies [first1, last1) into [result, result + (last1 - first1)), and |
7ffec97f | 333 | // move [first2, last2) into |
02d92e3b | 334 | // [result, result + (last1 - first1) + (last2 - first2)). |
ed6814f7 | 335 | template<typename _InputIterator1, typename _InputIterator2, |
1985f1cd | 336 | typename _ForwardIterator, typename _Allocator> |
08addde6 | 337 | inline _ForwardIterator |
7ffec97f | 338 | __uninitialized_copy_move(_InputIterator1 __first1, |
917a9fd4 | 339 | _InputIterator1 __last1, |
ed6814f7 | 340 | _InputIterator2 __first2, |
917a9fd4 | 341 | _InputIterator2 __last2, |
1985f1cd | 342 | _ForwardIterator __result, |
c531371e | 343 | _Allocator& __alloc) |
02d92e3b | 344 | { |
1985f1cd MA |
345 | _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, |
346 | __result, | |
347 | __alloc); | |
bc2631e0 | 348 | __try |
15d72060 | 349 | { |
7ffec97f | 350 | return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); |
15d72060 | 351 | } |
bc2631e0 | 352 | __catch(...) |
ed6814f7 | 353 | { |
1985f1cd | 354 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 355 | __throw_exception_again; |
322821b9 | 356 | } |
02d92e3b SW |
357 | } |
358 | ||
7ffec97f CJ |
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 | _Allocator& __alloc) | |
372 | { | |
373 | _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, | |
374 | __result, | |
375 | __alloc); | |
bc2631e0 | 376 | __try |
7ffec97f CJ |
377 | { |
378 | return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); | |
379 | } | |
bc2631e0 | 380 | __catch(...) |
7ffec97f CJ |
381 | { |
382 | std::_Destroy(__result, __mid, __alloc); | |
383 | __throw_exception_again; | |
384 | } | |
385 | } | |
386 | ||
387 | // __uninitialized_fill_move | |
388 | // Fills [result, mid) with x, and moves [first, last) into | |
02d92e3b | 389 | // [mid, mid + (last - first)). |
1985f1cd MA |
390 | template<typename _ForwardIterator, typename _Tp, typename _InputIterator, |
391 | typename _Allocator> | |
ed6814f7 | 392 | inline _ForwardIterator |
7ffec97f | 393 | __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, |
15d72060 | 394 | const _Tp& __x, _InputIterator __first, |
c531371e | 395 | _InputIterator __last, _Allocator& __alloc) |
02d92e3b | 396 | { |
1985f1cd | 397 | std::__uninitialized_fill_a(__result, __mid, __x, __alloc); |
bc2631e0 | 398 | __try |
15d72060 | 399 | { |
7ffec97f | 400 | return std::__uninitialized_move_a(__first, __last, __mid, __alloc); |
15d72060 | 401 | } |
bc2631e0 | 402 | __catch(...) |
322821b9 | 403 | { |
1985f1cd | 404 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 405 | __throw_exception_again; |
322821b9 | 406 | } |
02d92e3b SW |
407 | } |
408 | ||
7ffec97f CJ |
409 | // __uninitialized_move_fill |
410 | // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and | |
02d92e3b | 411 | // fills [first2 + (last1 - first1), last2) with x. |
1985f1cd MA |
412 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp, |
413 | typename _Allocator> | |
02d92e3b | 414 | inline void |
7ffec97f | 415 | __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, |
15d72060 | 416 | _ForwardIterator __first2, |
1985f1cd | 417 | _ForwardIterator __last2, const _Tp& __x, |
c531371e | 418 | _Allocator& __alloc) |
02d92e3b | 419 | { |
7ffec97f | 420 | _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, |
1985f1cd MA |
421 | __first2, |
422 | __alloc); | |
bc2631e0 | 423 | __try |
917a9fd4 | 424 | { |
1985f1cd | 425 | std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); |
917a9fd4 | 426 | } |
bc2631e0 | 427 | __catch(...) |
322821b9 | 428 | { |
1985f1cd | 429 | std::_Destroy(__first2, __mid2, __alloc); |
ed6814f7 | 430 | __throw_exception_again; |
322821b9 | 431 | } |
02d92e3b | 432 | } |
725dc051 | 433 | |
b0371776 PC |
434 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ |
435 | template<typename _InputIterator, typename _Size, | |
436 | typename _ForwardIterator> | |
437 | _ForwardIterator | |
438 | __uninitialized_copy_n(_InputIterator __first, _Size __n, | |
439 | _ForwardIterator __result, input_iterator_tag) | |
440 | { | |
441 | _ForwardIterator __cur = __result; | |
bc2631e0 | 442 | __try |
b0371776 PC |
443 | { |
444 | for (; __n > 0; --__n, ++__first, ++__cur) | |
445 | ::new(static_cast<void*>(&*__cur)) typename | |
446 | iterator_traits<_ForwardIterator>::value_type(*__first); | |
447 | return __cur; | |
448 | } | |
bc2631e0 | 449 | __catch(...) |
b0371776 PC |
450 | { |
451 | std::_Destroy(__result, __cur); | |
452 | __throw_exception_again; | |
453 | } | |
454 | } | |
455 | ||
456 | template<typename _RandomAccessIterator, typename _Size, | |
457 | typename _ForwardIterator> | |
458 | inline _ForwardIterator | |
459 | __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, | |
460 | _ForwardIterator __result, | |
461 | random_access_iterator_tag) | |
462 | { return std::uninitialized_copy(__first, __first + __n, __result); } | |
463 | ||
464 | /** | |
465 | * @brief Copies the range [first,first+n) into result. | |
466 | * @param first An input iterator. | |
467 | * @param n The number of elements to copy. | |
468 | * @param result An output iterator. | |
469 | * @return result + n | |
470 | * | |
471 | * Like copy_n(), but does not require an initialized output range. | |
472 | */ | |
473 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> | |
474 | inline _ForwardIterator | |
475 | uninitialized_copy_n(_InputIterator __first, _Size __n, | |
476 | _ForwardIterator __result) | |
477 | { return std::__uninitialized_copy_n(__first, __n, __result, | |
478 | std::__iterator_category(__first)); } | |
479 | #endif | |
480 | ||
3cbc7af0 | 481 | _GLIBCXX_END_NAMESPACE |
725dc051 | 482 | |
3d7c150e | 483 | #endif /* _STL_UNINITIALIZED_H */ |