]>
Commit | Line | Data |
---|---|---|
42526146 PE |
1 | // Raw memory manipulators -*- C++ -*- |
2 | ||
7adcbafe | 3 | // Copyright (C) 2001-2022 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 | |
377f30c0 VV |
59 | #if __cplusplus >= 201103L |
60 | #include <type_traits> | |
61 | #endif | |
62 | ||
47cca028 JW |
63 | #include <bits/stl_algobase.h> // copy |
64 | #include <ext/alloc_traits.h> // __alloc_traits | |
65 | ||
66 | #if __cplusplus >= 201703L | |
67 | #include <bits/stl_pair.h> | |
68 | #endif | |
85f24114 | 69 | |
12ffa228 BK |
70 | namespace std _GLIBCXX_VISIBILITY(default) |
71 | { | |
72 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 73 | |
302b6996 JW |
74 | /** @addtogroup memory |
75 | * @{ | |
76 | */ | |
77 | ||
78 | /// @cond undocumented | |
79 | ||
ead40852 JW |
80 | #if __cplusplus >= 201103L |
81 | template<typename _ValueType, typename _Tp> | |
82 | constexpr bool | |
83 | __check_constructible() | |
84 | { | |
85 | // Trivial types can have deleted constructors, but std::copy etc. | |
86 | // only use assignment (or memmove) not construction, so we need an | |
87 | // explicit check that construction from _Tp is actually valid, | |
88 | // otherwise some ill-formed uses of std::uninitialized_xxx would | |
89 | // compile without errors. This gives a nice clear error message. | |
90 | static_assert(is_constructible<_ValueType, _Tp>::value, | |
91 | "result type must be constructible from input type"); | |
92 | ||
93 | return true; | |
94 | } | |
95 | ||
96 | // If the type is trivial we don't need to construct it, just assign to it. | |
97 | // But trivial types can still have deleted or inaccessible assignment, | |
98 | // so don't try to use std::copy or std::fill etc. if we can't assign. | |
99 | # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \ | |
100 | __is_trivial(T) && __is_assignable(T&, U) \ | |
101 | && std::__check_constructible<T, U>() | |
102 | #else | |
103 | // No need to check if is_constructible<T, U> for C++98. Trivial types have | |
104 | // no user-declared constructors, so if the assignment is valid, construction | |
105 | // should be too. | |
106 | # define _GLIBCXX_USE_ASSIGN_FOR_INIT(T, U) \ | |
107 | __is_trivial(T) && __is_assignable(T&, U) | |
108 | #endif | |
109 | ||
1ae8edf5 JW |
110 | template<typename _InputIterator, typename _ForwardIterator> |
111 | _GLIBCXX20_CONSTEXPR | |
112 | _ForwardIterator | |
113 | __do_uninit_copy(_InputIterator __first, _InputIterator __last, | |
114 | _ForwardIterator __result) | |
115 | { | |
116 | _ForwardIterator __cur = __result; | |
117 | __try | |
118 | { | |
119 | for (; __first != __last; ++__first, (void)++__cur) | |
120 | std::_Construct(std::__addressof(*__cur), *__first); | |
121 | return __cur; | |
122 | } | |
123 | __catch(...) | |
124 | { | |
125 | std::_Destroy(__result, __cur); | |
126 | __throw_exception_again; | |
127 | } | |
128 | } | |
129 | ||
cc86c05a | 130 | template<bool _TrivialValueTypes> |
f4c5578f | 131 | struct __uninitialized_copy |
02d92e3b | 132 | { |
f4c5578f PC |
133 | template<typename _InputIterator, typename _ForwardIterator> |
134 | static _ForwardIterator | |
cc86c05a PC |
135 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
136 | _ForwardIterator __result) | |
1ae8edf5 | 137 | { return std::__do_uninit_copy(__first, __last, __result); } |
f4c5578f PC |
138 | }; |
139 | ||
140 | template<> | |
141 | struct __uninitialized_copy<true> | |
142 | { | |
143 | template<typename _InputIterator, typename _ForwardIterator> | |
144 | static _ForwardIterator | |
cc86c05a PC |
145 | __uninit_copy(_InputIterator __first, _InputIterator __last, |
146 | _ForwardIterator __result) | |
f4c5578f PC |
147 | { return std::copy(__first, __last, __result); } |
148 | }; | |
02d92e3b | 149 | |
302b6996 JW |
150 | /// @endcond |
151 | ||
82b61df5 PE |
152 | /** |
153 | * @brief Copies the range [first,last) into result. | |
93c66bc6 BK |
154 | * @param __first An input iterator. |
155 | * @param __last An input iterator. | |
156 | * @param __result An output iterator. | |
157 | * @return __result + (__first - __last) | |
82b61df5 PE |
158 | * |
159 | * Like copy(), but does not require an initialized output range. | |
160 | */ | |
08addde6 PE |
161 | template<typename _InputIterator, typename _ForwardIterator> |
162 | inline _ForwardIterator | |
ed6814f7 | 163 | uninitialized_copy(_InputIterator __first, _InputIterator __last, |
917a9fd4 | 164 | _ForwardIterator __result) |
02d92e3b | 165 | { |
f4c5578f PC |
166 | typedef typename iterator_traits<_InputIterator>::value_type |
167 | _ValueType1; | |
ff2ea587 | 168 | typedef typename iterator_traits<_ForwardIterator>::value_type |
f4c5578f | 169 | _ValueType2; |
ead40852 JW |
170 | |
171 | // _ValueType1 must be trivially-copyable to use memmove, so don't | |
dd3e5859 | 172 | // bother optimizing to std::copy if it isn't. |
ead40852 JW |
173 | // XXX Unnecessary because std::copy would check it anyway? |
174 | const bool __can_memmove = __is_trivial(_ValueType1); | |
175 | ||
5275f3e5 | 176 | #if __cplusplus < 201103L |
ead40852 | 177 | typedef typename iterator_traits<_InputIterator>::reference _From; |
5275f3e5 | 178 | #else |
ead40852 | 179 | using _From = decltype(*__first); |
5275f3e5 | 180 | #endif |
ead40852 JW |
181 | const bool __assignable |
182 | = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType2, _From); | |
5275f3e5 | 183 | |
ead40852 | 184 | return std::__uninitialized_copy<__can_memmove && __assignable>:: |
cc86c05a | 185 | __uninit_copy(__first, __last, __result); |
02d92e3b SW |
186 | } |
187 | ||
302b6996 | 188 | /// @cond undocumented |
02d92e3b | 189 | |
1ae8edf5 JW |
190 | template<typename _ForwardIterator, typename _Tp> |
191 | _GLIBCXX20_CONSTEXPR void | |
192 | __do_uninit_fill(_ForwardIterator __first, _ForwardIterator __last, | |
193 | const _Tp& __x) | |
194 | { | |
195 | _ForwardIterator __cur = __first; | |
196 | __try | |
197 | { | |
198 | for (; __cur != __last; ++__cur) | |
199 | std::_Construct(std::__addressof(*__cur), __x); | |
200 | } | |
201 | __catch(...) | |
202 | { | |
203 | std::_Destroy(__first, __cur); | |
204 | __throw_exception_again; | |
205 | } | |
206 | } | |
207 | ||
cc86c05a | 208 | template<bool _TrivialValueType> |
f4c5578f | 209 | struct __uninitialized_fill |
02d92e3b | 210 | { |
f4c5578f PC |
211 | template<typename _ForwardIterator, typename _Tp> |
212 | static void | |
cc86c05a PC |
213 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
214 | const _Tp& __x) | |
1ae8edf5 | 215 | { std::__do_uninit_fill(__first, __last, __x); } |
f4c5578f PC |
216 | }; |
217 | ||
218 | template<> | |
219 | struct __uninitialized_fill<true> | |
220 | { | |
221 | template<typename _ForwardIterator, typename _Tp> | |
222 | static void | |
cc86c05a PC |
223 | __uninit_fill(_ForwardIterator __first, _ForwardIterator __last, |
224 | const _Tp& __x) | |
f4c5578f PC |
225 | { std::fill(__first, __last, __x); } |
226 | }; | |
02d92e3b | 227 | |
302b6996 JW |
228 | /// @endcond |
229 | ||
82b61df5 PE |
230 | /** |
231 | * @brief Copies the value x into the range [first,last). | |
93c66bc6 BK |
232 | * @param __first An input iterator. |
233 | * @param __last An input iterator. | |
234 | * @param __x The source value. | |
82b61df5 PE |
235 | * @return Nothing. |
236 | * | |
237 | * Like fill(), but does not require an initialized output range. | |
238 | */ | |
08addde6 | 239 | template<typename _ForwardIterator, typename _Tp> |
02d92e3b | 240 | inline void |
ed6814f7 | 241 | uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, |
917a9fd4 | 242 | const _Tp& __x) |
02d92e3b | 243 | { |
ff2ea587 PC |
244 | typedef typename iterator_traits<_ForwardIterator>::value_type |
245 | _ValueType; | |
61f5cb23 | 246 | |
ead40852 JW |
247 | // Trivial types do not need a constructor to begin their lifetime, |
248 | // so try to use std::fill to benefit from its memset optimization. | |
249 | const bool __can_fill | |
250 | = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&); | |
5275f3e5 | 251 | |
ead40852 | 252 | std::__uninitialized_fill<__can_fill>:: |
cc86c05a | 253 | __uninit_fill(__first, __last, __x); |
02d92e3b SW |
254 | } |
255 | ||
302b6996 | 256 | /// @cond undocumented |
02d92e3b | 257 | |
1ae8edf5 JW |
258 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
259 | _GLIBCXX20_CONSTEXPR | |
260 | _ForwardIterator | |
261 | __do_uninit_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) | |
262 | { | |
263 | _ForwardIterator __cur = __first; | |
264 | __try | |
265 | { | |
266 | for (; __n > 0; --__n, (void) ++__cur) | |
267 | std::_Construct(std::__addressof(*__cur), __x); | |
268 | return __cur; | |
269 | } | |
270 | __catch(...) | |
271 | { | |
272 | std::_Destroy(__first, __cur); | |
273 | __throw_exception_again; | |
274 | } | |
275 | } | |
276 | ||
cc86c05a | 277 | template<bool _TrivialValueType> |
f4c5578f | 278 | struct __uninitialized_fill_n |
02d92e3b | 279 | { |
f4c5578f | 280 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
1ae8edf5 | 281 | static _ForwardIterator |
cc86c05a PC |
282 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
283 | const _Tp& __x) | |
1ae8edf5 | 284 | { return std::__do_uninit_fill_n(__first, __n, __x); } |
f4c5578f PC |
285 | }; |
286 | ||
287 | template<> | |
288 | struct __uninitialized_fill_n<true> | |
289 | { | |
290 | template<typename _ForwardIterator, typename _Size, typename _Tp> | |
1ae8edf5 | 291 | static _ForwardIterator |
cc86c05a PC |
292 | __uninit_fill_n(_ForwardIterator __first, _Size __n, |
293 | const _Tp& __x) | |
e51cf2f5 | 294 | { return std::fill_n(__first, __n, __x); } |
f4c5578f | 295 | }; |
02d92e3b | 296 | |
302b6996 JW |
297 | /// @endcond |
298 | ||
e51cf2f5 JW |
299 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
300 | // DR 1339. uninitialized_fill_n should return the end of its range | |
82b61df5 PE |
301 | /** |
302 | * @brief Copies the value x into the range [first,first+n). | |
93c66bc6 BK |
303 | * @param __first An input iterator. |
304 | * @param __n The number of copies to make. | |
305 | * @param __x The source value. | |
368b7a30 | 306 | * @return Nothing. |
82b61df5 PE |
307 | * |
308 | * Like fill_n(), but does not require an initialized output range. | |
309 | */ | |
08addde6 | 310 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
e51cf2f5 | 311 | inline _ForwardIterator |
08addde6 | 312 | uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) |
02d92e3b | 313 | { |
ff2ea587 PC |
314 | typedef typename iterator_traits<_ForwardIterator>::value_type |
315 | _ValueType; | |
c9dce3b1 JW |
316 | |
317 | // Trivial types do not need a constructor to begin their lifetime, | |
ead40852 JW |
318 | // so try to use std::fill_n to benefit from its optimizations. |
319 | const bool __can_fill | |
320 | = _GLIBCXX_USE_ASSIGN_FOR_INIT(_ValueType, const _Tp&) | |
c9dce3b1 JW |
321 | // For arbitrary class types and floating point types we can't assume |
322 | // that __n > 0 and std::__size_to_integer(__n) > 0 are equivalent, | |
323 | // so only use std::fill_n when _Size is already an integral type. | |
ead40852 | 324 | && __is_integer<_Size>::__value; |
61f5cb23 | 325 | |
ead40852 | 326 | return __uninitialized_fill_n<__can_fill>:: |
cc86c05a | 327 | __uninit_fill_n(__first, __n, __x); |
02d92e3b SW |
328 | } |
329 | ||
ead40852 JW |
330 | #undef _GLIBCXX_USE_ASSIGN_FOR_INIT |
331 | ||
302b6996 JW |
332 | /// @cond undocumented |
333 | ||
1985f1cd MA |
334 | // Extensions: versions of uninitialized_copy, uninitialized_fill, |
335 | // and uninitialized_fill_n that take an allocator parameter. | |
336 | // We dispatch back to the standard versions when we're given the | |
1ae8edf5 | 337 | // default allocator. For nondefault allocators we do not use |
1985f1cd MA |
338 | // any of the POD optimizations. |
339 | ||
340 | template<typename _InputIterator, typename _ForwardIterator, | |
341 | typename _Allocator> | |
1ae8edf5 | 342 | _GLIBCXX20_CONSTEXPR |
1985f1cd MA |
343 | _ForwardIterator |
344 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, | |
c531371e | 345 | _ForwardIterator __result, _Allocator& __alloc) |
1985f1cd MA |
346 | { |
347 | _ForwardIterator __cur = __result; | |
bc2631e0 | 348 | __try |
1985f1cd | 349 | { |
e8eb60bd | 350 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
f970a17d | 351 | for (; __first != __last; ++__first, (void)++__cur) |
e8eb60bd | 352 | __traits::construct(__alloc, std::__addressof(*__cur), *__first); |
1985f1cd MA |
353 | return __cur; |
354 | } | |
bc2631e0 | 355 | __catch(...) |
1985f1cd MA |
356 | { |
357 | std::_Destroy(__result, __cur, __alloc); | |
358 | __throw_exception_again; | |
359 | } | |
360 | } | |
361 | ||
362 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp> | |
1ae8edf5 | 363 | _GLIBCXX20_CONSTEXPR |
1985f1cd MA |
364 | inline _ForwardIterator |
365 | __uninitialized_copy_a(_InputIterator __first, _InputIterator __last, | |
c531371e | 366 | _ForwardIterator __result, allocator<_Tp>&) |
1ae8edf5 JW |
367 | { |
368 | #ifdef __cpp_lib_is_constant_evaluated | |
369 | if (std::is_constant_evaluated()) | |
370 | return std::__do_uninit_copy(__first, __last, __result); | |
371 | #endif | |
372 | return std::uninitialized_copy(__first, __last, __result); | |
373 | } | |
1985f1cd | 374 | |
6eef7402 CJ |
375 | template<typename _InputIterator, typename _ForwardIterator, |
376 | typename _Allocator> | |
1ae8edf5 | 377 | _GLIBCXX20_CONSTEXPR |
6eef7402 CJ |
378 | inline _ForwardIterator |
379 | __uninitialized_move_a(_InputIterator __first, _InputIterator __last, | |
380 | _ForwardIterator __result, _Allocator& __alloc) | |
381 | { | |
382 | return std::__uninitialized_copy_a(_GLIBCXX_MAKE_MOVE_ITERATOR(__first), | |
383 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), | |
384 | __result, __alloc); | |
385 | } | |
386 | ||
74a2a1b4 PC |
387 | template<typename _InputIterator, typename _ForwardIterator, |
388 | typename _Allocator> | |
1ae8edf5 | 389 | _GLIBCXX20_CONSTEXPR |
74a2a1b4 PC |
390 | inline _ForwardIterator |
391 | __uninitialized_move_if_noexcept_a(_InputIterator __first, | |
392 | _InputIterator __last, | |
393 | _ForwardIterator __result, | |
394 | _Allocator& __alloc) | |
395 | { | |
396 | return std::__uninitialized_copy_a | |
397 | (_GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__first), | |
398 | _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(__last), __result, __alloc); | |
399 | } | |
400 | ||
1985f1cd | 401 | template<typename _ForwardIterator, typename _Tp, typename _Allocator> |
1ae8edf5 | 402 | _GLIBCXX20_CONSTEXPR |
1985f1cd MA |
403 | void |
404 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, | |
c531371e | 405 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
406 | { |
407 | _ForwardIterator __cur = __first; | |
bc2631e0 | 408 | __try |
1985f1cd | 409 | { |
e8eb60bd | 410 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
1985f1cd | 411 | for (; __cur != __last; ++__cur) |
e8eb60bd | 412 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
1985f1cd | 413 | } |
bc2631e0 | 414 | __catch(...) |
1985f1cd MA |
415 | { |
416 | std::_Destroy(__first, __cur, __alloc); | |
417 | __throw_exception_again; | |
418 | } | |
419 | } | |
420 | ||
421 | template<typename _ForwardIterator, typename _Tp, typename _Tp2> | |
1ae8edf5 | 422 | _GLIBCXX20_CONSTEXPR |
1985f1cd MA |
423 | inline void |
424 | __uninitialized_fill_a(_ForwardIterator __first, _ForwardIterator __last, | |
c531371e | 425 | const _Tp& __x, allocator<_Tp2>&) |
1ae8edf5 JW |
426 | { |
427 | #ifdef __cpp_lib_is_constant_evaluated | |
428 | if (std::is_constant_evaluated()) | |
429 | return std::__do_uninit_fill(__first, __last, __x); | |
430 | #endif | |
431 | std::uninitialized_fill(__first, __last, __x); | |
432 | } | |
1985f1cd MA |
433 | |
434 | template<typename _ForwardIterator, typename _Size, typename _Tp, | |
435 | typename _Allocator> | |
1ae8edf5 | 436 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 437 | _ForwardIterator |
1ae8edf5 | 438 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
c531371e | 439 | const _Tp& __x, _Allocator& __alloc) |
1985f1cd MA |
440 | { |
441 | _ForwardIterator __cur = __first; | |
bc2631e0 | 442 | __try |
1985f1cd | 443 | { |
e8eb60bd | 444 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
d67be443 | 445 | for (; __n > 0; --__n, (void) ++__cur) |
e8eb60bd | 446 | __traits::construct(__alloc, std::__addressof(*__cur), __x); |
e51cf2f5 | 447 | return __cur; |
1985f1cd | 448 | } |
bc2631e0 | 449 | __catch(...) |
1985f1cd MA |
450 | { |
451 | std::_Destroy(__first, __cur, __alloc); | |
452 | __throw_exception_again; | |
453 | } | |
454 | } | |
455 | ||
456 | template<typename _ForwardIterator, typename _Size, typename _Tp, | |
457 | typename _Tp2> | |
1ae8edf5 | 458 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 459 | inline _ForwardIterator |
1ae8edf5 | 460 | __uninitialized_fill_n_a(_ForwardIterator __first, _Size __n, |
c531371e | 461 | const _Tp& __x, allocator<_Tp2>&) |
1ae8edf5 JW |
462 | { |
463 | #ifdef __cpp_lib_is_constant_evaluated | |
464 | if (std::is_constant_evaluated()) | |
465 | return std::__do_uninit_fill_n(__first, __n, __x); | |
466 | #endif | |
467 | return std::uninitialized_fill_n(__first, __n, __x); | |
468 | } | |
1985f1cd MA |
469 | |
470 | ||
7ffec97f CJ |
471 | // Extensions: __uninitialized_copy_move, __uninitialized_move_copy, |
472 | // __uninitialized_fill_move, __uninitialized_move_fill. | |
473 | // All of these algorithms take a user-supplied allocator, which is used | |
474 | // for construction and destruction. | |
02d92e3b | 475 | |
7ffec97f | 476 | // __uninitialized_copy_move |
02d92e3b | 477 | // Copies [first1, last1) into [result, result + (last1 - first1)), and |
7ffec97f | 478 | // move [first2, last2) into |
02d92e3b | 479 | // [result, result + (last1 - first1) + (last2 - first2)). |
ed6814f7 | 480 | template<typename _InputIterator1, typename _InputIterator2, |
1985f1cd | 481 | typename _ForwardIterator, typename _Allocator> |
08addde6 | 482 | inline _ForwardIterator |
7ffec97f | 483 | __uninitialized_copy_move(_InputIterator1 __first1, |
917a9fd4 | 484 | _InputIterator1 __last1, |
ed6814f7 | 485 | _InputIterator2 __first2, |
917a9fd4 | 486 | _InputIterator2 __last2, |
1985f1cd | 487 | _ForwardIterator __result, |
c531371e | 488 | _Allocator& __alloc) |
02d92e3b | 489 | { |
1985f1cd MA |
490 | _ForwardIterator __mid = std::__uninitialized_copy_a(__first1, __last1, |
491 | __result, | |
492 | __alloc); | |
bc2631e0 | 493 | __try |
15d72060 | 494 | { |
7ffec97f | 495 | return std::__uninitialized_move_a(__first2, __last2, __mid, __alloc); |
15d72060 | 496 | } |
bc2631e0 | 497 | __catch(...) |
ed6814f7 | 498 | { |
1985f1cd | 499 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 500 | __throw_exception_again; |
322821b9 | 501 | } |
02d92e3b SW |
502 | } |
503 | ||
7ffec97f CJ |
504 | // __uninitialized_move_copy |
505 | // Moves [first1, last1) into [result, result + (last1 - first1)), and | |
506 | // copies [first2, last2) into | |
507 | // [result, result + (last1 - first1) + (last2 - first2)). | |
508 | template<typename _InputIterator1, typename _InputIterator2, | |
509 | typename _ForwardIterator, typename _Allocator> | |
510 | inline _ForwardIterator | |
511 | __uninitialized_move_copy(_InputIterator1 __first1, | |
512 | _InputIterator1 __last1, | |
513 | _InputIterator2 __first2, | |
514 | _InputIterator2 __last2, | |
515 | _ForwardIterator __result, | |
516 | _Allocator& __alloc) | |
517 | { | |
518 | _ForwardIterator __mid = std::__uninitialized_move_a(__first1, __last1, | |
519 | __result, | |
520 | __alloc); | |
bc2631e0 | 521 | __try |
7ffec97f CJ |
522 | { |
523 | return std::__uninitialized_copy_a(__first2, __last2, __mid, __alloc); | |
524 | } | |
bc2631e0 | 525 | __catch(...) |
7ffec97f CJ |
526 | { |
527 | std::_Destroy(__result, __mid, __alloc); | |
528 | __throw_exception_again; | |
529 | } | |
530 | } | |
1ae8edf5 | 531 | |
7ffec97f CJ |
532 | // __uninitialized_fill_move |
533 | // Fills [result, mid) with x, and moves [first, last) into | |
02d92e3b | 534 | // [mid, mid + (last - first)). |
1985f1cd MA |
535 | template<typename _ForwardIterator, typename _Tp, typename _InputIterator, |
536 | typename _Allocator> | |
ed6814f7 | 537 | inline _ForwardIterator |
7ffec97f | 538 | __uninitialized_fill_move(_ForwardIterator __result, _ForwardIterator __mid, |
15d72060 | 539 | const _Tp& __x, _InputIterator __first, |
c531371e | 540 | _InputIterator __last, _Allocator& __alloc) |
02d92e3b | 541 | { |
1985f1cd | 542 | std::__uninitialized_fill_a(__result, __mid, __x, __alloc); |
bc2631e0 | 543 | __try |
15d72060 | 544 | { |
7ffec97f | 545 | return std::__uninitialized_move_a(__first, __last, __mid, __alloc); |
15d72060 | 546 | } |
bc2631e0 | 547 | __catch(...) |
322821b9 | 548 | { |
1985f1cd | 549 | std::_Destroy(__result, __mid, __alloc); |
ed6814f7 | 550 | __throw_exception_again; |
322821b9 | 551 | } |
02d92e3b SW |
552 | } |
553 | ||
7ffec97f CJ |
554 | // __uninitialized_move_fill |
555 | // Moves [first1, last1) into [first2, first2 + (last1 - first1)), and | |
02d92e3b | 556 | // fills [first2 + (last1 - first1), last2) with x. |
1985f1cd MA |
557 | template<typename _InputIterator, typename _ForwardIterator, typename _Tp, |
558 | typename _Allocator> | |
02d92e3b | 559 | inline void |
7ffec97f | 560 | __uninitialized_move_fill(_InputIterator __first1, _InputIterator __last1, |
15d72060 | 561 | _ForwardIterator __first2, |
1985f1cd | 562 | _ForwardIterator __last2, const _Tp& __x, |
c531371e | 563 | _Allocator& __alloc) |
02d92e3b | 564 | { |
7ffec97f | 565 | _ForwardIterator __mid2 = std::__uninitialized_move_a(__first1, __last1, |
1985f1cd MA |
566 | __first2, |
567 | __alloc); | |
bc2631e0 | 568 | __try |
917a9fd4 | 569 | { |
1985f1cd | 570 | std::__uninitialized_fill_a(__mid2, __last2, __x, __alloc); |
917a9fd4 | 571 | } |
bc2631e0 | 572 | __catch(...) |
322821b9 | 573 | { |
1985f1cd | 574 | std::_Destroy(__first2, __mid2, __alloc); |
ed6814f7 | 575 | __throw_exception_again; |
322821b9 | 576 | } |
02d92e3b | 577 | } |
725dc051 | 578 | |
302b6996 JW |
579 | /// @endcond |
580 | ||
734f5023 | 581 | #if __cplusplus >= 201103L |
302b6996 JW |
582 | /// @cond undocumented |
583 | ||
cc86c05a PC |
584 | // Extensions: __uninitialized_default, __uninitialized_default_n, |
585 | // __uninitialized_default_a, __uninitialized_default_n_a. | |
586 | ||
587 | template<bool _TrivialValueType> | |
588 | struct __uninitialized_default_1 | |
589 | { | |
590 | template<typename _ForwardIterator> | |
591 | static void | |
592 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) | |
593 | { | |
594 | _ForwardIterator __cur = __first; | |
595 | __try | |
596 | { | |
597 | for (; __cur != __last; ++__cur) | |
598 | std::_Construct(std::__addressof(*__cur)); | |
599 | } | |
600 | __catch(...) | |
601 | { | |
602 | std::_Destroy(__first, __cur); | |
603 | __throw_exception_again; | |
604 | } | |
605 | } | |
606 | }; | |
607 | ||
608 | template<> | |
609 | struct __uninitialized_default_1<true> | |
610 | { | |
611 | template<typename _ForwardIterator> | |
612 | static void | |
613 | __uninit_default(_ForwardIterator __first, _ForwardIterator __last) | |
614 | { | |
632183dd JW |
615 | if (__first == __last) |
616 | return; | |
617 | ||
618 | typename iterator_traits<_ForwardIterator>::value_type* __val | |
619 | = std::__addressof(*__first); | |
620 | std::_Construct(__val); | |
621 | if (++__first != __last) | |
622 | std::fill(__first, __last, *__val); | |
cc86c05a PC |
623 | } |
624 | }; | |
625 | ||
626 | template<bool _TrivialValueType> | |
627 | struct __uninitialized_default_n_1 | |
628 | { | |
629 | template<typename _ForwardIterator, typename _Size> | |
1ae8edf5 | 630 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 631 | static _ForwardIterator |
cc86c05a PC |
632 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
633 | { | |
634 | _ForwardIterator __cur = __first; | |
635 | __try | |
636 | { | |
d67be443 | 637 | for (; __n > 0; --__n, (void) ++__cur) |
cc86c05a | 638 | std::_Construct(std::__addressof(*__cur)); |
e51cf2f5 | 639 | return __cur; |
cc86c05a PC |
640 | } |
641 | __catch(...) | |
642 | { | |
643 | std::_Destroy(__first, __cur); | |
644 | __throw_exception_again; | |
645 | } | |
646 | } | |
647 | }; | |
648 | ||
649 | template<> | |
650 | struct __uninitialized_default_n_1<true> | |
651 | { | |
652 | template<typename _ForwardIterator, typename _Size> | |
1ae8edf5 | 653 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 654 | static _ForwardIterator |
cc86c05a PC |
655 | __uninit_default_n(_ForwardIterator __first, _Size __n) |
656 | { | |
632183dd JW |
657 | if (__n > 0) |
658 | { | |
659 | typename iterator_traits<_ForwardIterator>::value_type* __val | |
660 | = std::__addressof(*__first); | |
661 | std::_Construct(__val); | |
662 | ++__first; | |
663 | __first = std::fill_n(__first, __n - 1, *__val); | |
664 | } | |
665 | return __first; | |
cc86c05a PC |
666 | } |
667 | }; | |
668 | ||
669 | // __uninitialized_default | |
632183dd | 670 | // Fills [first, last) with value-initialized value_types. |
cc86c05a PC |
671 | template<typename _ForwardIterator> |
672 | inline void | |
673 | __uninitialized_default(_ForwardIterator __first, | |
674 | _ForwardIterator __last) | |
675 | { | |
676 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
677 | _ValueType; | |
5275f3e5 JW |
678 | // trivial types can have deleted assignment |
679 | const bool __assignable = is_copy_assignable<_ValueType>::value; | |
cc86c05a | 680 | |
5275f3e5 JW |
681 | std::__uninitialized_default_1<__is_trivial(_ValueType) |
682 | && __assignable>:: | |
cc86c05a PC |
683 | __uninit_default(__first, __last); |
684 | } | |
685 | ||
686 | // __uninitialized_default_n | |
632183dd | 687 | // Fills [first, first + n) with value-initialized value_types. |
cc86c05a | 688 | template<typename _ForwardIterator, typename _Size> |
1ae8edf5 | 689 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 690 | inline _ForwardIterator |
cc86c05a PC |
691 | __uninitialized_default_n(_ForwardIterator __first, _Size __n) |
692 | { | |
693 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
694 | _ValueType; | |
c9dce3b1 JW |
695 | // See uninitialized_fill_n for the conditions for using std::fill_n. |
696 | constexpr bool __can_fill | |
697 | = __and_<is_integral<_Size>, is_copy_assignable<_ValueType>>::value; | |
cc86c05a | 698 | |
e51cf2f5 | 699 | return __uninitialized_default_n_1<__is_trivial(_ValueType) |
c9dce3b1 | 700 | && __can_fill>:: |
cc86c05a PC |
701 | __uninit_default_n(__first, __n); |
702 | } | |
703 | ||
704 | ||
705 | // __uninitialized_default_a | |
632183dd JW |
706 | // Fills [first, last) with value_types constructed by the allocator |
707 | // alloc, with no arguments passed to the construct call. | |
cc86c05a PC |
708 | template<typename _ForwardIterator, typename _Allocator> |
709 | void | |
710 | __uninitialized_default_a(_ForwardIterator __first, | |
711 | _ForwardIterator __last, | |
712 | _Allocator& __alloc) | |
713 | { | |
714 | _ForwardIterator __cur = __first; | |
715 | __try | |
716 | { | |
e8eb60bd | 717 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
cc86c05a | 718 | for (; __cur != __last; ++__cur) |
e8eb60bd | 719 | __traits::construct(__alloc, std::__addressof(*__cur)); |
cc86c05a PC |
720 | } |
721 | __catch(...) | |
722 | { | |
723 | std::_Destroy(__first, __cur, __alloc); | |
724 | __throw_exception_again; | |
725 | } | |
726 | } | |
727 | ||
728 | template<typename _ForwardIterator, typename _Tp> | |
729 | inline void | |
730 | __uninitialized_default_a(_ForwardIterator __first, | |
731 | _ForwardIterator __last, | |
732 | allocator<_Tp>&) | |
733 | { std::__uninitialized_default(__first, __last); } | |
734 | ||
735 | ||
736 | // __uninitialized_default_n_a | |
632183dd JW |
737 | // Fills [first, first + n) with value_types constructed by the allocator |
738 | // alloc, with no arguments passed to the construct call. | |
cc86c05a | 739 | template<typename _ForwardIterator, typename _Size, typename _Allocator> |
1ae8edf5 JW |
740 | _GLIBCXX20_CONSTEXPR _ForwardIterator |
741 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, | |
cc86c05a PC |
742 | _Allocator& __alloc) |
743 | { | |
744 | _ForwardIterator __cur = __first; | |
745 | __try | |
746 | { | |
e8eb60bd | 747 | typedef __gnu_cxx::__alloc_traits<_Allocator> __traits; |
d67be443 | 748 | for (; __n > 0; --__n, (void) ++__cur) |
e8eb60bd | 749 | __traits::construct(__alloc, std::__addressof(*__cur)); |
e51cf2f5 | 750 | return __cur; |
cc86c05a PC |
751 | } |
752 | __catch(...) | |
753 | { | |
754 | std::_Destroy(__first, __cur, __alloc); | |
755 | __throw_exception_again; | |
756 | } | |
757 | } | |
758 | ||
632183dd JW |
759 | // __uninitialized_default_n_a specialization for std::allocator, |
760 | // which ignores the allocator and value-initializes the elements. | |
cc86c05a | 761 | template<typename _ForwardIterator, typename _Size, typename _Tp> |
1ae8edf5 | 762 | _GLIBCXX20_CONSTEXPR |
e51cf2f5 | 763 | inline _ForwardIterator |
1ae8edf5 | 764 | __uninitialized_default_n_a(_ForwardIterator __first, _Size __n, |
cc86c05a | 765 | allocator<_Tp>&) |
e51cf2f5 | 766 | { return std::__uninitialized_default_n(__first, __n); } |
cc86c05a | 767 | |
377f30c0 VV |
768 | template<bool _TrivialValueType> |
769 | struct __uninitialized_default_novalue_1 | |
770 | { | |
771 | template<typename _ForwardIterator> | |
772 | static void | |
773 | __uninit_default_novalue(_ForwardIterator __first, | |
774 | _ForwardIterator __last) | |
775 | { | |
776 | _ForwardIterator __cur = __first; | |
777 | __try | |
778 | { | |
779 | for (; __cur != __last; ++__cur) | |
780 | std::_Construct_novalue(std::__addressof(*__cur)); | |
781 | } | |
782 | __catch(...) | |
783 | { | |
784 | std::_Destroy(__first, __cur); | |
785 | __throw_exception_again; | |
786 | } | |
787 | } | |
788 | }; | |
789 | ||
790 | template<> | |
791 | struct __uninitialized_default_novalue_1<true> | |
792 | { | |
793 | template<typename _ForwardIterator> | |
794 | static void | |
795 | __uninit_default_novalue(_ForwardIterator __first, | |
796 | _ForwardIterator __last) | |
797 | { | |
798 | } | |
799 | }; | |
800 | ||
801 | template<bool _TrivialValueType> | |
802 | struct __uninitialized_default_novalue_n_1 | |
803 | { | |
804 | template<typename _ForwardIterator, typename _Size> | |
805 | static _ForwardIterator | |
806 | __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) | |
807 | { | |
808 | _ForwardIterator __cur = __first; | |
809 | __try | |
810 | { | |
d67be443 | 811 | for (; __n > 0; --__n, (void) ++__cur) |
377f30c0 VV |
812 | std::_Construct_novalue(std::__addressof(*__cur)); |
813 | return __cur; | |
814 | } | |
815 | __catch(...) | |
816 | { | |
817 | std::_Destroy(__first, __cur); | |
818 | __throw_exception_again; | |
819 | } | |
820 | } | |
821 | }; | |
822 | ||
823 | template<> | |
824 | struct __uninitialized_default_novalue_n_1<true> | |
825 | { | |
826 | template<typename _ForwardIterator, typename _Size> | |
827 | static _ForwardIterator | |
828 | __uninit_default_novalue_n(_ForwardIterator __first, _Size __n) | |
08a53a2e | 829 | { return std::next(__first, __n); } |
377f30c0 VV |
830 | }; |
831 | ||
832 | // __uninitialized_default_novalue | |
632183dd | 833 | // Fills [first, last) with default-initialized value_types. |
377f30c0 VV |
834 | template<typename _ForwardIterator> |
835 | inline void | |
836 | __uninitialized_default_novalue(_ForwardIterator __first, | |
837 | _ForwardIterator __last) | |
838 | { | |
839 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
840 | _ValueType; | |
841 | ||
842 | std::__uninitialized_default_novalue_1< | |
843 | is_trivially_default_constructible<_ValueType>::value>:: | |
844 | __uninit_default_novalue(__first, __last); | |
845 | } | |
846 | ||
632183dd JW |
847 | // __uninitialized_default_novalue_n |
848 | // Fills [first, first + n) with default-initialized value_types. | |
377f30c0 VV |
849 | template<typename _ForwardIterator, typename _Size> |
850 | inline _ForwardIterator | |
851 | __uninitialized_default_novalue_n(_ForwardIterator __first, _Size __n) | |
852 | { | |
853 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
854 | _ValueType; | |
855 | ||
856 | return __uninitialized_default_novalue_n_1< | |
857 | is_trivially_default_constructible<_ValueType>::value>:: | |
858 | __uninit_default_novalue_n(__first, __n); | |
859 | } | |
cc86c05a | 860 | |
b0371776 PC |
861 | template<typename _InputIterator, typename _Size, |
862 | typename _ForwardIterator> | |
863 | _ForwardIterator | |
864 | __uninitialized_copy_n(_InputIterator __first, _Size __n, | |
865 | _ForwardIterator __result, input_iterator_tag) | |
866 | { | |
867 | _ForwardIterator __cur = __result; | |
bc2631e0 | 868 | __try |
b0371776 | 869 | { |
d67be443 | 870 | for (; __n > 0; --__n, (void) ++__first, ++__cur) |
fe27aa8b | 871 | std::_Construct(std::__addressof(*__cur), *__first); |
b0371776 PC |
872 | return __cur; |
873 | } | |
bc2631e0 | 874 | __catch(...) |
b0371776 PC |
875 | { |
876 | std::_Destroy(__result, __cur); | |
877 | __throw_exception_again; | |
878 | } | |
879 | } | |
880 | ||
881 | template<typename _RandomAccessIterator, typename _Size, | |
882 | typename _ForwardIterator> | |
883 | inline _ForwardIterator | |
884 | __uninitialized_copy_n(_RandomAccessIterator __first, _Size __n, | |
885 | _ForwardIterator __result, | |
886 | random_access_iterator_tag) | |
887 | { return std::uninitialized_copy(__first, __first + __n, __result); } | |
888 | ||
377f30c0 VV |
889 | template<typename _InputIterator, typename _Size, |
890 | typename _ForwardIterator> | |
891 | pair<_InputIterator, _ForwardIterator> | |
892 | __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, | |
893 | _ForwardIterator __result, input_iterator_tag) | |
894 | { | |
895 | _ForwardIterator __cur = __result; | |
896 | __try | |
897 | { | |
d67be443 | 898 | for (; __n > 0; --__n, (void) ++__first, ++__cur) |
377f30c0 VV |
899 | std::_Construct(std::__addressof(*__cur), *__first); |
900 | return {__first, __cur}; | |
901 | } | |
902 | __catch(...) | |
903 | { | |
904 | std::_Destroy(__result, __cur); | |
905 | __throw_exception_again; | |
906 | } | |
907 | } | |
908 | ||
909 | template<typename _RandomAccessIterator, typename _Size, | |
910 | typename _ForwardIterator> | |
911 | inline pair<_RandomAccessIterator, _ForwardIterator> | |
912 | __uninitialized_copy_n_pair(_RandomAccessIterator __first, _Size __n, | |
913 | _ForwardIterator __result, | |
914 | random_access_iterator_tag) | |
915 | { | |
916 | auto __second_res = uninitialized_copy(__first, __first + __n, __result); | |
917 | auto __first_res = std::next(__first, __n); | |
918 | return {__first_res, __second_res}; | |
919 | } | |
920 | ||
302b6996 JW |
921 | /// @endcond |
922 | ||
b0371776 PC |
923 | /** |
924 | * @brief Copies the range [first,first+n) into result. | |
93c66bc6 BK |
925 | * @param __first An input iterator. |
926 | * @param __n The number of elements to copy. | |
927 | * @param __result An output iterator. | |
928 | * @return __result + __n | |
ead40852 | 929 | * @since C++11 |
b0371776 PC |
930 | * |
931 | * Like copy_n(), but does not require an initialized output range. | |
932 | */ | |
933 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> | |
934 | inline _ForwardIterator | |
935 | uninitialized_copy_n(_InputIterator __first, _Size __n, | |
936 | _ForwardIterator __result) | |
937 | { return std::__uninitialized_copy_n(__first, __n, __result, | |
938 | std::__iterator_category(__first)); } | |
377f30c0 | 939 | |
302b6996 | 940 | /// @cond undocumented |
377f30c0 VV |
941 | template<typename _InputIterator, typename _Size, typename _ForwardIterator> |
942 | inline pair<_InputIterator, _ForwardIterator> | |
943 | __uninitialized_copy_n_pair(_InputIterator __first, _Size __n, | |
944 | _ForwardIterator __result) | |
945 | { | |
946 | return | |
947 | std::__uninitialized_copy_n_pair(__first, __n, __result, | |
948 | std::__iterator_category(__first)); | |
949 | } | |
302b6996 | 950 | /// @endcond |
b0371776 PC |
951 | #endif |
952 | ||
56a9eaf9 JW |
953 | #if __cplusplus >= 201703L |
954 | # define __cpp_lib_raw_memory_algorithms 201606L | |
955 | ||
302b6996 JW |
956 | /** |
957 | * @brief Default-initializes objects in the range [first,last). | |
958 | * @param __first A forward iterator. | |
959 | * @param __last A forward iterator. | |
ead40852 | 960 | * @since C++17 |
302b6996 | 961 | */ |
8e14a10c VV |
962 | template <typename _ForwardIterator> |
963 | inline void | |
964 | uninitialized_default_construct(_ForwardIterator __first, | |
965 | _ForwardIterator __last) | |
b26f45f0 JW |
966 | { |
967 | __uninitialized_default_novalue(__first, __last); | |
968 | } | |
8e14a10c | 969 | |
302b6996 JW |
970 | /** |
971 | * @brief Default-initializes objects in the range [first,first+count). | |
972 | * @param __first A forward iterator. | |
973 | * @param __count The number of objects to construct. | |
974 | * @return __first + __count | |
ead40852 | 975 | * @since C++17 |
302b6996 | 976 | */ |
8e14a10c VV |
977 | template <typename _ForwardIterator, typename _Size> |
978 | inline _ForwardIterator | |
979 | uninitialized_default_construct_n(_ForwardIterator __first, _Size __count) | |
b26f45f0 JW |
980 | { |
981 | return __uninitialized_default_novalue_n(__first, __count); | |
982 | } | |
8e14a10c | 983 | |
302b6996 JW |
984 | /** |
985 | * @brief Value-initializes objects in the range [first,last). | |
986 | * @param __first A forward iterator. | |
987 | * @param __last A forward iterator. | |
ead40852 | 988 | * @since C++17 |
302b6996 | 989 | */ |
8e14a10c VV |
990 | template <typename _ForwardIterator> |
991 | inline void | |
992 | uninitialized_value_construct(_ForwardIterator __first, | |
993 | _ForwardIterator __last) | |
b26f45f0 JW |
994 | { |
995 | return __uninitialized_default(__first, __last); | |
996 | } | |
8e14a10c | 997 | |
302b6996 JW |
998 | /** |
999 | * @brief Value-initializes objects in the range [first,first+count). | |
1000 | * @param __first A forward iterator. | |
1001 | * @param __count The number of objects to construct. | |
1002 | * @return __result + __count | |
ead40852 | 1003 | * @since C++17 |
302b6996 | 1004 | */ |
8e14a10c VV |
1005 | template <typename _ForwardIterator, typename _Size> |
1006 | inline _ForwardIterator | |
1007 | uninitialized_value_construct_n(_ForwardIterator __first, _Size __count) | |
b26f45f0 JW |
1008 | { |
1009 | return __uninitialized_default_n(__first, __count); | |
1010 | } | |
8e14a10c | 1011 | |
302b6996 JW |
1012 | /** |
1013 | * @brief Move-construct from the range [first,last) into result. | |
1014 | * @param __first An input iterator. | |
1015 | * @param __last An input iterator. | |
1016 | * @param __result An output iterator. | |
1017 | * @return __result + (__first - __last) | |
ead40852 | 1018 | * @since C++17 |
302b6996 | 1019 | */ |
8e14a10c VV |
1020 | template <typename _InputIterator, typename _ForwardIterator> |
1021 | inline _ForwardIterator | |
1022 | uninitialized_move(_InputIterator __first, _InputIterator __last, | |
1023 | _ForwardIterator __result) | |
b26f45f0 JW |
1024 | { |
1025 | return std::uninitialized_copy | |
1026 | (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), | |
1027 | _GLIBCXX_MAKE_MOVE_ITERATOR(__last), __result); | |
1028 | } | |
8e14a10c | 1029 | |
302b6996 JW |
1030 | /** |
1031 | * @brief Move-construct from the range [first,first+count) into result. | |
1032 | * @param __first An input iterator. | |
1033 | * @param __count The number of objects to initialize. | |
1034 | * @param __result An output iterator. | |
1035 | * @return __result + __count | |
ead40852 | 1036 | * @since C++17 |
302b6996 | 1037 | */ |
8e14a10c VV |
1038 | template <typename _InputIterator, typename _Size, typename _ForwardIterator> |
1039 | inline pair<_InputIterator, _ForwardIterator> | |
1040 | uninitialized_move_n(_InputIterator __first, _Size __count, | |
1041 | _ForwardIterator __result) | |
b26f45f0 JW |
1042 | { |
1043 | auto __res = std::__uninitialized_copy_n_pair | |
1044 | (_GLIBCXX_MAKE_MOVE_ITERATOR(__first), | |
1045 | __count, __result); | |
1046 | return {__res.first.base(), __res.second}; | |
1047 | } | |
56a9eaf9 | 1048 | #endif // C++17 |
8e14a10c | 1049 | |
0f317ef7 | 1050 | #if __cplusplus >= 201103L |
302b6996 JW |
1051 | /// @cond undocumented |
1052 | ||
0f317ef7 | 1053 | template<typename _Tp, typename _Up, typename _Allocator> |
33adfd0d | 1054 | _GLIBCXX20_CONSTEXPR |
0f317ef7 | 1055 | inline void |
2b326d53 MG |
1056 | __relocate_object_a(_Tp* __restrict __dest, _Up* __restrict __orig, |
1057 | _Allocator& __alloc) | |
0f317ef7 MG |
1058 | noexcept(noexcept(std::allocator_traits<_Allocator>::construct(__alloc, |
1059 | __dest, std::move(*__orig))) | |
1060 | && noexcept(std::allocator_traits<_Allocator>::destroy( | |
1061 | __alloc, std::__addressof(*__orig)))) | |
1062 | { | |
1063 | typedef std::allocator_traits<_Allocator> __traits; | |
1064 | __traits::construct(__alloc, __dest, std::move(*__orig)); | |
1065 | __traits::destroy(__alloc, std::__addressof(*__orig)); | |
1066 | } | |
1067 | ||
1068 | // This class may be specialized for specific types. | |
9aa2470a | 1069 | // Also known as is_trivially_relocatable. |
ff2e7f19 | 1070 | template<typename _Tp, typename = void> |
9aa2470a | 1071 | struct __is_bitwise_relocatable |
0f317ef7 MG |
1072 | : is_trivial<_Tp> { }; |
1073 | ||
0f317ef7 MG |
1074 | template <typename _InputIterator, typename _ForwardIterator, |
1075 | typename _Allocator> | |
1ae8edf5 | 1076 | _GLIBCXX20_CONSTEXPR |
0f317ef7 MG |
1077 | inline _ForwardIterator |
1078 | __relocate_a_1(_InputIterator __first, _InputIterator __last, | |
1079 | _ForwardIterator __result, _Allocator& __alloc) | |
ff2e7f19 MG |
1080 | noexcept(noexcept(std::__relocate_object_a(std::addressof(*__result), |
1081 | std::addressof(*__first), | |
1082 | __alloc))) | |
0f317ef7 MG |
1083 | { |
1084 | typedef typename iterator_traits<_InputIterator>::value_type | |
1085 | _ValueType; | |
1086 | typedef typename iterator_traits<_ForwardIterator>::value_type | |
1087 | _ValueType2; | |
27812872 JW |
1088 | static_assert(std::is_same<_ValueType, _ValueType2>::value, |
1089 | "relocation is only possible for values of the same type"); | |
0f317ef7 MG |
1090 | _ForwardIterator __cur = __result; |
1091 | for (; __first != __last; ++__first, (void)++__cur) | |
1092 | std::__relocate_object_a(std::__addressof(*__cur), | |
1093 | std::__addressof(*__first), __alloc); | |
1094 | return __cur; | |
1095 | } | |
1096 | ||
33adfd0d JW |
1097 | template <typename _Tp, typename _Up> |
1098 | _GLIBCXX20_CONSTEXPR | |
1099 | inline __enable_if_t<std::__is_bitwise_relocatable<_Tp>::value, _Tp*> | |
1100 | __relocate_a_1(_Tp* __first, _Tp* __last, | |
1101 | _Tp* __result, | |
1102 | [[__maybe_unused__]] allocator<_Up>& __alloc) noexcept | |
1103 | { | |
1104 | ptrdiff_t __count = __last - __first; | |
1105 | if (__count > 0) | |
1106 | { | |
1107 | #ifdef __cpp_lib_is_constant_evaluated | |
1108 | if (std::is_constant_evaluated()) | |
1109 | { | |
1110 | // Can't use memmove. Wrap the pointer so that __relocate_a_1 | |
1111 | // resolves to the non-trivial overload above. | |
1112 | __gnu_cxx::__normal_iterator<_Tp*, void> __out(__result); | |
1113 | __out = std::__relocate_a_1(__first, __last, __out, __alloc); | |
1114 | return __out.base(); | |
1115 | } | |
1116 | #endif | |
1117 | __builtin_memmove(__result, __first, __count * sizeof(_Tp)); | |
1118 | } | |
1119 | return __result + __count; | |
1120 | } | |
1121 | ||
1122 | ||
0f317ef7 MG |
1123 | template <typename _InputIterator, typename _ForwardIterator, |
1124 | typename _Allocator> | |
1ae8edf5 | 1125 | _GLIBCXX20_CONSTEXPR |
0f317ef7 MG |
1126 | inline _ForwardIterator |
1127 | __relocate_a(_InputIterator __first, _InputIterator __last, | |
1128 | _ForwardIterator __result, _Allocator& __alloc) | |
ff2e7f19 MG |
1129 | noexcept(noexcept(__relocate_a_1(std::__niter_base(__first), |
1130 | std::__niter_base(__last), | |
1131 | std::__niter_base(__result), __alloc))) | |
0f317ef7 | 1132 | { |
33adfd0d JW |
1133 | return std::__relocate_a_1(std::__niter_base(__first), |
1134 | std::__niter_base(__last), | |
1135 | std::__niter_base(__result), __alloc); | |
0f317ef7 | 1136 | } |
302b6996 JW |
1137 | |
1138 | /// @endcond | |
0f317ef7 MG |
1139 | #endif |
1140 | ||
f0b88346 | 1141 | /// @} group memory |
302b6996 | 1142 | |
12ffa228 BK |
1143 | _GLIBCXX_END_NAMESPACE_VERSION |
1144 | } // namespace | |
725dc051 | 1145 | |
3d7c150e | 1146 | #endif /* _STL_UNINITIALIZED_H */ |