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_BEGIN_NAMESPACE_STD
35 
36 #if _LIBCPP_STD_VER >= 20
37 
38 namespace ranges {
39 
40 // uninitialized_default_construct
41 
42 namespace __uninitialized_default_construct {
43 
44 struct __fn {
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));
52   }
53 
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));
58   }
59 };
60 
61 } // namespace __uninitialized_default_construct
62 
63 inline namespace __cpo {
64   inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{};
65 } // namespace __cpo
66 
67 // uninitialized_default_construct_n
68 
69 namespace __uninitialized_default_construct_n {
70 
71 struct __fn {
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);
78   }
79 };
80 
81 } // namespace __uninitialized_default_construct_n
82 
83 inline namespace __cpo {
84   inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{};
85 } // namespace __cpo
86 
87 // uninitialized_value_construct
88 
89 namespace __uninitialized_value_construct {
90 
91 struct __fn {
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));
99   }
100 
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));
105   }
106 };
107 
108 } // namespace __uninitialized_value_construct
109 
110 inline namespace __cpo {
111   inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{};
112 } // namespace __cpo
113 
114 // uninitialized_value_construct_n
115 
116 namespace __uninitialized_value_construct_n {
117 
118 struct __fn {
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);
125   }
126 };
127 
128 } // namespace __uninitialized_value_construct_n
129 
130 inline namespace __cpo {
131   inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{};
132 } // namespace __cpo
133 
134 // uninitialized_fill
135 
136 namespace __uninitialized_fill {
137 
138 struct __fn {
139   template <__nothrow_forward_iterator _ForwardIterator,
140             __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
141             class _Tp>
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);
146   }
147 
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);
152   }
153 };
154 
155 } // namespace __uninitialized_fill
156 
157 inline namespace __cpo {
158   inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{};
159 } // namespace __cpo
160 
161 // uninitialized_fill_n
162 
163 namespace __uninitialized_fill_n {
164 
165 struct __fn {
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);
173   }
174 };
175 
176 } // namespace __uninitialized_fill_n
177 
178 inline namespace __cpo {
179   inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{};
180 } // namespace __cpo
181 
182 // uninitialized_copy
183 
184 template <class _InputIterator, class _OutputIterator>
185 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
186 
187 namespace __uninitialized_copy {
188 
189 struct __fn {
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>>;
198 
199     auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
200                                                             _VSTD::move(__ofirst), _VSTD::move(__olast));
201     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
202   }
203 
204   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
205     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
206   _LIBCPP_HIDE_FROM_ABI uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
207   operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const {
208     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
209                    ranges::begin(__out_range), ranges::end(__out_range));
210   }
211 };
212 
213 } // namespace __uninitialized_copy
214 
215 inline namespace __cpo {
216   inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{};
217 } // namespace __cpo
218 
219 // uninitialized_copy_n
220 
221 template <class _InputIterator, class _OutputIterator>
222 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
223 
224 namespace __uninitialized_copy_n {
225 
226 struct __fn {
227   template <input_iterator _InputIterator,
228            __nothrow_forward_iterator _OutputIterator,
229            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
230     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
231   _LIBCPP_HIDE_FROM_ABI uninitialized_copy_n_result<_InputIterator, _OutputIterator>
232   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
233              _OutputIterator __ofirst, _Sentinel __olast) const {
234     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
235     auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n,
236                                                               _VSTD::move(__ofirst), _VSTD::move(__olast));
237     return {_VSTD::move(__result.first), _VSTD::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>
261   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 __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
265                                                             _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move);
266     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
267   }
268 
269   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
270     requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>>
271   _LIBCPP_HIDE_FROM_ABI uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
272   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
273     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
274                    ranges::begin(__out_range), ranges::end(__out_range));
275   }
276 };
277 
278 } // namespace __uninitialized_move
279 
280 inline namespace __cpo {
281   inline constexpr auto uninitialized_move = __uninitialized_move::__fn{};
282 } // namespace __cpo
283 
284 // uninitialized_move_n
285 
286 template <class _InputIterator, class _OutputIterator>
287 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
288 
289 namespace __uninitialized_move_n {
290 
291 struct __fn {
292   template <input_iterator _InputIterator,
293            __nothrow_forward_iterator _OutputIterator,
294            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
295     requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>>
296   _LIBCPP_HIDE_FROM_ABI uninitialized_move_n_result<_InputIterator, _OutputIterator>
297   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
298              _OutputIterator __ofirst, _Sentinel __olast) const {
299     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
300     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
301     auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n,
302                                                               _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move);
303     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
304   }
305 };
306 
307 } // namespace __uninitialized_move_n
308 
309 inline namespace __cpo {
310   inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{};
311 } // namespace __cpo
312 
313 } // namespace ranges
314 
315 #endif // _LIBCPP_STD_VER >= 20
316 
317 _LIBCPP_END_NAMESPACE_STD
318 
319 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
320