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_RANGES_UNINITIALIZED_ALGORITHMS_H
11 #define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
13 #include <__algorithm/in_out_result.h>
14 #include <__concepts/constructible.h>
16 #include <__iterator/concepts.h>
17 #include <__iterator/incrementable_traits.h>
18 #include <__iterator/iter_move.h>
19 #include <__iterator/iterator_traits.h>
20 #include <__iterator/readable_traits.h>
21 #include <__memory/concepts.h>
22 #include <__memory/uninitialized_algorithms.h>
23 #include <__ranges/access.h>
24 #include <__ranges/concepts.h>
25 #include <__ranges/dangling.h>
26 #include <__type_traits/remove_reference.h>
27 #include <__utility/move.h>
30 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31 # pragma GCC system_header
34 _LIBCPP_BEGIN_NAMESPACE_STD
36 #if _LIBCPP_STD_VER >= 20
40 // uninitialized_default_construct
42 namespace __uninitialized_default_construct
{
45 template <__nothrow_forward_iterator _ForwardIterator
,
46 __nothrow_sentinel_for
<_ForwardIterator
> _Sentinel
>
47 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
48 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
, _Sentinel __last
) const {
49 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
50 return _VSTD::__uninitialized_default_construct
<_ValueType
>(
51 _VSTD::move(__first
), _VSTD::move(__last
));
54 template <__nothrow_forward_range _ForwardRange
>
55 requires default_initializable
<range_value_t
<_ForwardRange
>>
56 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
) const {
57 return (*this)(ranges::begin(__range
), ranges::end(__range
));
61 } // namespace __uninitialized_default_construct
63 inline namespace __cpo
{
64 inline constexpr auto uninitialized_default_construct
= __uninitialized_default_construct::__fn
{};
67 // uninitialized_default_construct_n
69 namespace __uninitialized_default_construct_n
{
72 template <__nothrow_forward_iterator _ForwardIterator
>
73 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
74 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
,
75 iter_difference_t
<_ForwardIterator
> __n
) const {
76 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
77 return _VSTD::__uninitialized_default_construct_n
<_ValueType
>(_VSTD::move(__first
), __n
);
81 } // namespace __uninitialized_default_construct_n
83 inline namespace __cpo
{
84 inline constexpr auto uninitialized_default_construct_n
= __uninitialized_default_construct_n::__fn
{};
87 // uninitialized_value_construct
89 namespace __uninitialized_value_construct
{
92 template <__nothrow_forward_iterator _ForwardIterator
,
93 __nothrow_sentinel_for
<_ForwardIterator
> _Sentinel
>
94 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
95 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
, _Sentinel __last
) const {
96 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
97 return _VSTD::__uninitialized_value_construct
<_ValueType
>(
98 _VSTD::move(__first
), _VSTD::move(__last
));
101 template <__nothrow_forward_range _ForwardRange
>
102 requires default_initializable
<range_value_t
<_ForwardRange
>>
103 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
) const {
104 return (*this)(ranges::begin(__range
), ranges::end(__range
));
108 } // namespace __uninitialized_value_construct
110 inline namespace __cpo
{
111 inline constexpr auto uninitialized_value_construct
= __uninitialized_value_construct::__fn
{};
114 // uninitialized_value_construct_n
116 namespace __uninitialized_value_construct_n
{
119 template <__nothrow_forward_iterator _ForwardIterator
>
120 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
121 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
,
122 iter_difference_t
<_ForwardIterator
> __n
) const {
123 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
124 return _VSTD::__uninitialized_value_construct_n
<_ValueType
>(_VSTD::move(__first
), __n
);
128 } // namespace __uninitialized_value_construct_n
130 inline namespace __cpo
{
131 inline constexpr auto uninitialized_value_construct_n
= __uninitialized_value_construct_n::__fn
{};
134 // uninitialized_fill
136 namespace __uninitialized_fill
{
139 template <__nothrow_forward_iterator _ForwardIterator
,
140 __nothrow_sentinel_for
<_ForwardIterator
> _Sentinel
,
142 requires constructible_from
<iter_value_t
<_ForwardIterator
>, const _Tp
&>
143 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
, _Sentinel __last
, const _Tp
& __x
) const {
144 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
145 return _VSTD::__uninitialized_fill
<_ValueType
>(_VSTD::move(__first
), _VSTD::move(__last
), __x
);
148 template <__nothrow_forward_range _ForwardRange
, class _Tp
>
149 requires constructible_from
<range_value_t
<_ForwardRange
>, const _Tp
&>
150 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
, const _Tp
& __x
) const {
151 return (*this)(ranges::begin(__range
), ranges::end(__range
), __x
);
155 } // namespace __uninitialized_fill
157 inline namespace __cpo
{
158 inline constexpr auto uninitialized_fill
= __uninitialized_fill::__fn
{};
161 // uninitialized_fill_n
163 namespace __uninitialized_fill_n
{
166 template <__nothrow_forward_iterator _ForwardIterator
, class _Tp
>
167 requires constructible_from
<iter_value_t
<_ForwardIterator
>, const _Tp
&>
168 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
,
169 iter_difference_t
<_ForwardIterator
> __n
,
170 const _Tp
& __x
) const {
171 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
172 return _VSTD::__uninitialized_fill_n
<_ValueType
>(_VSTD::move(__first
), __n
, __x
);
176 } // namespace __uninitialized_fill_n
178 inline namespace __cpo
{
179 inline constexpr auto uninitialized_fill_n
= __uninitialized_fill_n::__fn
{};
182 // uninitialized_copy
184 template <class _InputIterator
, class _OutputIterator
>
185 using uninitialized_copy_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
187 namespace __uninitialized_copy
{
190 template <input_iterator _InputIterator
,
191 sentinel_for
<_InputIterator
> _Sentinel1
,
192 __nothrow_forward_iterator _OutputIterator
,
193 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel2
>
194 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_reference_t
<_InputIterator
>>
195 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result
<_InputIterator
, _OutputIterator
>
196 operator()(_InputIterator __ifirst
, _Sentinel1 __ilast
, _OutputIterator __ofirst
, _Sentinel2 __olast
) const {
197 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
199 auto __stop_copying
= [&__olast
](auto&& __out_iter
) { return __out_iter
== __olast
; };
200 auto __result
= std::__uninitialized_copy
<_ValueType
>(
201 std::move(__ifirst
), std::move(__ilast
), std::move(__ofirst
), __stop_copying
);
202 return {_VSTD::move(__result
.first
), _VSTD::move(__result
.second
)};
205 template <input_range _InputRange
, __nothrow_forward_range _OutputRange
>
206 requires constructible_from
<range_value_t
<_OutputRange
>, range_reference_t
<_InputRange
>>
207 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result
<borrowed_iterator_t
<_InputRange
>, borrowed_iterator_t
<_OutputRange
>>
208 operator()( _InputRange
&& __in_range
, _OutputRange
&& __out_range
) const {
209 return (*this)(ranges::begin(__in_range
), ranges::end(__in_range
),
210 ranges::begin(__out_range
), ranges::end(__out_range
));
214 } // namespace __uninitialized_copy
216 inline namespace __cpo
{
217 inline constexpr auto uninitialized_copy
= __uninitialized_copy::__fn
{};
220 // uninitialized_copy_n
222 template <class _InputIterator
, class _OutputIterator
>
223 using uninitialized_copy_n_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
225 namespace __uninitialized_copy_n
{
228 template <input_iterator _InputIterator
,
229 __nothrow_forward_iterator _OutputIterator
,
230 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel
>
231 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_reference_t
<_InputIterator
>>
232 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result
<_InputIterator
, _OutputIterator
>
233 operator()(_InputIterator __ifirst
, iter_difference_t
<_InputIterator
> __n
,
234 _OutputIterator __ofirst
, _Sentinel __olast
) const {
235 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
236 auto __stop_copying
= [&__olast
](auto&& __out_iter
) { return __out_iter
== __olast
; };
238 std::__uninitialized_copy_n
<_ValueType
>(std::move(__ifirst
), __n
, std::move(__ofirst
), __stop_copying
);
239 return {_VSTD::move(__result
.first
), _VSTD::move(__result
.second
)};
243 } // namespace __uninitialized_copy_n
245 inline namespace __cpo
{
246 inline constexpr auto uninitialized_copy_n
= __uninitialized_copy_n::__fn
{};
249 // uninitialized_move
251 template <class _InputIterator
, class _OutputIterator
>
252 using uninitialized_move_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
254 namespace __uninitialized_move
{
257 template <input_iterator _InputIterator
,
258 sentinel_for
<_InputIterator
> _Sentinel1
,
259 __nothrow_forward_iterator _OutputIterator
,
260 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel2
>
261 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_rvalue_reference_t
<_InputIterator
>>
262 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result
<_InputIterator
, _OutputIterator
>
263 operator()(_InputIterator __ifirst
, _Sentinel1 __ilast
, _OutputIterator __ofirst
, _Sentinel2 __olast
) const {
264 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
265 auto __iter_move
= [](auto&& __iter
) -> decltype(auto) { return ranges::iter_move(__iter
); };
266 auto __stop_moving
= [&__olast
](auto&& __out_iter
) { return __out_iter
== __olast
; };
267 auto __result
= std::__uninitialized_move
<_ValueType
>(
268 std::move(__ifirst
), std::move(__ilast
), std::move(__ofirst
), __stop_moving
, __iter_move
);
269 return {_VSTD::move(__result
.first
), _VSTD::move(__result
.second
)};
272 template <input_range _InputRange
, __nothrow_forward_range _OutputRange
>
273 requires constructible_from
<range_value_t
<_OutputRange
>, range_rvalue_reference_t
<_InputRange
>>
274 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result
<borrowed_iterator_t
<_InputRange
>, borrowed_iterator_t
<_OutputRange
>>
275 operator()(_InputRange
&& __in_range
, _OutputRange
&& __out_range
) const {
276 return (*this)(ranges::begin(__in_range
), ranges::end(__in_range
),
277 ranges::begin(__out_range
), ranges::end(__out_range
));
281 } // namespace __uninitialized_move
283 inline namespace __cpo
{
284 inline constexpr auto uninitialized_move
= __uninitialized_move::__fn
{};
287 // uninitialized_move_n
289 template <class _InputIterator
, class _OutputIterator
>
290 using uninitialized_move_n_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
292 namespace __uninitialized_move_n
{
295 template <input_iterator _InputIterator
,
296 __nothrow_forward_iterator _OutputIterator
,
297 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel
>
298 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_rvalue_reference_t
<_InputIterator
>>
299 _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result
<_InputIterator
, _OutputIterator
>
300 operator()(_InputIterator __ifirst
, iter_difference_t
<_InputIterator
> __n
,
301 _OutputIterator __ofirst
, _Sentinel __olast
) const {
302 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
303 auto __iter_move
= [](auto&& __iter
) -> decltype(auto) { return ranges::iter_move(__iter
); };
304 auto __stop_moving
= [&__olast
](auto&& __out_iter
) { return __out_iter
== __olast
; };
305 auto __result
= std::__uninitialized_move_n
<_ValueType
>(
306 std::move(__ifirst
), __n
, std::move(__ofirst
), __stop_moving
, __iter_move
);
307 return {_VSTD::move(__result
.first
), _VSTD::move(__result
.second
)};
311 } // namespace __uninitialized_move_n
313 inline namespace __cpo
{
314 inline constexpr auto uninitialized_move_n
= __uninitialized_move_n::__fn
{};
317 } // namespace ranges
319 #endif // _LIBCPP_STD_VER >= 20
321 _LIBCPP_END_NAMESPACE_STD
323 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H