]>
Commit | Line | Data |
---|---|---|
42526146 PE |
1 | // Raw memory manipulators -*- C++ -*- |
2 | ||
5624e564 | 3 | // Copyright (C) 2001-2015 Free Software Foundation, Inc. |
42526146 PE |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
42526146 PE |
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 | ||
748086b7 JJ |
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. | |
42526146 | 19 | |
748086b7 JJ |
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/>. | |
42526146 | 24 | |
725dc051 BK |
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 | ||
f910786b | 51 | /** @file bits/stl_uninitialized.h |
729e3d3f | 52 | * This is an internal header file, included by other library headers. |
f910786b | 53 | * Do not attempt to use it directly. @headername{memory} |
725dc051 BK |
54 | */ |
55 | ||
3d7c150e BK |
56 | #ifndef _STL_UNINITIALIZED_H |
57 | #define _STL_UNINITIALIZED_H 1 | |
725dc051 | 58 | |
12ffa228 BK |
59 | namespace std _GLIBCXX_VISIBILITY(default) |
60 | { | |
61 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 62 | |
cc86c05a | 63 | template<bool _TrivialValueTypes> |
f4c5578f | 64 | struct __uninitialized_copy |
02d92e3b | 65 | { |
f4c5578f PC |
66 | template<typename _InputIterator, typename _ForwardIterator> |
67 | static _ForwardIterator | |
cc86c05a PC |
68 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
69 | _ForwardIterator __result) | |
f4c5578f PC |
70 | { |
71 | _ForwardIterator __cur = __result; | |
bc2631e0 | 72 | __try |
f4c5578f PC |
73 | { |
74 | for (; __first != __last; ++__first, ++__cur) | |
882b3d5c | 75 | std::_Construct(std::__addressof(*__cur), *__first); |
f4c5578f PC |
76 | return __cur; |
77 | } | |
bc2631e0 | 78 | __catch(...) |
f4c5578f PC |
79 | { |
80 | std::_Destroy(__result, __cur); | |
81 | __throw_exception_again; | |
82 | } | |
322821b9 | 83 | } |
f4c5578f PC |
84 | }; |
85 | ||
86 | template<> | |
87 | struct __uninitialized_copy<true> | |
88 | { | |
89 | template<typename _InputIterator, typename _ForwardIterator> | |
90 | static _ForwardIterator | |
cc86c05a PC |
91 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
92 | _ForwardIterator __result) | |
f4c5578f PC |
93 | { return std::copy(__first, __last, __result); } |
94 | }; | |
02d92e3b | 95 | |
82b61df5 PE |
96 | /** |
97 | * @brief Copies the range [first,last) into result. | |
93c66bc6 BK |
98 | * @param __first An input iterator. |
99 | * @param __last An input iterator. | |
100 | * @param __result An output iterator. | |
101 | * @return __result + (__first - __last) | |
82b61df5 PE |
102 | * |
103 | * Like copy(), but does not require an initialized output range. | |
104 | */ | |
08addde6 PE |
105 | template<typename _InputIterator, typename _ForwardIterator> |
106 | inline _ForwardIterator | |
ed6814f7 | 107 | uninitialized_copy(_InputIterator __first, _InputIterator __last, |
917a9fd4 | 108 | _ForwardIterator __result) |
02d92e3b | 109 | { |
f4c5578f PC |
110 | typedef typename iterator_traits<_InputIterator>::value_type |
111 | _ValueType1; | |
ff2ea587 | 112 | typedef typename iterator_traits<_ForwardIterator>::value_type |
f4c5578f | 113 | _ValueType2; |
5275f3e5 JW |
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 _RefType; | |
119 | const bool __assignable = is_assignable<_ValueType1, _RefType>::value; | |
120 | #endif | |
121 | ||
122 | return std::__uninitialized_copy<__is_trivial(_ValueType1) | |
123 | && __is_trivial(_ValueType2) | |
124 | && __assignable>:: | |
cc86c05a | 125 | __uninit_copy(__first, __last, __result); |
02d92e3b SW |
126 | } |
127 | ||
02d92e3b | 128 | |
cc86c05a | 129 | template<bool _TrivialValueType> |
f4c5578f | 130 | struct __uninitialized_fill |
02d92e3b | 131 | { |
f4c5578f PC |
132 | template<typename _ForwardIterator, typename _Tp> |
133 | static void | |
cc86c05a PC |
134 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
135 | const _Tp& __x) | |
f4c5578f PC |
136 | { |
137 | _ForwardIterator __cur = __first; | |
bc2631e0 | 138 | __try |
f4c5578f PC |
139 | { |
140 | for (; __cur != __last; ++__cur) | |
882b3d5c | 141 | std::_Construct(std::__addressof(*__cur), __x); |
f4c5578f | 142 | } |
bc2631e0 | 143 | __catch(...) |
f4c5578f PC |
144 | { |
145 | std::_Destroy(__first, __cur); | |
146 | __throw_exception_again; | |
147 | } | |
15d72060 | 148 | } |
f4c5578f PC |
149 | }; |
150 | ||
151 | template<> | |
152 | struct __uninitialized_fill<true> | |
153 | { | |
154 | template<typename _ForwardIterator, typename _Tp> | |
155 | static void | |
cc86c05a PC |
156 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
157 | const _Tp& __x) | |
f4c5578f PC |
158 | { std::fill(__first, __last, __x); } |
159 | }; | |
02d92e3b | 160 | |
82b61df5 PE |
161 | /** |
162 | * @brief Copies the value x into the range [first,last). | |
93c66bc6 BK |
163 | * @param __first An input iterator. |
164 | * @param __last An input iterator. | |
165 | * @param __x The source value. | |
82b61df5 PE |
166 | * @return Nothing. |
167 | * | |
168 | * Like fill(), but does not require an initialized output range. | |
169 | */ | |
08addde6 | 170 | template<typename _ForwardIterator, typename _Tp> |
02d92e3b | 171 | inline void |
ed6814f7 | 172 | uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, |
917a9fd4 | 173 | const _Tp& __x) |
02d92e3b | 174 | { |
ff2ea587 PC |
175 | typedef typename iterator_traits<_ForwardIterator>::value_type |
176 | _ValueType; | |
5275f3e5 JW |
177 | #if __cplusplus < 201103L |
178 | const bool __assignable = true; | |
179 | #else | |
180 | // trivial types can have deleted assignment | |
181 | const bool __assignable = is_copy_assignable<_ValueType>::value; | |
182 | #endif | |
183 | ||
184 | std::__uninitialized_fill<__is_trivial(_ValueType) && __assignable>:: | |
cc86c05a | 185 | __uninit_fill(__first, __last, __x); |
02d92e3b SW |
186 | } |
187 | ||
02d92e3b | 188 | |
cc86c05a | 189 | template<bool _TrivialValueType> |
f4c5578f | 190 | struct __uninitialized_fill_n |
02d92e3b | 191 | { |
f4c5578f | 192 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
e51cf2f5 | 193 | static _ForwardIterator |
cc86c05a PC |
194 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
195 | const _Tp& __x) | |
f4c5578f PC |
196 | { |
197 | _ForwardIterator __cur = __first; | |
bc2631e0 | 198 | __try |
f4c5578f PC |
199 | { |
200 | for (; __n > 0; --__n, ++__cur) | |
882b3d5c | 201 | std::_Construct(std::__addressof(*__cur), __x); |
e51cf2f5 | 202 | return __cur; |
f4c5578f | 203 | } |
bc2631e0 | 204 | __catch(...) |
f4c5578f PC |
205 | { |
206 | std::_Destroy(__first, __cur); | |
207 | __throw_exception_again; | |
208 | } | |
322821b9 | 209 | } |
f4c5578f PC |
210 | }; |
211 | ||
212 | template<> | |
213 | struct __uninitialized_fill_n<true> | |
214 | { | |
215 | template<typename _ForwardIterator, typename _Size, typename _Tp> | |
e51cf2f5 | 216 | static _ForwardIterator |
cc86c05a PC |
217 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
218 | const _Tp& __x) | |
e51cf2f5 | 219 | { return std::fill_n(__first, __n, __x); } |
f4c5578f | 220 | }; |
02d92e3b | 221 | |
e51cf2f5 JW |
222 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
223 | // DR 1339. uninitialized_fill_n should return the end of its range | |
82b61df5 PE |
224 | /** |
225 | * @brief Copies the value x into the range [first,first+n). | |
93c66bc6 BK |
226 | * @param __first An input iterator. |
227 | * @param __n The number of copies to make. | |
228 | * @param __x The source value. | |
368b7a30 | 229 | * @return Nothing. |
82b61df5 PE |
230 | * |
231 | * Like fill_n(), but does not require an initialized output range. | |
232 | */ | |
08addde6 | 233 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
e51cf2f5 | 234 | inline _ForwardIterator |
08addde6 | 235 | uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) |
02d92e3b | 236 | { |
ff2ea587 PC |
237 | typedef typename iterator_traits<_ForwardIterator>::value_type |
238 | _ValueType; | |
5275f3e5 JW |
239 | #if __cplusplus < 201103L |
240 | const bool __assignable = true; | |
241 | #else | |
242 | // trivial types can have deleted assignment | |
243 | const bool __assignable = is_copy_assignable<_ValueType>::value; | |
244 | #endif | |
e51cf2f5 | 245 | return __uninitialized_fill_n<__is_trivial(_ValueType) && __assignable>:: |
cc86c05a | 246 | __uninit_fill_n(__first, __n, __x); |
02d92e3b SW |
247 | } |
248 | ||
1985f1cd MA |
249 | // Extensions: versions of uninitialized_copy, uninitialized_fill, |
250 | // and uninitialized_fill_n that take an allocator parameter. | |
251 | // We dispatch back to the standard versions when we're given the | |
252 | // default allocator. For nondefault allocators we do not use | |
253 | // any of the POD optimizations. | |
254 | ||
255 | template<typename _InputIterator, typename _ForwardIterator, | |
256 | typename _Allocator> | |
257 | _ForwardIterator | |
258 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, | |
c531371e | 259 | _ForwardIterator __result, _Allocator& __alloc) |
1985f1cd MA |
260 | { |
261 | _ForwardIterator __cur = __result; | |
bc2631e0 | 262 | __try |
1985f1cd | 263 | { |
e8eb60bd | 264 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
1985f1cd | 265 | for (; __first != __last; ++__first, ++__cur) |
e8eb60bd | 266 | __traits::construct(__alloc, std::__addressof(*__cur), *__first); |
1985f1cd MA |
267 | return __cur; |
268 | } | |
bc2631e0 | 269 | __catch(...) |
1985f1cd MA |
270 | { |
271 | std::_Destroy(__result, __cur, __alloc); | |
272 | __throw_exception_again; | |
273 | } | |
274 | } | |
275 | ||
276 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp> | |
277 | inline _ForwardIterator | |
278 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, | |
c531371e | 279 | _ForwardIterator __result, allocator<_Tp>&) |
8072ddb0 | 280 | { return std::uninitialized_copy(__first, __last, __result); } |
1985f1cd | 281 | |
6eef7402 CJ |
282 | template<typename _InputIterator, typename _ForwardIterator, |
283 | typename _Allocator> | |
284 | inline _ForwardIterator | |
285 | __uninitialized_move_a(_InputIterator __first, _InputIterator __last, | |
286 | _ForwardIterator __result, _Allocator& __alloc) | |
287 | { | |
288 | return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), | |
289 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), | |
290 | __result, __alloc); | |
291 | } | |
292 | ||
74a2a1b4 PC |
293 | template<typename _InputIterator, typename _ForwardIterator, |
294 | typename _Allocator> | |
295 | inline _ForwardIterator | |
296 | __uninitialized_move_if_noexcept_a(_InputIterator __first, | |
297 | _InputIterator __last, | |
298 | _ForwardIterator __result, | |
299 | _Allocator& __alloc) | |
300 | { | |
301 | return std::__uninitialized_copy_a | |
302 | (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), | |
303 | _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); | |
304 | } | |
305 | ||
1985f1cd MA |
306 | template<typename _ForwardIterator, typename _Tp, typename _Allocator> |
307 | void | |
308 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, | |
c531371e | 309 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
310 | { |
311 | _ForwardIterator __cur = __first; | |
bc2631e0 | 312 | __try |
1985f1cd | 313 | { |
e8eb60bd | 314 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
1985f1cd | 315 | for (; __cur != __last; ++__cur) |
e8eb60bd | 316 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
1985f1cd | 317 | } |
bc2631e0 | 318 | __catch(...) |
1985f1cd MA |
319 | { |
320 | std::_Destroy(__first, __cur, __alloc); | |
321 | __throw_exception_again; | |
322 | } | |
323 | } | |
324 | ||
325 | template<typename _ForwardIterator, typename _Tp, typename _Tp2> | |
326 | inline void | |
327 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, | |
c531371e | 328 | const _Tp& __x, allocator<_Tp2>&) |
8072ddb0 | 329 | { std::uninitialized_fill(__first, __last, __x); } |
1985f1cd MA |
330 | |
331 | template<typename _ForwardIterator, typename _Size, typename _Tp, | |
332 | typename _Allocator> | |
e51cf2f5 | 333 | _ForwardIterator |
1985f1cd | 334 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
c531371e | 335 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
336 | { |
337 | _ForwardIterator __cur = __first; | |
bc2631e0 | 338 | __try |
1985f1cd | 339 | { |
e8eb60bd | 340 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
1985f1cd | 341 | for (; __n > 0; --__n, ++__cur) |
e8eb60bd | 342 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
e51cf2f5 | 343 | return __cur; |
1985f1cd | 344 | } |
bc2631e0 | 345 | __catch(...) |
1985f1cd MA |
346 | { |
347 | std::_Destroy(__first, __cur, __alloc); | |
348 | __throw_exception_again; | |
349 | } | |
350 | } | |
351 | ||
352 | template<typename _ForwardIterator, typename _Size, typename _Tp, | |
353 | typename _Tp2> | |
e51cf2f5 | 354 | inline _ForwardIterator |
1985f1cd | 355 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
c531371e | 356 | const _Tp& __x, allocator<_Tp2>&) |
e51cf2f5 | 357 | { return std::uninitialized_fill_n(__first, __n, __x); } |
1985f1cd MA |
358 | |
359 | ||
7ffec97f CJ |
360 | // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, |
361 | // __uninitialized_fill_move, __uninitialized_move_fill. | |
362 | // All of these algorithms take a user-supplied allocator, which is used | |
363 | // for construction and destruction. | |
02d92e3b | 364 | |
7ffec97f | 365 | // __uninitialized_copy_move |
02d92e3b | 366 | // Copies [first1, last1) into [result, result + (last1 - first1)), and |
7ffec97f | 367 | // move [first2, last2) into |
02d92e3b | 368 | // [result, result + (last1 - first1) + (last2 - first2)). |
ed6814f7 | 369 | template<typename _InputIterator1, typename _InputIterator2, |
1985f1cd | 370 | typename _ForwardIterator, typename _Allocator> |
08addde6 | 371 | inline _ForwardIterator |
7ffec97f | 372 | __uninitialized_copy_move(_InputIterator1 __first1, |
917a9fd4 | 373 | _InputIterator1 __last1, |
ed6814f7 | 374 | _InputIterator2 __first2, |
917a9fd4 | 375 | _InputIterator2 __last2, |
1985f1cd | 376 | _ForwardIterator __result, |
c531371e | 377 | _Allocator& __alloc) |
02d92e3b | 378 | { |
1985f1cd MA |
379 | _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, |
380 | __result, | |
381 | __alloc); | |
bc2631e0 | 382 | __try |
15d72060 | 383 | { |
7ffec97f | 384 | return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); |
15d72060 | 385 | } |
bc2631e0 | 386 | __catch(...) |
ed6814f7 | 387 | { |
1985f1cd | 388 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 389 | __throw_exception_again; |
322821b9 | 390 | } |
02d92e3b SW |
391 | } |
392 | ||
7ffec97f CJ |
393 | // __uninitialized_move_copy |
394 | // Moves [first1, last1) into [result, result + (last1 - first1)), and | |
395 | // copies [first2, last2) into | |
396 | // [result, result + (last1 - first1) + (last2 - first2)). | |
397 | template<typename _InputIterator1, typename _InputIterator2, | |
398 | typename _ForwardIterator, typename _Allocator> | |
399 | inline _ForwardIterator | |
400 | __uninitialized_move_copy(_InputIterator1 __first1, | |
401 | _InputIterator1 __last1, | |
402 | _InputIterator2 __first2, | |
403 | _InputIterator2 __last2, | |
404 | _ForwardIterator __result, | |
405 | _Allocator& __alloc) | |
406 | { | |
407 | _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, | |
408 | __result, | |
409 | __alloc); | |
bc2631e0 | 410 | __try |
7ffec97f CJ |
411 | { |
412 | return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); | |
413 | } | |
bc2631e0 | 414 | __catch(...) |
7ffec97f CJ |
415 | { |
416 | std::_Destroy(__result, __mid, __alloc); | |
417 | __throw_exception_again; | |
418 | } | |
419 | } | |
420 | ||
421 | // __uninitialized_fill_move | |
422 | // Fills [result, mid) with x, and moves [first, last) into | |
02d92e3b | 423 | // [mid, mid + (last - first)). |
1985f1cd MA |
424 | template<typename _ForwardIterator, typename _Tp, typename _InputIterator, |
425 | typename _Allocator> | |
ed6814f7 | 426 | inline _ForwardIterator |
7ffec97f | 427 | __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, |
15d72060 | 428 | const _Tp& __x, _InputIterator __first, |
c531371e | 429 | _InputIterator __last, _Allocator& __alloc) |
02d92e3b | 430 | { |
1985f1cd | 431 | std::__uninitialized_fill_a(__result, __mid, __x, __alloc); |
bc2631e0 | 432 | __try |
15d72060 | 433 | { |
7ffec97f | 434 | return std::__uninitialized_move_a(__first, __last, __mid, __alloc); |
15d72060 | 435 | } |
bc2631e0 | 436 | __catch(...) |
322821b9 | 437 | { |
1985f1cd | 438 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 439 | __throw_exception_again; |
322821b9 | 440 | } |
02d92e3b SW |
441 | } |
442 | ||
7ffec97f CJ |
443 | // __uninitialized_move_fill |
444 | // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and | |
02d92e3b | 445 | // fills [first2 + (last1 - first1), last2) with x. |
1985f1cd MA |
446 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp, |
447 | typename _Allocator> | |
02d92e3b | 448 | inline void |
7ffec97f | 449 | __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, |
15d72060 | 450 | _ForwardIterator __first2, |
1985f1cd | 451 | _ForwardIterator __last2, const _Tp& __x, |
c531371e | 452 | _Allocator& __alloc) |
02d92e3b | 453 | { |
7ffec97f | 454 | _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, |
1985f1cd MA |
455 | __first2, |
456 | __alloc); | |
bc2631e0 | 457 | __try |
917a9fd4 | 458 | { |
1985f1cd | 459 | std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); |
917a9fd4 | 460 | } |
bc2631e0 | 461 | __catch(...) |
322821b9 | 462 | { |
1985f1cd | 463 | std::_Destroy(__first2, __mid2, __alloc); |
ed6814f7 | 464 | __throw_exception_again; |
322821b9 | 465 | } |
02d92e3b | 466 | } |
725dc051 | 467 | |
734f5023 | 468 | #if __cplusplus >= 201103L |
cc86c05a PC |
469 | // Extensions: __uninitialized_default, __uninitialized_default_n, |
470 | // __uninitialized_default_a, __uninitialized_default_n_a. | |
471 | ||
472 | template<bool _TrivialValueType> | |
473 | struct __uninitialized_default_1 | |
474 | { | |
475 | template<typename _ForwardIterator> | |
476 | static void | |
477 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) | |
478 | { | |
479 | _ForwardIterator __cur = __first; | |
480 | __try | |
481 | { | |
482 | for (; __cur != __last; ++__cur) | |
483 | std::_Construct(std::__addressof(*__cur)); | |
484 | } | |
485 | __catch(...) | |
486 | { | |
487 | std::_Destroy(__first, __cur); | |
488 | __throw_exception_again; | |
489 | } | |
490 | } | |
491 | }; | |
492 | ||
493 | template<> | |
494 | struct __uninitialized_default_1<true> | |
495 | { | |
496 | template<typename _ForwardIterator> | |
497 | static void | |
498 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) | |
499 | { | |
500 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
501 | _ValueType; | |
502 | ||
503 | std::fill(__first, __last, _ValueType()); | |
504 | } | |
505 | }; | |
506 | ||
507 | template<bool _TrivialValueType> | |
508 | struct __uninitialized_default_n_1 | |
509 | { | |
510 | template<typename _ForwardIterator, typename _Size> | |
e51cf2f5 | 511 | static _ForwardIterator |
cc86c05a PC |
512 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
513 | { | |
514 | _ForwardIterator __cur = __first; | |
515 | __try | |
516 | { | |
517 | for (; __n > 0; --__n, ++__cur) | |
518 | std::_Construct(std::__addressof(*__cur)); | |
e51cf2f5 | 519 | return __cur; |
cc86c05a PC |
520 | } |
521 | __catch(...) | |
522 | { | |
523 | std::_Destroy(__first, __cur); | |
524 | __throw_exception_again; | |
525 | } | |
526 | } | |
527 | }; | |
528 | ||
529 | template<> | |
530 | struct __uninitialized_default_n_1<true> | |
531 | { | |
532 | template<typename _ForwardIterator, typename _Size> | |
e51cf2f5 | 533 | static _ForwardIterator |
cc86c05a PC |
534 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
535 | { | |
536 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
537 | _ValueType; | |
538 | ||
e51cf2f5 | 539 | return std::fill_n(__first, __n, _ValueType()); |
cc86c05a PC |
540 | } |
541 | }; | |
542 | ||
543 | // __uninitialized_default | |
544 | // Fills [first, last) with std::distance(first, last) default | |
545 | // constructed value_types(s). | |
546 | template<typename _ForwardIterator> | |
547 | inline void | |
548 | __uninitialized_default(_ForwardIterator __first, | |
549 | _ForwardIterator __last) | |
550 | { | |
551 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
552 | _ValueType; | |
5275f3e5 JW |
553 | // trivial types can have deleted assignment |
554 | const bool __assignable = is_copy_assignable<_ValueType>::value; | |
cc86c05a | 555 | |
5275f3e5 JW |
556 | std::__uninitialized_default_1<__is_trivial(_ValueType) |
557 | && __assignable>:: | |
cc86c05a PC |
558 | __uninit_default(__first, __last); |
559 | } | |
560 | ||
561 | // __uninitialized_default_n | |
562 | // Fills [first, first + n) with n default constructed value_type(s). | |
563 | template<typename _ForwardIterator, typename _Size> | |
e51cf2f5 | 564 | inline _ForwardIterator |
cc86c05a PC |
565 | __uninitialized_default_n(_ForwardIterator __first, _Size __n) |
566 | { | |
567 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
568 | _ValueType; | |
5275f3e5 JW |
569 | // trivial types can have deleted assignment |
570 | const bool __assignable = is_copy_assignable<_ValueType>::value; | |
cc86c05a | 571 | |
e51cf2f5 | 572 | return __uninitialized_default_n_1<__is_trivial(_ValueType) |
5275f3e5 | 573 | && __assignable>:: |
cc86c05a PC |
574 | __uninit_default_n(__first, __n); |
575 | } | |
576 | ||
577 | ||
578 | // __uninitialized_default_a | |
579 | // Fills [first, last) with std::distance(first, last) default | |
580 | // constructed value_types(s), constructed with the allocator alloc. | |
581 | template<typename _ForwardIterator, typename _Allocator> | |
582 | void | |
583 | __uninitialized_default_a(_ForwardIterator __first, | |
584 | _ForwardIterator __last, | |
585 | _Allocator& __alloc) | |
586 | { | |
587 | _ForwardIterator __cur = __first; | |
588 | __try | |
589 | { | |
e8eb60bd | 590 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
cc86c05a | 591 | for (; __cur != __last; ++__cur) |
e8eb60bd | 592 | __traits::construct(__alloc, std::__addressof(*__cur)); |
cc86c05a PC |
593 | } |
594 | __catch(...) | |
595 | { | |
596 | std::_Destroy(__first, __cur, __alloc); | |
597 | __throw_exception_again; | |
598 | } | |
599 | } | |
600 | ||
601 | template<typename _ForwardIterator, typename _Tp> | |
602 | inline void | |
603 | __uninitialized_default_a(_ForwardIterator __first, | |
604 | _ForwardIterator __last, | |
605 | allocator<_Tp>&) | |
606 | { std::__uninitialized_default(__first, __last); } | |
607 | ||
608 | ||
609 | // __uninitialized_default_n_a | |
610 | // Fills [first, first + n) with n default constructed value_types(s), | |
611 | // constructed with the allocator alloc. | |
612 | template<typename _ForwardIterator, typename _Size, typename _Allocator> | |
e51cf2f5 | 613 | _ForwardIterator |
cc86c05a PC |
614 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
615 | _Allocator& __alloc) | |
616 | { | |
617 | _ForwardIterator __cur = __first; | |
618 | __try | |
619 | { | |
e8eb60bd | 620 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
cc86c05a | 621 | for (; __n > 0; --__n, ++__cur) |
e8eb60bd | 622 | __traits::construct(__alloc, std::__addressof(*__cur)); |
e51cf2f5 | 623 | return __cur; |
cc86c05a PC |
624 | } |
625 | __catch(...) | |
626 | { | |
627 | std::_Destroy(__first, __cur, __alloc); | |
628 | __throw_exception_again; | |
629 | } | |
630 | } | |
631 | ||
632 | template<typename _ForwardIterator, typename _Size, typename _Tp> | |
e51cf2f5 | 633 | inline _ForwardIterator |
cc86c05a PC |
634 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
635 | allocator<_Tp>&) | |
e51cf2f5 | 636 | { return std::__uninitialized_default_n(__first, __n); } |
cc86c05a PC |
637 | |
638 | ||
b0371776 PC |
639 | template<typename _InputIterator, typename _Size, |
640 | typename _ForwardIterator> | |
641 | _ForwardIterator | |
642 | __uninitialized_copy_n(_InputIterator __first, _Size __n, | |
643 | _ForwardIterator __result, input_iterator_tag) | |
644 | { | |
645 | _ForwardIterator __cur = __result; | |
bc2631e0 | 646 | __try |
b0371776 PC |
647 | { |
648 | for (; __n > 0; --__n, ++__first, ++__cur) | |
fe27aa8b | 649 | std::_Construct(std::__addressof(*__cur), *__first); |
b0371776 PC |
650 | return __cur; |
651 | } | |
bc2631e0 | 652 | __catch(...) |
b0371776 PC |
653 | { |
654 | std::_Destroy(__result, __cur); | |
655 | __throw_exception_again; | |
656 | } | |
657 | } | |
658 | ||
659 | template<typename _RandomAccessIterator, typename _Size, | |
660 | typename _ForwardIterator> | |
661 | inline _ForwardIterator | |
662 | __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, | |
663 | _ForwardIterator __result, | |
664 | random_access_iterator_tag) | |
665 | { return std::uninitialized_copy(__first, __first + __n, __result); } | |
666 | ||
667 | /** | |
668 | * @brief Copies the range [first,first+n) into result. | |
93c66bc6 BK |
669 | * @param __first An input iterator. |
670 | * @param __n The number of elements to copy. | |
671 | * @param __result An output iterator. | |
672 | * @return __result + __n | |
b0371776 PC |
673 | * |
674 | * Like copy_n(), but does not require an initialized output range. | |
675 | */ | |
676 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> | |
677 | inline _ForwardIterator | |
678 | uninitialized_copy_n(_InputIterator __first, _Size __n, | |
679 | _ForwardIterator __result) | |
680 | { return std::__uninitialized_copy_n(__first, __n, __result, | |
681 | std::__iterator_category(__first)); } | |
682 | #endif | |
683 | ||
12ffa228 BK |
684 | _GLIBCXX_END_NAMESPACE_VERSION |
685 | } // namespace | |
725dc051 | 686 | |
3d7c150e | 687 | #endif /* _STL_UNINITIALIZED_H */ |