1 | // Raw memory manipulators -*- C++ -*- |
2 | |
3 | // Copyright (C) 2001-2016 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /* |
26 | * |
27 | * Copyright (c) 1994 |
28 | * Hewlett-Packard Company |
29 | * |
30 | * Permission to use, copy, modify, distribute and sell this software |
31 | * and its documentation for any purpose is hereby granted without fee, |
32 | * provided that the above copyright notice appear in all copies and |
33 | * that both that copyright notice and this permission notice appear |
34 | * in supporting documentation. Hewlett-Packard Company makes no |
35 | * representations about the suitability of this software for any |
36 | * purpose. It is provided "as is" without express or implied warranty. |
37 | * |
38 | * |
39 | * Copyright (c) 1996,1997 |
40 | * Silicon Graphics Computer Systems, Inc. |
41 | * |
42 | * Permission to use, copy, modify, distribute and sell this software |
43 | * and its documentation for any purpose is hereby granted without fee, |
44 | * provided that the above copyright notice appear in all copies and |
45 | * that both that copyright notice and this permission notice appear |
46 | * in supporting documentation. Silicon Graphics makes no |
47 | * representations about the suitability of this software for any |
48 | * purpose. It is provided "as is" without express or implied warranty. |
49 | */ |
50 | |
51 | /** @file bits/stl_uninitialized.h |
52 | * This is an internal header file, included by other library headers. |
53 | * Do not attempt to use it directly. @headername{memory} |
54 | */ |
55 | |
56 | #ifndef _STL_UNINITIALIZED_H |
57 | #define _STL_UNINITIALIZED_H 1 |
58 | |
59 | namespace std _GLIBCXX_VISIBILITY(default) |
60 | { |
61 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
62 | |
63 | template<bool _TrivialValueTypes> |
64 | struct __uninitialized_copy |
65 | { |
66 | template<typename _InputIterator, typename _ForwardIterator> |
67 | static _ForwardIterator |
68 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
69 | _ForwardIterator __result) |
70 | { |
71 | _ForwardIterator __cur = __result; |
72 | __try |
73 | { |
74 | for (; __first != __last; ++__first, (void)++__cur) |
75 | std::_Construct(std::__addressof(*__cur), *__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 | __uninit_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 | #if __cplusplus < 201103L |
115 | const bool __assignable = true; |
116 | #else |
117 | // trivial types can have deleted assignment |
118 | typedef typename iterator_traits<_InputIterator>::reference _RefType1; |
119 | typedef typename iterator_traits<_ForwardIterator>::reference _RefType2; |
120 | const bool __assignable = is_assignable<_RefType2, _RefType1>::value; |
121 | #endif |
122 | |
123 | return std::__uninitialized_copy<__is_trivial(_ValueType1) |
124 | && __is_trivial(_ValueType2) |
125 | && __assignable>:: |
126 | __uninit_copy(__first, __last, __result); |
127 | } |
128 | |
129 | |
130 | template<bool _TrivialValueType> |
131 | struct __uninitialized_fill |
132 | { |
133 | template<typename _ForwardIterator, typename _Tp> |
134 | static void |
135 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
136 | const _Tp& __x) |
137 | { |
138 | _ForwardIterator __cur = __first; |
139 | __try |
140 | { |
141 | for (; __cur != __last; ++__cur) |
142 | std::_Construct(std::__addressof(*__cur), __x); |
143 | } |
144 | __catch(...) |
145 | { |
146 | std::_Destroy(__first, __cur); |
147 | __throw_exception_again; |
148 | } |
149 | } |
150 | }; |
151 | |
152 | template<> |
153 | struct __uninitialized_fill<true> |
154 | { |
155 | template<typename _ForwardIterator, typename _Tp> |
156 | static void |
157 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
158 | const _Tp& __x) |
159 | { std::fill(__first, __last, __x); } |
160 | }; |
161 | |
162 | /** |
163 | * @brief Copies the value x into the range [first,last). |
164 | * @param __first An input iterator. |
165 | * @param __last An input iterator. |
166 | * @param __x The source value. |
167 | * @return Nothing. |
168 | * |
169 | * Like fill(), but does not require an initialized output range. |
170 | */ |
171 | template<typename _ForwardIterator, typename _Tp> |
172 | inline void |
173 | uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, |
174 | const _Tp& __x) |
175 | { |
176 | typedef typename iterator_traits<_ForwardIterator>::value_type |
177 | _ValueType; |
178 | #if __cplusplus < 201103L |
179 | const bool __assignable = true; |
180 | #else |
181 | // trivial types can have deleted assignment |
182 | const bool __assignable = is_copy_assignable<_ValueType>::value; |
183 | #endif |
184 | |
185 | std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: |
186 | __uninit_fill(__first, __last, __x); |
187 | } |
188 | |
189 | |
190 | template<bool _TrivialValueType> |
191 | struct __uninitialized_fill_n |
192 | { |
193 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
194 | static _ForwardIterator |
195 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
196 | const _Tp& __x) |
197 | { |
198 | _ForwardIterator __cur = __first; |
199 | __try |
200 | { |
201 | for (; __n > 0; --__n, ++__cur) |
202 | std::_Construct(std::__addressof(*__cur), __x); |
203 | return __cur; |
204 | } |
205 | __catch(...) |
206 | { |
207 | std::_Destroy(__first, __cur); |
208 | __throw_exception_again; |
209 | } |
210 | } |
211 | }; |
212 | |
213 | template<> |
214 | struct __uninitialized_fill_n<true> |
215 | { |
216 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
217 | static _ForwardIterator |
218 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
219 | const _Tp& __x) |
220 | { return std::fill_n(__first, __n, __x); } |
221 | }; |
222 | |
223 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
224 | // DR 1339. uninitialized_fill_n should return the end of its range |
225 | /** |
226 | * @brief Copies the value x into the range [first,first+n). |
227 | * @param __first An input iterator. |
228 | * @param __n The number of copies to make. |
229 | * @param __x The source value. |
230 | * @return Nothing. |
231 | * |
232 | * Like fill_n(), but does not require an initialized output range. |
233 | */ |
234 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
235 | inline _ForwardIterator |
236 | uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) |
237 | { |
238 | typedef typename iterator_traits<_ForwardIterator>::value_type |
239 | _ValueType; |
240 | #if __cplusplus < 201103L |
241 | const bool __assignable = true; |
242 | #else |
243 | // trivial types can have deleted assignment |
244 | const bool __assignable = is_copy_assignable<_ValueType>::value; |
245 | #endif |
246 | return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: |
247 | __uninit_fill_n(__first, __n, __x); |
248 | } |
249 | |
250 | // Extensions: versions of uninitialized_copy, uninitialized_fill, |
251 | // and uninitialized_fill_n that take an allocator parameter. |
252 | // We dispatch back to the standard versions when we're given the |
253 | // default allocator. For nondefault allocators we do not use |
254 | // any of the POD optimizations. |
255 | |
256 | template<typename _InputIterator, typename _ForwardIterator, |
257 | typename _Allocator> |
258 | _ForwardIterator |
259 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, |
260 | _ForwardIterator __result, _Allocator& __alloc) |
261 | { |
262 | _ForwardIterator __cur = __result; |
263 | __try |
264 | { |
265 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
266 | for (; __first != __last; ++__first, (void)++__cur) |
267 | __traits::construct(__alloc, std::__addressof(*__cur), *__first); |
268 | return __cur; |
269 | } |
270 | __catch(...) |
271 | { |
272 | std::_Destroy(__result, __cur, __alloc); |
273 | __throw_exception_again; |
274 | } |
275 | } |
276 | |
277 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp> |
278 | inline _ForwardIterator |
279 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, |
280 | _ForwardIterator __result, allocator<_Tp>&) |
281 | { return std::uninitialized_copy(__first, __last, __result); } |
282 | |
283 | template<typename _InputIterator, typename _ForwardIterator, |
284 | typename _Allocator> |
285 | inline _ForwardIterator |
286 | __uninitialized_move_a(_InputIterator __first, _InputIterator __last, |
287 | _ForwardIterator __result, _Allocator& __alloc) |
288 | { |
289 | return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), |
290 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), |
291 | __result, __alloc); |
292 | } |
293 | |
294 | template<typename _InputIterator, typename _ForwardIterator, |
295 | typename _Allocator> |
296 | inline _ForwardIterator |
297 | __uninitialized_move_if_noexcept_a(_InputIterator __first, |
298 | _InputIterator __last, |
299 | _ForwardIterator __result, |
300 | _Allocator& __alloc) |
301 | { |
302 | return std::__uninitialized_copy_a |
303 | (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), |
304 | _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); |
305 | } |
306 | |
307 | template<typename _ForwardIterator, typename _Tp, typename _Allocator> |
308 | void |
309 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, |
310 | const _Tp& __x, _Allocator& __alloc) |
311 | { |
312 | _ForwardIterator __cur = __first; |
313 | __try |
314 | { |
315 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
316 | for (; __cur != __last; ++__cur) |
317 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
318 | } |
319 | __catch(...) |
320 | { |
321 | std::_Destroy(__first, __cur, __alloc); |
322 | __throw_exception_again; |
323 | } |
324 | } |
325 | |
326 | template<typename _ForwardIterator, typename _Tp, typename _Tp2> |
327 | inline void |
328 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, |
329 | const _Tp& __x, allocator<_Tp2>&) |
330 | { std::uninitialized_fill(__first, __last, __x); } |
331 | |
332 | template<typename _ForwardIterator, typename _Size, typename _Tp, |
333 | typename _Allocator> |
334 | _ForwardIterator |
335 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
336 | const _Tp& __x, _Allocator& __alloc) |
337 | { |
338 | _ForwardIterator __cur = __first; |
339 | __try |
340 | { |
341 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
342 | for (; __n > 0; --__n, ++__cur) |
343 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
344 | return __cur; |
345 | } |
346 | __catch(...) |
347 | { |
348 | std::_Destroy(__first, __cur, __alloc); |
349 | __throw_exception_again; |
350 | } |
351 | } |
352 | |
353 | template<typename _ForwardIterator, typename _Size, typename _Tp, |
354 | typename _Tp2> |
355 | inline _ForwardIterator |
356 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
357 | const _Tp& __x, allocator<_Tp2>&) |
358 | { return std::uninitialized_fill_n(__first, __n, __x); } |
359 | |
360 | |
361 | // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, |
362 | // __uninitialized_fill_move, __uninitialized_move_fill. |
363 | // All of these algorithms take a user-supplied allocator, which is used |
364 | // for construction and destruction. |
365 | |
366 | // __uninitialized_copy_move |
367 | // Copies [first1, last1) into [result, result + (last1 - first1)), and |
368 | // move [first2, last2) into |
369 | // [result, result + (last1 - first1) + (last2 - first2)). |
370 | template<typename _InputIterator1, typename _InputIterator2, |
371 | typename _ForwardIterator, typename _Allocator> |
372 | inline _ForwardIterator |
373 | __uninitialized_copy_move(_InputIterator1 __first1, |
374 | _InputIterator1 __last1, |
375 | _InputIterator2 __first2, |
376 | _InputIterator2 __last2, |
377 | _ForwardIterator __result, |
378 | _Allocator& __alloc) |
379 | { |
380 | _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, |
381 | __result, |
382 | __alloc); |
383 | __try |
384 | { |
385 | return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); |
386 | } |
387 | __catch(...) |
388 | { |
389 | std::_Destroy(__result, __mid, __alloc); |
390 | __throw_exception_again; |
391 | } |
392 | } |
393 | |
394 | // __uninitialized_move_copy |
395 | // Moves [first1, last1) into [result, result + (last1 - first1)), and |
396 | // copies [first2, last2) into |
397 | // [result, result + (last1 - first1) + (last2 - first2)). |
398 | template<typename _InputIterator1, typename _InputIterator2, |
399 | typename _ForwardIterator, typename _Allocator> |
400 | inline _ForwardIterator |
401 | __uninitialized_move_copy(_InputIterator1 __first1, |
402 | _InputIterator1 __last1, |
403 | _InputIterator2 __first2, |
404 | _InputIterator2 __last2, |
405 | _ForwardIterator __result, |
406 | _Allocator& __alloc) |
407 | { |
408 | _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, |
409 | __result, |
410 | __alloc); |
411 | __try |
412 | { |
413 | return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); |
414 | } |
415 | __catch(...) |
416 | { |
417 | std::_Destroy(__result, __mid, __alloc); |
418 | __throw_exception_again; |
419 | } |
420 | } |
421 | |
422 | // __uninitialized_fill_move |
423 | // Fills [result, mid) with x, and moves [first, last) into |
424 | // [mid, mid + (last - first)). |
425 | template<typename _ForwardIterator, typename _Tp, typename _InputIterator, |
426 | typename _Allocator> |
427 | inline _ForwardIterator |
428 | __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, |
429 | const _Tp& __x, _InputIterator __first, |
430 | _InputIterator __last, _Allocator& __alloc) |
431 | { |
432 | std::__uninitialized_fill_a(__result, __mid, __x, __alloc); |
433 | __try |
434 | { |
435 | return std::__uninitialized_move_a(__first, __last, __mid, __alloc); |
436 | } |
437 | __catch(...) |
438 | { |
439 | std::_Destroy(__result, __mid, __alloc); |
440 | __throw_exception_again; |
441 | } |
442 | } |
443 | |
444 | // __uninitialized_move_fill |
445 | // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and |
446 | // fills [first2 + (last1 - first1), last2) with x. |
447 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp, |
448 | typename _Allocator> |
449 | inline void |
450 | __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, |
451 | _ForwardIterator __first2, |
452 | _ForwardIterator __last2, const _Tp& __x, |
453 | _Allocator& __alloc) |
454 | { |
455 | _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, |
456 | __first2, |
457 | __alloc); |
458 | __try |
459 | { |
460 | std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); |
461 | } |
462 | __catch(...) |
463 | { |
464 | std::_Destroy(__first2, __mid2, __alloc); |
465 | __throw_exception_again; |
466 | } |
467 | } |
468 | |
469 | #if __cplusplus >= 201103L |
470 | // Extensions: __uninitialized_default, __uninitialized_default_n, |
471 | // __uninitialized_default_a, __uninitialized_default_n_a. |
472 | |
473 | template<bool _TrivialValueType> |
474 | struct __uninitialized_default_1 |
475 | { |
476 | template<typename _ForwardIterator> |
477 | static void |
478 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) |
479 | { |
480 | _ForwardIterator __cur = __first; |
481 | __try |
482 | { |
483 | for (; __cur != __last; ++__cur) |
484 | std::_Construct(std::__addressof(*__cur)); |
485 | } |
486 | __catch(...) |
487 | { |
488 | std::_Destroy(__first, __cur); |
489 | __throw_exception_again; |
490 | } |
491 | } |
492 | }; |
493 | |
494 | template<> |
495 | struct __uninitialized_default_1<true> |
496 | { |
497 | template<typename _ForwardIterator> |
498 | static void |
499 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) |
500 | { |
501 | typedef typename iterator_traits<_ForwardIterator>::value_type |
502 | _ValueType; |
503 | |
504 | std::fill(__first, __last, _ValueType()); |
505 | } |
506 | }; |
507 | |
508 | template<bool _TrivialValueType> |
509 | struct __uninitialized_default_n_1 |
510 | { |
511 | template<typename _ForwardIterator, typename _Size> |
512 | static _ForwardIterator |
513 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
514 | { |
515 | _ForwardIterator __cur = __first; |
516 | __try |
517 | { |
518 | for (; __n > 0; --__n, ++__cur) |
519 | std::_Construct(std::__addressof(*__cur)); |
520 | return __cur; |
521 | } |
522 | __catch(...) |
523 | { |
524 | std::_Destroy(__first, __cur); |
525 | __throw_exception_again; |
526 | } |
527 | } |
528 | }; |
529 | |
530 | template<> |
531 | struct __uninitialized_default_n_1<true> |
532 | { |
533 | template<typename _ForwardIterator, typename _Size> |
534 | static _ForwardIterator |
535 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
536 | { |
537 | typedef typename iterator_traits<_ForwardIterator>::value_type |
538 | _ValueType; |
539 | |
540 | return std::fill_n(__first, __n, _ValueType()); |
541 | } |
542 | }; |
543 | |
544 | // __uninitialized_default |
545 | // Fills [first, last) with std::distance(first, last) default |
546 | // constructed value_types(s). |
547 | template<typename _ForwardIterator> |
548 | inline void |
549 | __uninitialized_default(_ForwardIterator __first, |
550 | _ForwardIterator __last) |
551 | { |
552 | typedef typename iterator_traits<_ForwardIterator>::value_type |
553 | _ValueType; |
554 | // trivial types can have deleted assignment |
555 | const bool __assignable = is_copy_assignable<_ValueType>::value; |
556 | |
557 | std::__uninitialized_default_1<__is_trivial(_ValueType) |
558 | && __assignable>:: |
559 | __uninit_default(__first, __last); |
560 | } |
561 | |
562 | // __uninitialized_default_n |
563 | // Fills [first, first + n) with n default constructed value_type(s). |
564 | template<typename _ForwardIterator, typename _Size> |
565 | inline _ForwardIterator |
566 | __uninitialized_default_n(_ForwardIterator __first, _Size __n) |
567 | { |
568 | typedef typename iterator_traits<_ForwardIterator>::value_type |
569 | _ValueType; |
570 | // trivial types can have deleted assignment |
571 | const bool __assignable = is_copy_assignable<_ValueType>::value; |
572 | |
573 | return __uninitialized_default_n_1<__is_trivial(_ValueType) |
574 | && __assignable>:: |
575 | __uninit_default_n(__first, __n); |
576 | } |
577 | |
578 | |
579 | // __uninitialized_default_a |
580 | // Fills [first, last) with std::distance(first, last) default |
581 | // constructed value_types(s), constructed with the allocator alloc. |
582 | template<typename _ForwardIterator, typename _Allocator> |
583 | void |
584 | __uninitialized_default_a(_ForwardIterator __first, |
585 | _ForwardIterator __last, |
586 | _Allocator& __alloc) |
587 | { |
588 | _ForwardIterator __cur = __first; |
589 | __try |
590 | { |
591 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
592 | for (; __cur != __last; ++__cur) |
593 | __traits::construct(__alloc, std::__addressof(*__cur)); |
594 | } |
595 | __catch(...) |
596 | { |
597 | std::_Destroy(__first, __cur, __alloc); |
598 | __throw_exception_again; |
599 | } |
600 | } |
601 | |
602 | template<typename _ForwardIterator, typename _Tp> |
603 | inline void |
604 | __uninitialized_default_a(_ForwardIterator __first, |
605 | _ForwardIterator __last, |
606 | allocator<_Tp>&) |
607 | { std::__uninitialized_default(__first, __last); } |
608 | |
609 | |
610 | // __uninitialized_default_n_a |
611 | // Fills [first, first + n) with n default constructed value_types(s), |
612 | // constructed with the allocator alloc. |
613 | template<typename _ForwardIterator, typename _Size, typename _Allocator> |
614 | _ForwardIterator |
615 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
616 | _Allocator& __alloc) |
617 | { |
618 | _ForwardIterator __cur = __first; |
619 | __try |
620 | { |
621 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
622 | for (; __n > 0; --__n, ++__cur) |
623 | __traits::construct(__alloc, std::__addressof(*__cur)); |
624 | return __cur; |
625 | } |
626 | __catch(...) |
627 | { |
628 | std::_Destroy(__first, __cur, __alloc); |
629 | __throw_exception_again; |
630 | } |
631 | } |
632 | |
633 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
634 | inline _ForwardIterator |
635 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
636 | allocator<_Tp>&) |
637 | { return std::__uninitialized_default_n(__first, __n); } |
638 | |
639 | |
640 | template<typename _InputIterator, typename _Size, |
641 | typename _ForwardIterator> |
642 | _ForwardIterator |
643 | __uninitialized_copy_n(_InputIterator __first, _Size __n, |
644 | _ForwardIterator __result, input_iterator_tag) |
645 | { |
646 | _ForwardIterator __cur = __result; |
647 | __try |
648 | { |
649 | for (; __n > 0; --__n, ++__first, ++__cur) |
650 | std::_Construct(std::__addressof(*__cur), *__first); |
651 | return __cur; |
652 | } |
653 | __catch(...) |
654 | { |
655 | std::_Destroy(__result, __cur); |
656 | __throw_exception_again; |
657 | } |
658 | } |
659 | |
660 | template<typename _RandomAccessIterator, typename _Size, |
661 | typename _ForwardIterator> |
662 | inline _ForwardIterator |
663 | __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, |
664 | _ForwardIterator __result, |
665 | random_access_iterator_tag) |
666 | { return std::uninitialized_copy(__first, __first + __n, __result); } |
667 | |
668 | /** |
669 | * @brief Copies the range [first,first+n) into result. |
670 | * @param __first An input iterator. |
671 | * @param __n The number of elements to copy. |
672 | * @param __result An output iterator. |
673 | * @return __result + __n |
674 | * |
675 | * Like copy_n(), but does not require an initialized output range. |
676 | */ |
677 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> |
678 | inline _ForwardIterator |
679 | uninitialized_copy_n(_InputIterator __first, _Size __n, |
680 | _ForwardIterator __result) |
681 | { return std::__uninitialized_copy_n(__first, __n, __result, |
682 | std::__iterator_category(__first)); } |
683 | #endif |
684 | |
685 | _GLIBCXX_END_NAMESPACE_VERSION |
686 | } // namespace |
687 | |
688 | #endif /* _STL_UNINITIALIZED_H */ |
689 | |