master
  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
 40namespace ranges {
 41
 42// uninitialized_default_construct
 43
 44struct __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
 59inline namespace __cpo {
 60inline constexpr auto uninitialized_default_construct = __uninitialized_default_construct{};
 61} // namespace __cpo
 62
 63// uninitialized_default_construct_n
 64
 65struct __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
 75inline namespace __cpo {
 76inline constexpr auto uninitialized_default_construct_n = __uninitialized_default_construct_n{};
 77} // namespace __cpo
 78
 79// uninitialized_value_construct
 80
 81struct __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
 96inline namespace __cpo {
 97inline constexpr auto uninitialized_value_construct = __uninitialized_value_construct{};
 98} // namespace __cpo
 99
100// uninitialized_value_construct_n
101
102struct __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
112inline namespace __cpo {
113inline constexpr auto uninitialized_value_construct_n = __uninitialized_value_construct_n{};
114} // namespace __cpo
115
116// uninitialized_fill
117
118struct __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
133inline namespace __cpo {
134inline constexpr auto uninitialized_fill = __uninitialized_fill{};
135} // namespace __cpo
136
137// uninitialized_fill_n
138
139struct __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
149inline namespace __cpo {
150inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n{};
151} // namespace __cpo
152
153// uninitialized_copy
154
155template <class _InputIterator, class _OutputIterator>
156using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>;
157
158struct __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
183inline namespace __cpo {
184inline constexpr auto uninitialized_copy = __uninitialized_copy{};
185} // namespace __cpo
186
187// uninitialized_copy_n
188
189template <class _InputIterator, class _OutputIterator>
190using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>;
191
192struct __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
210inline namespace __cpo {
211inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n{};
212} // namespace __cpo
213
214// uninitialized_move
215
216template <class _InputIterator, class _OutputIterator>
217using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>;
218
219struct __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
244inline namespace __cpo {
245inline constexpr auto uninitialized_move = __uninitialized_move{};
246} // namespace __cpo
247
248// uninitialized_move_n
249
250template <class _InputIterator, class _OutputIterator>
251using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>;
252
253struct __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
272inline namespace __cpo {
273inline 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