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 <__function_like.h>
17 #include <__iterator/concepts.h>
18 #include <__iterator/incrementable_traits.h>
19 #include <__iterator/iter_move.h>
20 #include <__iterator/iterator_traits.h>
21 #include <__iterator/readable_traits.h>
22 #include <__memory/concepts.h>
23 #include <__memory/uninitialized_algorithms.h>
24 #include <__ranges/access.h>
25 #include <__ranges/concepts.h>
26 #include <__ranges/dangling.h>
27 #include <__utility/move.h>
28 #include <type_traits>
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 !defined(_LIBCPP_HAS_NO_RANGES)
37 namespace ranges {
38 
39 // uninitialized_default_construct
40 
41 namespace __uninitialized_default_construct {
42 
43 struct __fn final : private __function_like {
44   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
45 
46   template <__nothrow_forward_iterator _ForwardIterator,
47             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
48     requires default_initializable<iter_value_t<_ForwardIterator>>
49   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
50     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
51     return _VSTD::__uninitialized_default_construct<_ValueType>(
52         _VSTD::move(__first), _VSTD::move(__last));
53   }
54 
55   template <__nothrow_forward_range _ForwardRange>
56     requires default_initializable<range_value_t<_ForwardRange>>
57   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(__function_like::__tag());
66 } // namespace __cpo
67 
68 // uninitialized_default_construct_n
69 
70 namespace __uninitialized_default_construct_n {
71 
72 struct __fn final : private __function_like {
73   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
74 
75   template <__nothrow_forward_iterator _ForwardIterator>
76     requires default_initializable<iter_value_t<_ForwardIterator>>
77   _ForwardIterator operator()(_ForwardIterator __first,
78                               iter_difference_t<_ForwardIterator> __n) const {
79     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
80     return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n);
81   }
82 };
83 
84 } // namespace __uninitialized_default_construct_n
85 
86 inline namespace __cpo {
87   inline constexpr auto uninitialized_default_construct_n =
88       __uninitialized_default_construct_n::__fn(__function_like::__tag());
89 } // namespace __cpo
90 
91 // uninitialized_value_construct
92 
93 namespace __uninitialized_value_construct {
94 
95 struct __fn final : private __function_like {
96 
97   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
98 
99   template <__nothrow_forward_iterator _ForwardIterator,
100             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
101     requires default_initializable<iter_value_t<_ForwardIterator>>
102   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
103     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
104     return _VSTD::__uninitialized_value_construct<_ValueType>(
105         _VSTD::move(__first), _VSTD::move(__last));
106   }
107 
108   template <__nothrow_forward_range _ForwardRange>
109     requires default_initializable<range_value_t<_ForwardRange>>
110   borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
111     return (*this)(ranges::begin(__range), ranges::end(__range));
112   }
113 
114 };
115 
116 } // namespace __uninitialized_value_construct
117 
118 inline namespace __cpo {
119   inline constexpr auto uninitialized_value_construct =
120       __uninitialized_value_construct::__fn(__function_like::__tag());
121 } // namespace __cpo
122 
123 // uninitialized_value_construct_n
124 
125 namespace __uninitialized_value_construct_n {
126 
127 struct __fn final : private __function_like {
128 
129   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
130 
131   template <__nothrow_forward_iterator _ForwardIterator>
132     requires default_initializable<iter_value_t<_ForwardIterator>>
133   _ForwardIterator operator()(_ForwardIterator __first,
134                               iter_difference_t<_ForwardIterator> __n) const {
135     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
136     return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n);
137   }
138 
139 };
140 
141 } // namespace __uninitialized_value_construct_n
142 
143 inline namespace __cpo {
144   inline constexpr auto uninitialized_value_construct_n =
145       __uninitialized_value_construct_n::__fn(__function_like::__tag());
146 } // namespace __cpo
147 
148 // uninitialized_fill
149 
150 namespace __uninitialized_fill {
151 
152 struct __fn final : private __function_like {
153 
154   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
155 
156   template <__nothrow_forward_iterator _ForwardIterator,
157             __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
158             class _Tp>
159     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
160   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
161     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
162     return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x);
163   }
164 
165   template <__nothrow_forward_range _ForwardRange, class _Tp>
166     requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
167   borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
168     return (*this)(ranges::begin(__range), ranges::end(__range), __x);
169   }
170 
171 };
172 
173 } // namespace __uninitialized_fill
174 
175 inline namespace __cpo {
176   inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn(__function_like::__tag());
177 } // namespace __cpo
178 
179 // uninitialized_fill_n
180 
181 namespace __uninitialized_fill_n {
182 
183 struct __fn final : private __function_like {
184 
185   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
186 
187   template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
188     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
189   _ForwardIterator operator()(_ForwardIterator __first,
190                               iter_difference_t<_ForwardIterator> __n,
191                               const _Tp& __x) const {
192     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
193     return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x);
194   }
195 
196 };
197 
198 } // namespace __uninitialized_fill_n
199 
200 inline namespace __cpo {
201   inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn(__function_like::__tag());
202 } // namespace __cpo
203 
204 // uninitialized_copy
205 
206 template <class _InputIterator, class _OutputIterator>
207 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
208 
209 namespace __uninitialized_copy {
210 
211 struct __fn final : private __function_like {
212   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
213 
214   template <input_iterator _InputIterator,
215             sentinel_for<_InputIterator> _Sentinel1,
216             __nothrow_forward_iterator _OutputIterator,
217             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
218     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
219   uninitialized_copy_result<_InputIterator, _OutputIterator>
220   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
221     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
222 
223     auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
224                                                             _VSTD::move(__ofirst), _VSTD::move(__olast));
225     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
226   }
227 
228   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
229     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
230   uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
231   operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const {
232     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
233                    ranges::begin(__out_range), ranges::end(__out_range));
234   }
235 };
236 
237 } // namespace __uninitialized_copy
238 
239 inline namespace __cpo {
240   inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn(__function_like::__tag());
241 } // namespace __cpo
242 
243 // uninitialized_copy_n
244 
245 template <class _InputIterator, class _OutputIterator>
246 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
247 
248 namespace __uninitialized_copy_n {
249 
250 struct __fn final : private __function_like {
251   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
252 
253   template <input_iterator _InputIterator,
254            __nothrow_forward_iterator _OutputIterator,
255            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
256     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
257   uninitialized_copy_n_result<_InputIterator, _OutputIterator>
258   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
259              _OutputIterator __ofirst, _Sentinel __olast) const {
260     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
261     auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n,
262                                                               _VSTD::move(__ofirst), _VSTD::move(__olast));
263     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
264   }
265 };
266 
267 } // namespace __uninitialized_copy_n
268 
269 inline namespace __cpo {
270   inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn(__function_like::__tag());
271 } // namespace __cpo
272 
273 // uninitialized_move
274 
275 template <class _InputIterator, class _OutputIterator>
276 using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>;
277 
278 namespace __uninitialized_move {
279 
280 struct __fn final : private __function_like {
281   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
282 
283   template <input_iterator _InputIterator,
284             sentinel_for<_InputIterator> _Sentinel1,
285             __nothrow_forward_iterator _OutputIterator,
286             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
287     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
288   uninitialized_move_result<_InputIterator, _OutputIterator>
289   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
290     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
291     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
292 
293     auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
294                                                             _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move);
295     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
296   }
297 
298   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
299     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
300   uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
301   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
302     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
303                    ranges::begin(__out_range), ranges::end(__out_range));
304   }
305 };
306 
307 } // namespace __uninitialized_move
308 
309 inline namespace __cpo {
310   inline constexpr auto uninitialized_move = __uninitialized_move::__fn(__function_like::__tag());
311 } // namespace __cpo
312 
313 // uninitialized_move_n
314 
315 template <class _InputIterator, class _OutputIterator>
316 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
317 
318 namespace __uninitialized_move_n {
319 
320 struct __fn final : private __function_like {
321   constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {}
322 
323   template <input_iterator _InputIterator,
324            __nothrow_forward_iterator _OutputIterator,
325            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
326     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
327   uninitialized_move_n_result<_InputIterator, _OutputIterator>
328   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
329              _OutputIterator __ofirst, _Sentinel __olast) const {
330     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
331     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
332 
333     auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst),
334                                                               _VSTD::move(__olast), __iter_move);
335     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
336   }
337 };
338 
339 } // namespace __uninitialized_move_n
340 
341 inline namespace __cpo {
342   inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn(__function_like::__tag());
343 } // namespace __cpo
344 
345 } // namespace ranges
346 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
347 
348 _LIBCPP_END_NAMESPACE_STD
349 
350 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
351