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 > 17 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 _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 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 _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 _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 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 _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 _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 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 _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 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 __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 200 _VSTD::move(__ofirst), _VSTD::move(__olast)); 201 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 202 } 203 204 template <input_range _InputRange, __nothrow_forward_range _OutputRange> 205 requires constructible_from<range_value_t<_OutputRange>, range_reference_t<_InputRange>> 206 uninitialized_copy_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> operator__fn207 operator()( _InputRange&& __in_range, _OutputRange&& __out_range) const { 208 return (*this)(ranges::begin(__in_range), ranges::end(__in_range), 209 ranges::begin(__out_range), ranges::end(__out_range)); 210 } 211 }; 212 213 } // namespace __uninitialized_copy 214 215 inline namespace __cpo { 216 inline constexpr auto uninitialized_copy = __uninitialized_copy::__fn{}; 217 } // namespace __cpo 218 219 // uninitialized_copy_n 220 221 template <class _InputIterator, class _OutputIterator> 222 using uninitialized_copy_n_result = in_out_result<_InputIterator, _OutputIterator>; 223 224 namespace __uninitialized_copy_n { 225 226 struct __fn { 227 template <input_iterator _InputIterator, 228 __nothrow_forward_iterator _OutputIterator, 229 __nothrow_sentinel_for<_OutputIterator> _Sentinel> 230 requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>> 231 uninitialized_copy_n_result<_InputIterator, _OutputIterator> operator__fn232 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, 233 _OutputIterator __ofirst, _Sentinel __olast) const { 234 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 235 auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, 236 _VSTD::move(__ofirst), _VSTD::move(__olast)); 237 return {_VSTD::move(__result.first), _VSTD::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 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 __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 265 _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); 266 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 267 } 268 269 template <input_range _InputRange, __nothrow_forward_range _OutputRange> 270 requires constructible_from<range_value_t<_OutputRange>, range_rvalue_reference_t<_InputRange>> 271 uninitialized_move_result<borrowed_iterator_t<_InputRange>, borrowed_iterator_t<_OutputRange>> operator__fn272 operator()(_InputRange&& __in_range, _OutputRange&& __out_range) const { 273 return (*this)(ranges::begin(__in_range), ranges::end(__in_range), 274 ranges::begin(__out_range), ranges::end(__out_range)); 275 } 276 }; 277 278 } // namespace __uninitialized_move 279 280 inline namespace __cpo { 281 inline constexpr auto uninitialized_move = __uninitialized_move::__fn{}; 282 } // namespace __cpo 283 284 // uninitialized_move_n 285 286 template <class _InputIterator, class _OutputIterator> 287 using uninitialized_move_n_result = in_out_result<_InputIterator, _OutputIterator>; 288 289 namespace __uninitialized_move_n { 290 291 struct __fn { 292 template <input_iterator _InputIterator, 293 __nothrow_forward_iterator _OutputIterator, 294 __nothrow_sentinel_for<_OutputIterator> _Sentinel> 295 requires constructible_from<iter_value_t<_OutputIterator>, iter_rvalue_reference_t<_InputIterator>> 296 uninitialized_move_n_result<_InputIterator, _OutputIterator> operator__fn297 operator()(_InputIterator __ifirst, iter_difference_t<_InputIterator> __n, 298 _OutputIterator __ofirst, _Sentinel __olast) const { 299 using _ValueType = remove_reference_t<iter_reference_t<_OutputIterator>>; 300 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return ranges::iter_move(__iter); }; 301 auto __result = _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, 302 _VSTD::move(__ofirst), _VSTD::move(__olast), __iter_move); 303 return {_VSTD::move(__result.first), _VSTD::move(__result.second)}; 304 } 305 }; 306 307 } // namespace __uninitialized_move_n 308 309 inline namespace __cpo { 310 inline constexpr auto uninitialized_move_n = __uninitialized_move_n::__fn{}; 311 } // namespace __cpo 312 313 } // namespace ranges 314 315 #endif // _LIBCPP_STD_VER > 17 316 317 _LIBCPP_END_NAMESPACE_STD 318 319 #endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H 320