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