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
35 #include <__undef_macros>
37 _LIBCPP_BEGIN_NAMESPACE_STD
39 #if _LIBCPP_STD_VER >= 20
43 // uninitialized_default_construct
45 struct __uninitialized_default_construct
{
46 template <__nothrow_forward_iterator _ForwardIterator
, __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 std::__uninitialized_default_construct
<_ValueType
>(std::move(__first
), std::move(__last
));
53 template <__nothrow_forward_range _ForwardRange
>
54 requires default_initializable
<range_value_t
<_ForwardRange
>>
55 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
) const {
56 return (*this)(ranges::begin(__range
), ranges::end(__range
));
60 inline namespace __cpo
{
61 inline constexpr auto uninitialized_default_construct
= __uninitialized_default_construct
{};
64 // uninitialized_default_construct_n
66 struct __uninitialized_default_construct_n
{
67 template <__nothrow_forward_iterator _ForwardIterator
>
68 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
69 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
70 operator()(_ForwardIterator __first
, iter_difference_t
<_ForwardIterator
> __n
) const {
71 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
72 return std::__uninitialized_default_construct_n
<_ValueType
>(std::move(__first
), __n
);
76 inline namespace __cpo
{
77 inline constexpr auto uninitialized_default_construct_n
= __uninitialized_default_construct_n
{};
80 // uninitialized_value_construct
82 struct __uninitialized_value_construct
{
83 template <__nothrow_forward_iterator _ForwardIterator
, __nothrow_sentinel_for
<_ForwardIterator
> _Sentinel
>
84 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
85 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
, _Sentinel __last
) const {
86 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
87 return std::__uninitialized_value_construct
<_ValueType
>(std::move(__first
), std::move(__last
));
90 template <__nothrow_forward_range _ForwardRange
>
91 requires default_initializable
<range_value_t
<_ForwardRange
>>
92 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
) const {
93 return (*this)(ranges::begin(__range
), ranges::end(__range
));
97 inline namespace __cpo
{
98 inline constexpr auto uninitialized_value_construct
= __uninitialized_value_construct
{};
101 // uninitialized_value_construct_n
103 struct __uninitialized_value_construct_n
{
104 template <__nothrow_forward_iterator _ForwardIterator
>
105 requires default_initializable
<iter_value_t
<_ForwardIterator
>>
106 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
107 operator()(_ForwardIterator __first
, iter_difference_t
<_ForwardIterator
> __n
) const {
108 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
109 return std::__uninitialized_value_construct_n
<_ValueType
>(std::move(__first
), __n
);
113 inline namespace __cpo
{
114 inline constexpr auto uninitialized_value_construct_n
= __uninitialized_value_construct_n
{};
117 // uninitialized_fill
119 struct __uninitialized_fill
{
120 template <__nothrow_forward_iterator _ForwardIterator
, __nothrow_sentinel_for
<_ForwardIterator
> _Sentinel
, class _Tp
>
121 requires constructible_from
<iter_value_t
<_ForwardIterator
>, const _Tp
&>
122 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator()(_ForwardIterator __first
, _Sentinel __last
, const _Tp
& __x
) const {
123 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
124 return std::__uninitialized_fill
<_ValueType
>(std::move(__first
), std::move(__last
), __x
);
127 template <__nothrow_forward_range _ForwardRange
, class _Tp
>
128 requires constructible_from
<range_value_t
<_ForwardRange
>, const _Tp
&>
129 _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t
<_ForwardRange
> operator()(_ForwardRange
&& __range
, const _Tp
& __x
) const {
130 return (*this)(ranges::begin(__range
), ranges::end(__range
), __x
);
134 inline namespace __cpo
{
135 inline constexpr auto uninitialized_fill
= __uninitialized_fill
{};
138 // uninitialized_fill_n
140 struct __uninitialized_fill_n
{
141 template <__nothrow_forward_iterator _ForwardIterator
, class _Tp
>
142 requires constructible_from
<iter_value_t
<_ForwardIterator
>, const _Tp
&>
143 _LIBCPP_HIDE_FROM_ABI _ForwardIterator
144 operator()(_ForwardIterator __first
, iter_difference_t
<_ForwardIterator
> __n
, const _Tp
& __x
) const {
145 using _ValueType
= remove_reference_t
<iter_reference_t
<_ForwardIterator
>>;
146 return std::__uninitialized_fill_n
<_ValueType
>(std::move(__first
), __n
, __x
);
150 inline namespace __cpo
{
151 inline constexpr auto uninitialized_fill_n
= __uninitialized_fill_n
{};
154 // uninitialized_copy
156 template <class _InputIterator
, class _OutputIterator
>
157 using uninitialized_copy_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
159 struct __uninitialized_copy
{
160 template <input_iterator _InputIterator
,
161 sentinel_for
<_InputIterator
> _Sentinel1
,
162 __nothrow_forward_iterator _OutputIterator
,
163 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel2
>
164 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_reference_t
<_InputIterator
>>
165 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result
<_InputIterator
, _OutputIterator
>
166 operator()(_InputIterator __ifirst
, _Sentinel1 __ilast
, _OutputIterator __ofirst
, _Sentinel2 __olast
) const {
167 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
169 auto __stop_copying
= [&__olast
](auto&& __out_iter
) -> bool { return __out_iter
== __olast
; };
170 auto __result
= std::__uninitialized_copy
<_ValueType
>(
171 std::move(__ifirst
), std::move(__ilast
), std::move(__ofirst
), __stop_copying
);
172 return {std::move(__result
.first
), std::move(__result
.second
)};
175 template <input_range _InputRange
, __nothrow_forward_range _OutputRange
>
176 requires constructible_from
<range_value_t
<_OutputRange
>, range_reference_t
<_InputRange
>>
177 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result
<borrowed_iterator_t
<_InputRange
>, borrowed_iterator_t
<_OutputRange
>>
178 operator()(_InputRange
&& __in_range
, _OutputRange
&& __out_range
) const {
180 ranges::begin(__in_range
), ranges::end(__in_range
), ranges::begin(__out_range
), ranges::end(__out_range
));
184 inline namespace __cpo
{
185 inline constexpr auto uninitialized_copy
= __uninitialized_copy
{};
188 // uninitialized_copy_n
190 template <class _InputIterator
, class _OutputIterator
>
191 using uninitialized_copy_n_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
193 struct __uninitialized_copy_n
{
194 template <input_iterator _InputIterator
,
195 __nothrow_forward_iterator _OutputIterator
,
196 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel
>
197 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_reference_t
<_InputIterator
>>
198 _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result
<_InputIterator
, _OutputIterator
>
199 operator()(_InputIterator __ifirst
,
200 iter_difference_t
<_InputIterator
> __n
,
201 _OutputIterator __ofirst
,
202 _Sentinel __olast
) const {
203 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
204 auto __stop_copying
= [&__olast
](auto&& __out_iter
) -> bool { return __out_iter
== __olast
; };
206 std::__uninitialized_copy_n
<_ValueType
>(std::move(__ifirst
), __n
, std::move(__ofirst
), __stop_copying
);
207 return {std::move(__result
.first
), std::move(__result
.second
)};
211 inline namespace __cpo
{
212 inline constexpr auto uninitialized_copy_n
= __uninitialized_copy_n
{};
215 // uninitialized_move
217 template <class _InputIterator
, class _OutputIterator
>
218 using uninitialized_move_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
220 struct __uninitialized_move
{
221 template <input_iterator _InputIterator
,
222 sentinel_for
<_InputIterator
> _Sentinel1
,
223 __nothrow_forward_iterator _OutputIterator
,
224 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel2
>
225 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_rvalue_reference_t
<_InputIterator
>>
226 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result
<_InputIterator
, _OutputIterator
>
227 operator()(_InputIterator __ifirst
, _Sentinel1 __ilast
, _OutputIterator __ofirst
, _Sentinel2 __olast
) const {
228 using _ValueType
= remove_reference_t
<iter_reference_t
<_OutputIterator
>>;
229 auto __iter_move
= [](auto&& __iter
) -> decltype(auto) { return ranges::iter_move(__iter
); };
230 auto __stop_moving
= [&__olast
](auto&& __out_iter
) -> bool { return __out_iter
== __olast
; };
231 auto __result
= std::__uninitialized_move
<_ValueType
>(
232 std::move(__ifirst
), std::move(__ilast
), std::move(__ofirst
), __stop_moving
, __iter_move
);
233 return {std::move(__result
.first
), std::move(__result
.second
)};
236 template <input_range _InputRange
, __nothrow_forward_range _OutputRange
>
237 requires constructible_from
<range_value_t
<_OutputRange
>, range_rvalue_reference_t
<_InputRange
>>
238 _LIBCPP_HIDE_FROM_ABI uninitialized_move_result
<borrowed_iterator_t
<_InputRange
>, borrowed_iterator_t
<_OutputRange
>>
239 operator()(_InputRange
&& __in_range
, _OutputRange
&& __out_range
) const {
241 ranges::begin(__in_range
), ranges::end(__in_range
), ranges::begin(__out_range
), ranges::end(__out_range
));
245 inline namespace __cpo
{
246 inline constexpr auto uninitialized_move
= __uninitialized_move
{};
249 // uninitialized_move_n
251 template <class _InputIterator
, class _OutputIterator
>
252 using uninitialized_move_n_result
= in_out_result
<_InputIterator
, _OutputIterator
>;
254 struct __uninitialized_move_n
{
255 template <input_iterator _InputIterator
,
256 __nothrow_forward_iterator _OutputIterator
,
257 __nothrow_sentinel_for
<_OutputIterator
> _Sentinel
>
258 requires constructible_from
<iter_value_t
<_OutputIterator
>, iter_rvalue_reference_t
<_InputIterator
>>
259 _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result
<_InputIterator
, _OutputIterator
>
260 operator()(_InputIterator __ifirst
,
261 iter_difference_t
<_InputIterator
> __n
,
262 _OutputIterator __ofirst
,
263 _Sentinel __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
) -> bool { return __out_iter
== __olast
; };
267 auto __result
= std::__uninitialized_move_n
<_ValueType
>(
268 std::move(__ifirst
), __n
, std::move(__ofirst
), __stop_moving
, __iter_move
);
269 return {std::move(__result
.first
), std::move(__result
.second
)};
273 inline namespace __cpo
{
274 inline constexpr auto uninitialized_move_n
= __uninitialized_move_n
{};
277 } // namespace ranges
279 #endif // _LIBCPP_STD_VER >= 20
281 _LIBCPP_END_NAMESPACE_STD
285 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H