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 <__function_like.h> 17 #include <__iterator/concepts.h> 18 #include <__iterator/incrementable_traits.h> 19 #include <__iterator/iter_move.h> 20 #include <__iterator/iterator_traits.h> 21 #include <__iterator/readable_traits.h> 22 #include <__memory/concepts.h> 23 #include <__memory/uninitialized_algorithms.h> 24 #include <__ranges/access.h> 25 #include <__ranges/concepts.h> 26 #include <__ranges/dangling.h> 27 #include <__utility/move.h> 28 #include <type_traits> 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 !defined(_LIBCPP_HAS_NO_RANGES) 37 namespace ranges { 38 39 // uninitialized_default_construct 40 41 namespace __uninitialized_default_construct { 42 43 struct __fn final : private __function_like { 44 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 45 46 template <__nothrow_forward_iterator _ForwardIterator, 47 __nothrow_sentinel_for<_ForwardIterator> _Sentinel> 48 requires default_initializable<iter_value_t<_ForwardIterator>> 49 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { 50 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 51 return _VSTD::__uninitialized_default_construct<_ValueType>( 52 _VSTD::move(__first), _VSTD::move(__last)); 53 } 54 55 template <__nothrow_forward_range _ForwardRange> 56 requires default_initializable<range_value_t<_ForwardRange>> 57 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(__function_like::__tag()); 66 } // namespace __cpo 67 68 // uninitialized_default_construct_n 69 70 namespace __uninitialized_default_construct_n { 71 72 struct __fn final : private __function_like { 73 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 74 75 template <__nothrow_forward_iterator _ForwardIterator> 76 requires default_initializable<iter_value_t<_ForwardIterator>> 77 _ForwardIterator operator()(_ForwardIterator __first, 78 iter_difference_t<_ForwardIterator> __n) const { 79 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 80 return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n); 81 } 82 }; 83 84 } // namespace __uninitialized_default_construct_n 85 86 inline namespace __cpo { 87 inline constexpr auto uninitialized_default_construct_n = 88 __uninitialized_default_construct_n::__fn(__function_like::__tag()); 89 } // namespace __cpo 90 91 // uninitialized_value_construct 92 93 namespace __uninitialized_value_construct { 94 95 struct __fn final : private __function_like { 96 97 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 98 99 template <__nothrow_forward_iterator _ForwardIterator, 100 __nothrow_sentinel_for<_ForwardIterator> _Sentinel> 101 requires default_initializable<iter_value_t<_ForwardIterator>> 102 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last) const { 103 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 104 return _VSTD::__uninitialized_value_construct<_ValueType>( 105 _VSTD::move(__first), _VSTD::move(__last)); 106 } 107 108 template <__nothrow_forward_range _ForwardRange> 109 requires default_initializable<range_value_t<_ForwardRange>> 110 borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range) const { 111 return (*this)(ranges::begin(__range), ranges::end(__range)); 112 } 113 114 }; 115 116 } // namespace __uninitialized_value_construct 117 118 inline namespace __cpo { 119 inline constexpr auto uninitialized_value_construct = 120 __uninitialized_value_construct::__fn(__function_like::__tag()); 121 } // namespace __cpo 122 123 // uninitialized_value_construct_n 124 125 namespace __uninitialized_value_construct_n { 126 127 struct __fn final : private __function_like { 128 129 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 130 131 template <__nothrow_forward_iterator _ForwardIterator> 132 requires default_initializable<iter_value_t<_ForwardIterator>> 133 _ForwardIterator operator()(_ForwardIterator __first, 134 iter_difference_t<_ForwardIterator> __n) const { 135 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 136 return _VSTD::__uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); 137 } 138 139 }; 140 141 } // namespace __uninitialized_value_construct_n 142 143 inline namespace __cpo { 144 inline constexpr auto uninitialized_value_construct_n = 145 __uninitialized_value_construct_n::__fn(__function_like::__tag()); 146 } // namespace __cpo 147 148 // uninitialized_fill 149 150 namespace __uninitialized_fill { 151 152 struct __fn final : private __function_like { 153 154 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 155 156 template <__nothrow_forward_iterator _ForwardIterator, 157 __nothrow_sentinel_for<_ForwardIterator> _Sentinel, 158 class _Tp> 159 requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> 160 _ForwardIterator operator()(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) const { 161 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 162 return _VSTD::__uninitialized_fill<_ValueType>(_VSTD::move(__first), _VSTD::move(__last), __x); 163 } 164 165 template <__nothrow_forward_range _ForwardRange, class _Tp> 166 requires constructible_from<range_value_t<_ForwardRange>, const _Tp&> 167 borrowed_iterator_t<_ForwardRange> operator()(_ForwardRange&& __range, const _Tp& __x) const { 168 return (*this)(ranges::begin(__range), ranges::end(__range), __x); 169 } 170 171 }; 172 173 } // namespace __uninitialized_fill 174 175 inline namespace __cpo { 176 inline constexpr auto uninitialized_fill = __uninitialized_fill::__fn(__function_like::__tag()); 177 } // namespace __cpo 178 179 // uninitialized_fill_n 180 181 namespace __uninitialized_fill_n { 182 183 struct __fn final : private __function_like { 184 185 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 186 187 template <__nothrow_forward_iterator _ForwardIterator, class _Tp> 188 requires constructible_from<iter_value_t<_ForwardIterator>, const _Tp&> 189 _ForwardIterator operator()(_ForwardIterator __first, 190 iter_difference_t<_ForwardIterator> __n, 191 const _Tp& __x) const { 192 using _ValueType = remove_reference_t<iter_reference_t<_ForwardIterator>>; 193 return _VSTD::__uninitialized_fill_n<_ValueType>(_VSTD::move(__first), __n, __x); 194 } 195 196 }; 197 198 } // namespace __uninitialized_fill_n 199 200 inline namespace __cpo { 201 inline constexpr auto uninitialized_fill_n = __uninitialized_fill_n::__fn(__function_like::__tag()); 202 } // namespace __cpo 203 204 // uninitialized_copy 205 206 template <class _InputIterator, class _OutputIterator> 207 using uninitialized_copy_result = in_out_result<_InputIterator, _OutputIterator>; 208 209 namespace __uninitialized_copy { 210 211 struct __fn final : private __function_like { 212 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 213 214 template <input_iterator _InputIterator, 215 sentinel_for<_InputIterator> _Sentinel1, 216 __nothrow_forward_iterator _OutputIterator, 217 __nothrow_sentinel_for<_OutputIterator> _Sentinel2> 218 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> 219 uninitialized_copy_result<_InputIterator, _OutputIterator> 220 operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { 221 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 222 223 auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 224 _VSTD::move(__ofirst), _VSTD::move(__olast)); 225 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 226 } 227 228 template <input_range _InputRange, __nothrow_forward_range _OutputRange> 229 requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> 230 uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> 231 operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const { 232 return (*this)(ranges::begin(__in_range), ranges::end(__in_range), 233 ranges::begin(__out_range), ranges::end(__out_range)); 234 } 235 }; 236 237 } // namespace __uninitialized_copy 238 239 inline namespace __cpo { 240 inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn(__function_like::__tag()); 241 } // namespace __cpo 242 243 // uninitialized_copy_n 244 245 template <class _InputIterator, class _OutputIterator> 246 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>; 247 248 namespace __uninitialized_copy_n { 249 250 struct __fn final : private __function_like { 251 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 252 253 template <input_iterator _InputIterator, 254 __nothrow_forward_iterator _OutputIterator, 255 __nothrow_sentinel_for<_OutputIterator> _Sentinel> 256 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> 257 uninitialized_copy_n_result<_InputIterator, _OutputIterator> 258 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, 259 _OutputIterator __ofirst, _Sentinel __olast) const { 260 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 261 auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, 262 _VSTD::move(__ofirst), _VSTD::move(__olast)); 263 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 264 } 265 }; 266 267 } // namespace __uninitialized_copy_n 268 269 inline namespace __cpo { 270 inline constexpr auto uninitialized_copy_n = __uninitialized_copy_n::__fn(__function_like::__tag()); 271 } // namespace __cpo 272 273 // uninitialized_move 274 275 template <class _InputIterator, class _OutputIterator> 276 using uninitialized_move_result = in_out_result<_InputIterator, _OutputIterator>; 277 278 namespace __uninitialized_move { 279 280 struct __fn final : private __function_like { 281 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 282 283 template <input_iterator _InputIterator, 284 sentinel_for<_InputIterator> _Sentinel1, 285 __nothrow_forward_iterator _OutputIterator, 286 __nothrow_sentinel_for<_OutputIterator> _Sentinel2> 287 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> 288 uninitialized_move_result<_InputIterator, _OutputIterator> 289 operator()(_InputIterator __ifirst, _Sentinel1 __ilast, _OutputIterator __ofirst, _Sentinel2 __olast) const { 290 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 291 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; 292 293 auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 294 _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); 295 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 296 } 297 298 template <input_range _InputRange, __nothrow_forward_range _OutputRange> 299 requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> 300 uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> 301 operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { 302 return (*this)(ranges::begin(__in_range), ranges::end(__in_range), 303 ranges::begin(__out_range), ranges::end(__out_range)); 304 } 305 }; 306 307 } // namespace __uninitialized_move 308 309 inline namespace __cpo { 310 inline constexpr auto uninitialized_move = __uninitialized_move::__fn(__function_like::__tag()); 311 } // namespace __cpo 312 313 // uninitialized_move_n 314 315 template <class _InputIterator, class _OutputIterator> 316 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>; 317 318 namespace __uninitialized_move_n { 319 320 struct __fn final : private __function_like { 321 constexpr explicit __fn(__tag __x) noexcept : __function_like(__x) {} 322 323 template <input_iterator _InputIterator, 324 __nothrow_forward_iterator _OutputIterator, 325 __nothrow_sentinel_for<_OutputIterator> _Sentinel> 326 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> 327 uninitialized_move_n_result<_InputIterator, _OutputIterator> 328 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, 329 _OutputIterator __ofirst, _Sentinel __olast) const { 330 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 331 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; 332 333 auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), 334 _VSTD::move(__olast), __iter_move); 335 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 336 } 337 }; 338 339 } // namespace __uninitialized_move_n 340 341 inline namespace __cpo { 342 inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn(__function_like::__tag()); 343 } // namespace __cpo 344 345 } // namespace ranges 346 #endif // !defined(_LIBCPP_HAS_NO_RANGES) 347 348 _LIBCPP_END_NAMESPACE_STD 349 350 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H 351