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