1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
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
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
11 #define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
12 
13 #include <__algorithm/in_out_result.h>
14 #include <__concepts/constructible.h>
15 #include <__config>
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>
28 #include <new>
29 
30 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
31 #  pragma GCC system_header
32 #endif
33 
34 _LIBCPP_PUSH_MACROS
35 #include <__undef_macros>
36 
37 _LIBCPP_BEGIN_NAMESPACE_STD
38 
39 #if _LIBCPP_STD_VER >= 20
40 
41 namespace ranges {
42 
43 // uninitialized_default_construct
44 
45 namespace __uninitialized_default_construct {
46 
47 struct __fn {
48   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
49     requires default_initializable<iter_value_t<_ForwardIterator>>
operator__fn50   _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
51     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
52     return std::__uninitialized_default_construct<_ValueType>(std::move(__first), std::move(__last));
53   }
54 
55   template <__nothrow_forward_range _ForwardRange>
56     requires default_initializable<range_value_t<_ForwardRange>>
operator__fn57   _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
58     return (*this)(ranges::begin(__range), ranges::end(__range));
59   }
60 };
61 
62 } // namespace __uninitialized_default_construct
63 
64 inline namespace __cpo {
65 inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{};
66 } // namespace __cpo
67 
68 // uninitialized_default_construct_n
69 
70 namespace __uninitialized_default_construct_n {
71 
72 struct __fn {
73   template <__nothrow_forward_iterator _ForwardIterator>
74     requires default_initializable<iter_value_t<_ForwardIterator>>
75   _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator__fn76   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n) const {
77     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
78     return std::__uninitialized_default_construct_n<_ValueType>(std::move(__first), __n);
79   }
80 };
81 
82 } // namespace __uninitialized_default_construct_n
83 
84 inline namespace __cpo {
85 inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{};
86 } // namespace __cpo
87 
88 // uninitialized_value_construct
89 
90 namespace __uninitialized_value_construct {
91 
92 struct __fn {
93   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
94     requires default_initializable<iter_value_t<_ForwardIterator>>
operator__fn95   _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
96     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
97     return std::__uninitialized_value_construct<_ValueType>(std::move(__first), std::move(__last));
98   }
99 
100   template <__nothrow_forward_range _ForwardRange>
101     requires default_initializable<range_value_t<_ForwardRange>>
operator__fn102   _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
103     return (*this)(ranges::begin(__range), ranges::end(__range));
104   }
105 };
106 
107 } // namespace __uninitialized_value_construct
108 
109 inline namespace __cpo {
110 inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{};
111 } // namespace __cpo
112 
113 // uninitialized_value_construct_n
114 
115 namespace __uninitialized_value_construct_n {
116 
117 struct __fn {
118   template <__nothrow_forward_iterator _ForwardIterator>
119     requires default_initializable<iter_value_t<_ForwardIterator>>
120   _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator__fn121   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n) const {
122     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
123     return std::__uninitialized_value_construct_n<_ValueType>(std::move(__first), __n);
124   }
125 };
126 
127 } // namespace __uninitialized_value_construct_n
128 
129 inline namespace __cpo {
130 inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{};
131 } // namespace __cpo
132 
133 // uninitialized_fill
134 
135 namespace __uninitialized_fill {
136 
137 struct __fn {
138   template <__nothrow_forward_iterator _ForwardIterator, __nothrow_sentinel_for<_ForwardIterator> _Sentinel, class _Tp>
139     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
operator__fn140   _LIBCPP_HIDE_FROM_ABI _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
141     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
142     return std::__uninitialized_fill<_ValueType>(std::move(__first), std::move(__last), __x);
143   }
144 
145   template <__nothrow_forward_range _ForwardRange, class _Tp>
146     requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
operator__fn147   _LIBCPP_HIDE_FROM_ABI borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
148     return (*this)(ranges::begin(__range), ranges::end(__range), __x);
149   }
150 };
151 
152 } // namespace __uninitialized_fill
153 
154 inline namespace __cpo {
155 inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{};
156 } // namespace __cpo
157 
158 // uninitialized_fill_n
159 
160 namespace __uninitialized_fill_n {
161 
162 struct __fn {
163   template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
164     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
165   _LIBCPP_HIDE_FROM_ABI _ForwardIterator
operator__fn166   operator()(_ForwardIterator __first, iter_difference_t<_ForwardIterator> __n, const _Tp& __x) const {
167     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
168     return std::__uninitialized_fill_n<_ValueType>(std::move(__first), __n, __x);
169   }
170 };
171 
172 } // namespace __uninitialized_fill_n
173 
174 inline namespace __cpo {
175 inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{};
176 } // namespace __cpo
177 
178 // uninitialized_copy
179 
180 template <class _InputIterator, class _OutputIterator>
181 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
182 
183 namespace __uninitialized_copy {
184 
185 struct __fn {
186   template <input_iterator _InputIterator,
187             sentinel_for<_InputIterator> _Sentinel1,
188             __nothrow_forward_iterator _OutputIterator,
189             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
190     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
191   _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<_InputIterator, _OutputIterator>
operator__fn192   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
193     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
194 
195     auto __stop_copying = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
196     auto __result       = std::__uninitialized_copy<_ValueType>(
197         std::move(__ifirst), std::move(__ilast), std::move(__ofirst), __stop_copying);
198     return {std::move(__result.first), std::move(__result.second)};
199   }
200 
201   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
202     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
203   _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
operator__fn204   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
205     return (*this)(
206         ranges::begin(__in_range), ranges::end(__in_range), ranges::begin(__out_range), ranges::end(__out_range));
207   }
208 };
209 
210 } // namespace __uninitialized_copy
211 
212 inline namespace __cpo {
213 inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{};
214 } // namespace __cpo
215 
216 // uninitialized_copy_n
217 
218 template <class _InputIterator, class _OutputIterator>
219 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
220 
221 namespace __uninitialized_copy_n {
222 
223 struct __fn {
224   template <input_iterator _InputIterator,
225             __nothrow_forward_iterator _OutputIterator,
226             __nothrow_sentinel_for<_OutputIterator> _Sentinel>
227     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
228   _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator>
operator__fn229   operator()(_InputIterator __ifirst,
230              iter_difference_t<_InputIterator> __n,
231              _OutputIterator __ofirst,
232              _Sentinel __olast) const {
233     using _ValueType    = remove_reference_t<iter_reference_t<_OutputIterator>>;
234     auto __stop_copying = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
235     auto __result =
236         std::__uninitialized_copy_n<_ValueType>(std::move(__ifirst), __n, std::move(__ofirst), __stop_copying);
237     return {std::move(__result.first), std::move(__result.second)};
238   }
239 };
240 
241 } // namespace __uninitialized_copy_n
242 
243 inline namespace __cpo {
244 inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{};
245 } // namespace __cpo
246 
247 // uninitialized_move
248 
249 template <class _InputIterator, class _OutputIterator>
250 using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>;
251 
252 namespace __uninitialized_move {
253 
254 struct __fn {
255   template <input_iterator _InputIterator,
256             sentinel_for<_InputIterator> _Sentinel1,
257             __nothrow_forward_iterator _OutputIterator,
258             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
259     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
260   _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<_InputIterator, _OutputIterator>
operator__fn261   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
262     using _ValueType   = remove_reference_t<iter_reference_t<_OutputIterator>>;
263     auto __iter_move   = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
264     auto __stop_moving = [&__olast](auto&& __out_iter) -> bool { return __out_iter == __olast; };
265     auto __result      = std::__uninitialized_move<_ValueType>(
266         std::move(__ifirst), std::move(__ilast), std::move(__ofirst), __stop_moving, __iter_move);
267     return {std::move(__result.first), std::move(__result.second)};
268   }
269 
270   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
271     requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
272   _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
operator__fn273   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
274     return (*this)(
275         ranges::begin(__in_range), ranges::end(__in_range), ranges::begin(__out_range), ranges::end(__out_range));
276   }
277 };
278 
279 } // namespace __uninitialized_move
280 
281 inline namespace __cpo {
282 inline constexpr auto uninitialized_move = __uninitialized_move::__fn{};
283 } // namespace __cpo
284 
285 // uninitialized_move_n
286 
287 template <class _InputIterator, class _OutputIterator>
288 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
289 
290 namespace __uninitialized_move_n {
291 
292 struct __fn {
293   template <input_iterator _InputIterator,
294             __nothrow_forward_iterator _OutputIterator,
295             __nothrow_sentinel_for<_OutputIterator> _Sentinel>
296     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
297   _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator>
operator__fn298   operator()(_InputIterator __ifirst,
299              iter_difference_t<_InputIterator> __n,
300              _OutputIterator __ofirst,
301              _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) -> bool { 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 {std::move(__result.first), std::move(__result.second)};
308   }
309 };
310 
311 } // namespace __uninitialized_move_n
312 
313 inline namespace __cpo {
314 inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{};
315 } // namespace __cpo
316 
317 } // namespace ranges
318 
319 #endif // _LIBCPP_STD_VER >= 20
320 
321 _LIBCPP_END_NAMESPACE_STD
322 
323 _LIBCPP_POP_MACROS
324 
325 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
326