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