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