2 //===----------------------------------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
11 #define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H
14 #include <__memory/addressof.h>
15 #include <__memory/construct_at.h>
16 #include <__memory/voidify.h>
20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
21 #pragma GCC system_header
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 // This is a simplified version of C++20 `unreachable_sentinel` that doesn't use concepts and thus can be used in any
28 struct __unreachable_sentinel
{
29 template <class _Iter
>
30 _LIBCPP_HIDE_FROM_ABI
friend _LIBCPP_CONSTEXPR
bool operator!=(const _Iter
&, __unreachable_sentinel
) _NOEXCEPT
{
37 template <class _ValueType
, class _InputIterator
, class _Sentinel1
, class _ForwardIterator
, class _Sentinel2
>
38 inline _LIBCPP_HIDE_FROM_ABI pair
<_InputIterator
, _ForwardIterator
>
39 __uninitialized_copy(_InputIterator __ifirst
, _Sentinel1 __ilast
,
40 _ForwardIterator __ofirst
, _Sentinel2 __olast
) {
41 _ForwardIterator __idx
= __ofirst
;
42 #ifndef _LIBCPP_NO_EXCEPTIONS
45 for (; __ifirst
!= __ilast
&& __idx
!= __olast
; ++__ifirst
, (void)++__idx
)
46 ::new (_VSTD::__voidify(*__idx
)) _ValueType(*__ifirst
);
47 #ifndef _LIBCPP_NO_EXCEPTIONS
49 _VSTD::__destroy(__ofirst
, __idx
);
54 return pair
<_InputIterator
, _ForwardIterator
>(_VSTD::move(__ifirst
), _VSTD::move(__idx
));
57 template <class _InputIterator
, class _ForwardIterator
>
58 _ForwardIterator
uninitialized_copy(_InputIterator __ifirst
, _InputIterator __ilast
,
59 _ForwardIterator __ofirst
) {
60 typedef typename iterator_traits
<_ForwardIterator
>::value_type _ValueType
;
61 auto __result
= _VSTD::__uninitialized_copy
<_ValueType
>(_VSTD::move(__ifirst
), _VSTD::move(__ilast
),
62 _VSTD::move(__ofirst
), __unreachable_sentinel());
63 return _VSTD::move(__result
.second
);
66 // uninitialized_copy_n
68 template <class _ValueType
, class _InputIterator
, class _Size
, class _ForwardIterator
, class _Sentinel
>
69 inline _LIBCPP_HIDE_FROM_ABI pair
<_InputIterator
, _ForwardIterator
>
70 __uninitialized_copy_n(_InputIterator __ifirst
, _Size __n
,
71 _ForwardIterator __ofirst
, _Sentinel __olast
) {
72 _ForwardIterator __idx
= __ofirst
;
73 #ifndef _LIBCPP_NO_EXCEPTIONS
76 for (; __n
> 0 && __idx
!= __olast
; ++__ifirst
, (void)++__idx
, (void)--__n
)
77 ::new (_VSTD::__voidify(*__idx
)) _ValueType(*__ifirst
);
78 #ifndef _LIBCPP_NO_EXCEPTIONS
80 _VSTD::__destroy(__ofirst
, __idx
);
85 return pair
<_InputIterator
, _ForwardIterator
>(_VSTD::move(__ifirst
), _VSTD::move(__idx
));
88 template <class _InputIterator
, class _Size
, class _ForwardIterator
>
89 inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
uninitialized_copy_n(_InputIterator __ifirst
, _Size __n
,
90 _ForwardIterator __ofirst
) {
91 typedef typename iterator_traits
<_ForwardIterator
>::value_type _ValueType
;
92 auto __result
= _VSTD::__uninitialized_copy_n
<_ValueType
>(_VSTD::move(__ifirst
), __n
, _VSTD::move(__ofirst
),
93 __unreachable_sentinel());
94 return _VSTD::move(__result
.second
);
99 template <class _ValueType
, class _ForwardIterator
, class _Sentinel
, class _Tp
>
100 inline _LIBCPP_HIDE_FROM_ABI
101 _ForwardIterator
__uninitialized_fill(_ForwardIterator __first
, _Sentinel __last
, const _Tp
& __x
)
103 _ForwardIterator __idx
= __first
;
104 #ifndef _LIBCPP_NO_EXCEPTIONS
108 for (; __idx
!= __last
; ++__idx
)
109 ::new (_VSTD::__voidify(*__idx
)) _ValueType(__x
);
110 #ifndef _LIBCPP_NO_EXCEPTIONS
114 _VSTD::__destroy(__first
, __idx
);
122 template <class _ForwardIterator
, class _Tp
>
123 inline _LIBCPP_HIDE_FROM_ABI
124 void uninitialized_fill(_ForwardIterator __first
, _ForwardIterator __last
, const _Tp
& __x
)
126 typedef typename iterator_traits
<_ForwardIterator
>::value_type _ValueType
;
127 (void)_VSTD::__uninitialized_fill
<_ValueType
>(__first
, __last
, __x
);
130 // uninitialized_fill_n
132 template <class _ValueType
, class _ForwardIterator
, class _Size
, class _Tp
>
133 inline _LIBCPP_HIDE_FROM_ABI
134 _ForwardIterator
__uninitialized_fill_n(_ForwardIterator __first
, _Size __n
, const _Tp
& __x
)
136 _ForwardIterator __idx
= __first
;
137 #ifndef _LIBCPP_NO_EXCEPTIONS
141 for (; __n
> 0; ++__idx
, (void) --__n
)
142 ::new (_VSTD::__voidify(*__idx
)) _ValueType(__x
);
143 #ifndef _LIBCPP_NO_EXCEPTIONS
147 _VSTD::__destroy(__first
, __idx
);
155 template <class _ForwardIterator
, class _Size
, class _Tp
>
156 inline _LIBCPP_HIDE_FROM_ABI
157 _ForwardIterator
uninitialized_fill_n(_ForwardIterator __first
, _Size __n
, const _Tp
& __x
)
159 typedef typename iterator_traits
<_ForwardIterator
>::value_type _ValueType
;
160 return _VSTD::__uninitialized_fill_n
<_ValueType
>(__first
, __n
, __x
);
163 #if _LIBCPP_STD_VER > 14
165 // uninitialized_default_construct
167 template <class _ValueType
, class _ForwardIterator
, class _Sentinel
>
168 inline _LIBCPP_HIDE_FROM_ABI
169 _ForwardIterator
__uninitialized_default_construct(_ForwardIterator __first
, _Sentinel __last
) {
170 auto __idx
= __first
;
171 #ifndef _LIBCPP_NO_EXCEPTIONS
174 for (; __idx
!= __last
; ++__idx
)
175 ::new (_VSTD::__voidify(*__idx
)) _ValueType
;
176 #ifndef _LIBCPP_NO_EXCEPTIONS
178 _VSTD::__destroy(__first
, __idx
);
186 template <class _ForwardIterator
>
187 inline _LIBCPP_HIDE_FROM_ABI
188 void uninitialized_default_construct(_ForwardIterator __first
, _ForwardIterator __last
) {
189 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
190 (void)_VSTD::__uninitialized_default_construct
<_ValueType
>(
191 _VSTD::move(__first
), _VSTD::move(__last
));
194 // uninitialized_default_construct_n
196 template <class _ValueType
, class _ForwardIterator
, class _Size
>
197 inline _LIBCPP_HIDE_FROM_ABI
198 _ForwardIterator
__uninitialized_default_construct_n(_ForwardIterator __first
, _Size __n
) {
199 auto __idx
= __first
;
200 #ifndef _LIBCPP_NO_EXCEPTIONS
203 for (; __n
> 0; ++__idx
, (void) --__n
)
204 ::new (_VSTD::__voidify(*__idx
)) _ValueType
;
205 #ifndef _LIBCPP_NO_EXCEPTIONS
207 _VSTD::__destroy(__first
, __idx
);
215 template <class _ForwardIterator
, class _Size
>
216 inline _LIBCPP_HIDE_FROM_ABI
217 _ForwardIterator
uninitialized_default_construct_n(_ForwardIterator __first
, _Size __n
) {
218 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
219 return _VSTD::__uninitialized_default_construct_n
<_ValueType
>(_VSTD::move(__first
), __n
);
222 // uninitialized_value_construct
224 template <class _ValueType
, class _ForwardIterator
, class _Sentinel
>
225 inline _LIBCPP_HIDE_FROM_ABI
226 _ForwardIterator
__uninitialized_value_construct(_ForwardIterator __first
, _Sentinel __last
) {
227 auto __idx
= __first
;
228 #ifndef _LIBCPP_NO_EXCEPTIONS
231 for (; __idx
!= __last
; ++__idx
)
232 ::new (_VSTD::__voidify(*__idx
)) _ValueType();
233 #ifndef _LIBCPP_NO_EXCEPTIONS
235 _VSTD::__destroy(__first
, __idx
);
243 template <class _ForwardIterator
>
244 inline _LIBCPP_HIDE_FROM_ABI
245 void uninitialized_value_construct(_ForwardIterator __first
, _ForwardIterator __last
) {
246 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
247 (void)_VSTD::__uninitialized_value_construct
<_ValueType
>(
248 _VSTD::move(__first
), _VSTD::move(__last
));
251 // uninitialized_value_construct_n
253 template <class _ValueType
, class _ForwardIterator
, class _Size
>
254 inline _LIBCPP_HIDE_FROM_ABI
255 _ForwardIterator
__uninitialized_value_construct_n(_ForwardIterator __first
, _Size __n
) {
256 auto __idx
= __first
;
257 #ifndef _LIBCPP_NO_EXCEPTIONS
260 for (; __n
> 0; ++__idx
, (void) --__n
)
261 ::new (_VSTD::__voidify(*__idx
)) _ValueType();
262 #ifndef _LIBCPP_NO_EXCEPTIONS
264 _VSTD::__destroy(__first
, __idx
);
272 template <class _ForwardIterator
, class _Size
>
273 inline _LIBCPP_HIDE_FROM_ABI
274 _ForwardIterator
uninitialized_value_construct_n(_ForwardIterator __first
, _Size __n
) {
275 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
276 return __uninitialized_value_construct_n
<_ValueType
>(_VSTD::move(__first
), __n
);
279 // uninitialized_move
281 template <class _ValueType
, class _InputIterator
, class _Sentinel1
, class _ForwardIterator
, class _Sentinel2
,
283 inline _LIBCPP_HIDE_FROM_ABI pair
<_InputIterator
, _ForwardIterator
>
284 __uninitialized_move(_InputIterator __ifirst
, _Sentinel1 __ilast
,
285 _ForwardIterator __ofirst
, _Sentinel2 __olast
, _IterMove __iter_move
) {
286 auto __idx
= __ofirst
;
287 #ifndef _LIBCPP_NO_EXCEPTIONS
290 for (; __ifirst
!= __ilast
&& __idx
!= __olast
; ++__idx
, (void)++__ifirst
) {
291 ::new (_VSTD::__voidify(*__idx
)) _ValueType(__iter_move(__ifirst
));
293 #ifndef _LIBCPP_NO_EXCEPTIONS
295 _VSTD::__destroy(__ofirst
, __idx
);
300 return {_VSTD::move(__ifirst
), _VSTD::move(__idx
)};
303 template <class _InputIterator
, class _ForwardIterator
>
304 inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator
uninitialized_move(_InputIterator __ifirst
, _InputIterator __ilast
,
305 _ForwardIterator __ofirst
) {
306 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
307 auto __iter_move
= [](auto&& __iter
) -> decltype(auto) { return _VSTD::move(*__iter
); };
309 auto __result
= _VSTD::__uninitialized_move
<_ValueType
>(_VSTD::move(__ifirst
), _VSTD::move(__ilast
),
310 _VSTD::move(__ofirst
), __unreachable_sentinel(), __iter_move
);
311 return _VSTD::move(__result
.second
);
314 // uninitialized_move_n
316 template <class _ValueType
, class _InputIterator
, class _Size
, class _ForwardIterator
, class _Sentinel
, class _IterMove
>
317 inline _LIBCPP_HIDE_FROM_ABI pair
<_InputIterator
, _ForwardIterator
>
318 __uninitialized_move_n(_InputIterator __ifirst
, _Size __n
,
319 _ForwardIterator __ofirst
, _Sentinel __olast
, _IterMove __iter_move
) {
320 auto __idx
= __ofirst
;
321 #ifndef _LIBCPP_NO_EXCEPTIONS
324 for (; __n
> 0 && __idx
!= __olast
; ++__idx
, (void)++__ifirst
, --__n
)
325 ::new (_VSTD::__voidify(*__idx
)) _ValueType(__iter_move(__ifirst
));
326 #ifndef _LIBCPP_NO_EXCEPTIONS
328 _VSTD::__destroy(__ofirst
, __idx
);
333 return {_VSTD::move(__ifirst
), _VSTD::move(__idx
)};
336 template <class _InputIterator
, class _Size
, class _ForwardIterator
>
337 inline _LIBCPP_HIDE_FROM_ABI pair
<_InputIterator
, _ForwardIterator
>
338 uninitialized_move_n(_InputIterator __ifirst
, _Size __n
, _ForwardIterator __ofirst
) {
339 using _ValueType
= typename iterator_traits
<_ForwardIterator
>::value_type
;
340 auto __iter_move
= [](auto&& __iter
) -> decltype(auto) { return _VSTD::move(*__iter
); };
342 return _VSTD::__uninitialized_move_n
<_ValueType
>(_VSTD::move(__ifirst
), __n
, _VSTD::move(__ofirst
),
343 __unreachable_sentinel(), __iter_move
);
346 #endif // _LIBCPP_STD_VER > 14
348 _LIBCPP_END_NAMESPACE_STD
350 #endif // _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H