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 <__utility/move.h>
27 #include <type_traits>
28 
29 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30 #  pragma GCC system_header
31 #endif
32 
33 _LIBCPP_BEGIN_NAMESPACE_STD
34 
35 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
36 
37 namespace ranges {
38 
39 // uninitialized_default_construct
40 
41 namespace __uninitialized_default_construct {
42 
43 struct __fn {
44   template <__nothrow_forward_iterator _ForwardIterator,
45             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
46     requires default_initializable<iter_value_t<_ForwardIterator>>
47   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
48     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
49     return _VSTD::__uninitialized_default_construct<_ValueType>(
50         _VSTD::move(__first), _VSTD::move(__last));
51   }
52 
53   template <__nothrow_forward_range _ForwardRange>
54     requires default_initializable<range_value_t<_ForwardRange>>
55   borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const {
56     return (*this)(ranges::begin(__range), ranges::end(__range));
57   }
58 };
59 
60 } // namespace __uninitialized_default_construct
61 
62 inline namespace __cpo {
63   inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{};
64 } // namespace __cpo
65 
66 // uninitialized_default_construct_n
67 
68 namespace __uninitialized_default_construct_n {
69 
70 struct __fn {
71   template <__nothrow_forward_iterator _ForwardIterator>
72     requires default_initializable<iter_value_t<_ForwardIterator>>
73   _ForwardIterator operator()(_ForwardIterator __first,
74                               iter_difference_t<_ForwardIterator> __n) const {
75     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
76     return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n);
77   }
78 };
79 
80 } // namespace __uninitialized_default_construct_n
81 
82 inline namespace __cpo {
83   inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{};
84 } // namespace __cpo
85 
86 // uninitialized_value_construct
87 
88 namespace __uninitialized_value_construct {
89 
90 struct __fn {
91   template <__nothrow_forward_iterator _ForwardIterator,
92             __nothrow_sentinel_for<_ForwardIterator> _Sentinel>
93     requires default_initializable<iter_value_t<_ForwardIterator>>
94   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const {
95     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
96     return _VSTD::__uninitialized_value_construct<_ValueType>(
97         _VSTD::move(__first), _VSTD::move(__last));
98   }
99 
100   template <__nothrow_forward_range _ForwardRange>
101     requires default_initializable<range_value_t<_ForwardRange>>
102   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   _ForwardIterator operator()(_ForwardIterator __first,
121                               iter_difference_t<_ForwardIterator> __n) const {
122     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
123     return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::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,
139             __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
140             class _Tp>
141     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
142   _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const {
143     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
144     return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x);
145   }
146 
147   template <__nothrow_forward_range _ForwardRange, class _Tp>
148     requires constructible_from<range_value_t<_ForwardRange>, const _Tp&>
149   borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const {
150     return (*this)(ranges::begin(__range), ranges::end(__range), __x);
151   }
152 };
153 
154 } // namespace __uninitialized_fill
155 
156 inline namespace __cpo {
157   inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{};
158 } // namespace __cpo
159 
160 // uninitialized_fill_n
161 
162 namespace __uninitialized_fill_n {
163 
164 struct __fn {
165   template <__nothrow_forward_iterator _ForwardIterator, class _Tp>
166     requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&>
167   _ForwardIterator operator()(_ForwardIterator __first,
168                               iter_difference_t<_ForwardIterator> __n,
169                               const _Tp& __x) const {
170     using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>;
171     return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x);
172   }
173 };
174 
175 } // namespace __uninitialized_fill_n
176 
177 inline namespace __cpo {
178   inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{};
179 } // namespace __cpo
180 
181 // uninitialized_copy
182 
183 template <class _InputIterator, class _OutputIterator>
184 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
185 
186 namespace __uninitialized_copy {
187 
188 struct __fn {
189   template <input_iterator _InputIterator,
190             sentinel_for<_InputIterator> _Sentinel1,
191             __nothrow_forward_iterator _OutputIterator,
192             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
193     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
194   uninitialized_copy_result<_InputIterator, _OutputIterator>
195   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
196     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
197 
198     auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
199                                                             _VSTD::move(__ofirst), _VSTD::move(__olast));
200     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
201   }
202 
203   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
204     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
205   uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
206   operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const {
207     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
208                    ranges::begin(__out_range), ranges::end(__out_range));
209   }
210 };
211 
212 } // namespace __uninitialized_copy
213 
214 inline namespace __cpo {
215   inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{};
216 } // namespace __cpo
217 
218 // uninitialized_copy_n
219 
220 template <class _InputIterator, class _OutputIterator>
221 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
222 
223 namespace __uninitialized_copy_n {
224 
225 struct __fn {
226   template <input_iterator _InputIterator,
227            __nothrow_forward_iterator _OutputIterator,
228            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
229     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
230   uninitialized_copy_n_result<_InputIterator, _OutputIterator>
231   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
232              _OutputIterator __ofirst, _Sentinel __olast) const {
233     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
234     auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n,
235                                                               _VSTD::move(__ofirst), _VSTD::move(__olast));
236     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
237   }
238 };
239 
240 } // namespace __uninitialized_copy_n
241 
242 inline namespace __cpo {
243   inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{};
244 } // namespace __cpo
245 
246 // uninitialized_move
247 
248 template <class _InputIterator, class _OutputIterator>
249 using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>;
250 
251 namespace __uninitialized_move {
252 
253 struct __fn {
254   template <input_iterator _InputIterator,
255             sentinel_for<_InputIterator> _Sentinel1,
256             __nothrow_forward_iterator _OutputIterator,
257             __nothrow_sentinel_for<_OutputIterator> _Sentinel2>
258     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
259   uninitialized_move_result<_InputIterator, _OutputIterator>
260   operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const {
261     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
262     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
263     auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast),
264                                                             _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move);
265     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
266   }
267 
268   template <input_range _InputRange, __nothrow_forward_range _OutputRange>
269     requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>>
270   uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>>
271   operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const {
272     return (*this)(ranges::begin(__in_range), ranges::end(__in_range),
273                    ranges::begin(__out_range), ranges::end(__out_range));
274   }
275 };
276 
277 } // namespace __uninitialized_move
278 
279 inline namespace __cpo {
280   inline constexpr auto uninitialized_move = __uninitialized_move::__fn{};
281 } // namespace __cpo
282 
283 // uninitialized_move_n
284 
285 template <class _InputIterator, class _OutputIterator>
286 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
287 
288 namespace __uninitialized_move_n {
289 
290 struct __fn {
291   template <input_iterator _InputIterator,
292            __nothrow_forward_iterator _OutputIterator,
293            __nothrow_sentinel_for<_OutputIterator> _Sentinel>
294     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
295   uninitialized_move_n_result<_InputIterator, _OutputIterator>
296   operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n,
297              _OutputIterator __ofirst, _Sentinel __olast) const {
298     using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>;
299     auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); };
300     auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n,
301                                                               _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move);
302     return {_VSTD::move(__result.first), _VSTD::move(__result.second)};
303   }
304 };
305 
306 } // namespace __uninitialized_move_n
307 
308 inline namespace __cpo {
309   inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{};
310 } // namespace __cpo
311 
312 } // namespace ranges
313 
314 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
315 
316 _LIBCPP_END_NAMESPACE_STD
317 
318 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
319