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