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