2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
11 #define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H
13 #include <__algorithm/in_out_result.h>
14 #include <__concepts/constructible.h>
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>
29 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
30 # pragma GCC system_header
33 _LIBCPP_BEGIN_NAMESPACE_STD
35 #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
39 // uninitialized_default_construct
41 namespace __uninitialized_default_construct {
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));
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));
60 } // namespace __uninitialized_default_construct
62 inline namespace __cpo {
63 inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct::__fn{};
66 // uninitialized_default_construct_n
68 namespace __uninitialized_default_construct_n {
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);
80 } // namespace __uninitialized_default_construct_n
82 inline namespace __cpo {
83 inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n::__fn{};
86 // uninitialized_value_construct
88 namespace __uninitialized_value_construct {
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));
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));
107 } // namespace __uninitialized_value_construct
109 inline namespace __cpo {
110 inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct::__fn{};
113 // uninitialized_value_construct_n
115 namespace __uninitialized_value_construct_n {
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);
127 } // namespace __uninitialized_value_construct_n
129 inline namespace __cpo {
130 inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n::__fn{};
133 // uninitialized_fill
135 namespace __uninitialized_fill {
138 template <__nothrow_forward_iterator _ForwardIterator,
139 __nothrow_sentinel_for<_ForwardIterator> _Sentinel,
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);
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);
154 } // namespace __uninitialized_fill
156 inline namespace __cpo {
157 inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn{};
160 // uninitialized_fill_n
162 namespace __uninitialized_fill_n {
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);
175 } // namespace __uninitialized_fill_n
177 inline namespace __cpo {
178 inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn{};
181 // uninitialized_copy
183 template <class _InputIterator, class _OutputIterator>
184 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
186 namespace __uninitialized_copy {
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>>;
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)};
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));
212 } // namespace __uninitialized_copy
214 inline namespace __cpo {
215 inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{};
218 // uninitialized_copy_n
220 template <class _InputIterator, class _OutputIterator>
221 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
223 namespace __uninitialized_copy_n {
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)};
240 } // namespace __uninitialized_copy_n
242 inline namespace __cpo {
243 inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn{};
246 // uninitialized_move
248 template <class _InputIterator, class _OutputIterator>
249 using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>;
251 namespace __uninitialized_move {
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)};
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));
277 } // namespace __uninitialized_move
279 inline namespace __cpo {
280 inline constexpr auto uninitialized_move = __uninitialized_move::__fn{};
283 // uninitialized_move_n
285 template <class _InputIterator, class _OutputIterator>
286 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
288 namespace __uninitialized_move_n {
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)};
306 } // namespace __uninitialized_move_n
308 inline namespace __cpo {
309 inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{};
312 } // namespace ranges
314 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
316 _LIBCPP_END_NAMESPACE_STD
318 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H