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