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_UNINITIALIZED_ALGORITHMS_H 11 #define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H 12 13 #include <__config> 14 #include <__memory/addressof.h> 15 #include <__memory/construct_at.h> 16 #include <__memory/voidify.h> 17 #include <iterator> 18 #include <utility> 19 20 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 21 #pragma GCC system_header 22 #endif 23 24 _LIBCPP_BEGIN_NAMESPACE_STD 25 26 // This is a simplified version of C++20 `unreachable_sentinel` that doesn't use concepts and thus can be used in any 27 // language mode. 28 struct __unreachable_sentinel { 29 template <class _Iter> 30 _LIBCPP_HIDE_FROM_ABI friend _LIBCPP_CONSTEXPR bool operator!=(const _Iter&, __unreachable_sentinel) _NOEXCEPT { 31 return true; 32 } 33 }; 34 35 // uninitialized_copy 36 37 template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2> 38 inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> 39 __uninitialized_copy(_InputIterator __ifirst, _Sentinel1 __ilast, 40 _ForwardIterator __ofirst, _Sentinel2 __olast) { 41 _ForwardIterator __idx = __ofirst; 42 #ifndef _LIBCPP_NO_EXCEPTIONS 43 try { 44 #endif 45 for (; __ifirst != __ilast && __idx != __olast; ++__ifirst, (void)++__idx) 46 ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); 47 #ifndef _LIBCPP_NO_EXCEPTIONS 48 } catch (...) { 49 _VSTD::__destroy(__ofirst, __idx); 50 throw; 51 } 52 #endif 53 54 return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); 55 } 56 57 template <class _InputIterator, class _ForwardIterator> 58 _ForwardIterator uninitialized_copy(_InputIterator __ifirst, _InputIterator __ilast, 59 _ForwardIterator __ofirst) { 60 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 61 auto __result = _VSTD::__uninitialized_copy<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 62 _VSTD::move(__ofirst), __unreachable_sentinel()); 63 return _VSTD::move(__result.second); 64 } 65 66 // uninitialized_copy_n 67 68 template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel> 69 inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> 70 __uninitialized_copy_n(_InputIterator __ifirst, _Size __n, 71 _ForwardIterator __ofirst, _Sentinel __olast) { 72 _ForwardIterator __idx = __ofirst; 73 #ifndef _LIBCPP_NO_EXCEPTIONS 74 try { 75 #endif 76 for (; __n > 0 && __idx != __olast; ++__ifirst, (void)++__idx, (void)--__n) 77 ::new (_VSTD::__voidify(*__idx)) _ValueType(*__ifirst); 78 #ifndef _LIBCPP_NO_EXCEPTIONS 79 } catch (...) { 80 _VSTD::__destroy(__ofirst, __idx); 81 throw; 82 } 83 #endif 84 85 return pair<_InputIterator, _ForwardIterator>(_VSTD::move(__ifirst), _VSTD::move(__idx)); 86 } 87 88 template <class _InputIterator, class _Size, class _ForwardIterator> 89 inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_copy_n(_InputIterator __ifirst, _Size __n, 90 _ForwardIterator __ofirst) { 91 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 92 auto __result = _VSTD::__uninitialized_copy_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), 93 __unreachable_sentinel()); 94 return _VSTD::move(__result.second); 95 } 96 97 // uninitialized_fill 98 99 template <class _ValueType, class _ForwardIterator, class _Sentinel, class _Tp> 100 inline _LIBCPP_HIDE_FROM_ABI 101 _ForwardIterator __uninitialized_fill(_ForwardIterator __first, _Sentinel __last, const _Tp& __x) 102 { 103 _ForwardIterator __idx = __first; 104 #ifndef _LIBCPP_NO_EXCEPTIONS 105 try 106 { 107 #endif 108 for (; __idx != __last; ++__idx) 109 ::new (_VSTD::__voidify(*__idx)) _ValueType(__x); 110 #ifndef _LIBCPP_NO_EXCEPTIONS 111 } 112 catch (...) 113 { 114 _VSTD::__destroy(__first, __idx); 115 throw; 116 } 117 #endif 118 119 return __idx; 120 } 121 122 template <class _ForwardIterator, class _Tp> 123 inline _LIBCPP_HIDE_FROM_ABI 124 void uninitialized_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __x) 125 { 126 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 127 (void)_VSTD::__uninitialized_fill<_ValueType>(__first, __last, __x); 128 } 129 130 // uninitialized_fill_n 131 132 template <class _ValueType, class _ForwardIterator, class _Size, class _Tp> 133 inline _LIBCPP_HIDE_FROM_ABI 134 _ForwardIterator __uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 135 { 136 _ForwardIterator __idx = __first; 137 #ifndef _LIBCPP_NO_EXCEPTIONS 138 try 139 { 140 #endif 141 for (; __n > 0; ++__idx, (void) --__n) 142 ::new (_VSTD::__voidify(*__idx)) _ValueType(__x); 143 #ifndef _LIBCPP_NO_EXCEPTIONS 144 } 145 catch (...) 146 { 147 _VSTD::__destroy(__first, __idx); 148 throw; 149 } 150 #endif 151 152 return __idx; 153 } 154 155 template <class _ForwardIterator, class _Size, class _Tp> 156 inline _LIBCPP_HIDE_FROM_ABI 157 _ForwardIterator uninitialized_fill_n(_ForwardIterator __first, _Size __n, const _Tp& __x) 158 { 159 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 160 return _VSTD::__uninitialized_fill_n<_ValueType>(__first, __n, __x); 161 } 162 163 #if _LIBCPP_STD_VER > 14 164 165 // uninitialized_default_construct 166 167 template <class _ValueType, class _ForwardIterator, class _Sentinel> 168 inline _LIBCPP_HIDE_FROM_ABI 169 _ForwardIterator __uninitialized_default_construct(_ForwardIterator __first, _Sentinel __last) { 170 auto __idx = __first; 171 #ifndef _LIBCPP_NO_EXCEPTIONS 172 try { 173 #endif 174 for (; __idx != __last; ++__idx) 175 ::new (_VSTD::__voidify(*__idx)) _ValueType; 176 #ifndef _LIBCPP_NO_EXCEPTIONS 177 } catch (...) { 178 _VSTD::__destroy(__first, __idx); 179 throw; 180 } 181 #endif 182 183 return __idx; 184 } 185 186 template <class _ForwardIterator> 187 inline _LIBCPP_HIDE_FROM_ABI 188 void uninitialized_default_construct(_ForwardIterator __first, _ForwardIterator __last) { 189 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 190 (void)_VSTD::__uninitialized_default_construct<_ValueType>( 191 _VSTD::move(__first), _VSTD::move(__last)); 192 } 193 194 // uninitialized_default_construct_n 195 196 template <class _ValueType, class _ForwardIterator, class _Size> 197 inline _LIBCPP_HIDE_FROM_ABI 198 _ForwardIterator __uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { 199 auto __idx = __first; 200 #ifndef _LIBCPP_NO_EXCEPTIONS 201 try { 202 #endif 203 for (; __n > 0; ++__idx, (void) --__n) 204 ::new (_VSTD::__voidify(*__idx)) _ValueType; 205 #ifndef _LIBCPP_NO_EXCEPTIONS 206 } catch (...) { 207 _VSTD::__destroy(__first, __idx); 208 throw; 209 } 210 #endif 211 212 return __idx; 213 } 214 215 template <class _ForwardIterator, class _Size> 216 inline _LIBCPP_HIDE_FROM_ABI 217 _ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, _Size __n) { 218 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 219 return _VSTD::__uninitialized_default_construct_n<_ValueType>(_VSTD::move(__first), __n); 220 } 221 222 // uninitialized_value_construct 223 224 template <class _ValueType, class _ForwardIterator, class _Sentinel> 225 inline _LIBCPP_HIDE_FROM_ABI 226 _ForwardIterator __uninitialized_value_construct(_ForwardIterator __first, _Sentinel __last) { 227 auto __idx = __first; 228 #ifndef _LIBCPP_NO_EXCEPTIONS 229 try { 230 #endif 231 for (; __idx != __last; ++__idx) 232 ::new (_VSTD::__voidify(*__idx)) _ValueType(); 233 #ifndef _LIBCPP_NO_EXCEPTIONS 234 } catch (...) { 235 _VSTD::__destroy(__first, __idx); 236 throw; 237 } 238 #endif 239 240 return __idx; 241 } 242 243 template <class _ForwardIterator> 244 inline _LIBCPP_HIDE_FROM_ABI 245 void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator __last) { 246 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 247 (void)_VSTD::__uninitialized_value_construct<_ValueType>( 248 _VSTD::move(__first), _VSTD::move(__last)); 249 } 250 251 // uninitialized_value_construct_n 252 253 template <class _ValueType, class _ForwardIterator, class _Size> 254 inline _LIBCPP_HIDE_FROM_ABI 255 _ForwardIterator __uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { 256 auto __idx = __first; 257 #ifndef _LIBCPP_NO_EXCEPTIONS 258 try { 259 #endif 260 for (; __n > 0; ++__idx, (void) --__n) 261 ::new (_VSTD::__voidify(*__idx)) _ValueType(); 262 #ifndef _LIBCPP_NO_EXCEPTIONS 263 } catch (...) { 264 _VSTD::__destroy(__first, __idx); 265 throw; 266 } 267 #endif 268 269 return __idx; 270 } 271 272 template <class _ForwardIterator, class _Size> 273 inline _LIBCPP_HIDE_FROM_ABI 274 _ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, _Size __n) { 275 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 276 return __uninitialized_value_construct_n<_ValueType>(_VSTD::move(__first), __n); 277 } 278 279 // uninitialized_move 280 281 template <class _ValueType, class _InputIterator, class _Sentinel1, class _ForwardIterator, class _Sentinel2, 282 class _IterMove> 283 inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> 284 __uninitialized_move(_InputIterator __ifirst, _Sentinel1 __ilast, 285 _ForwardIterator __ofirst, _Sentinel2 __olast, _IterMove __iter_move) { 286 auto __idx = __ofirst; 287 #ifndef _LIBCPP_NO_EXCEPTIONS 288 try { 289 #endif 290 for (; __ifirst != __ilast && __idx != __olast; ++__idx, (void)++__ifirst) { 291 ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); 292 } 293 #ifndef _LIBCPP_NO_EXCEPTIONS 294 } catch (...) { 295 _VSTD::__destroy(__ofirst, __idx); 296 throw; 297 } 298 #endif 299 300 return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; 301 } 302 303 template <class _InputIterator, class _ForwardIterator> 304 inline _LIBCPP_HIDE_FROM_ABI _ForwardIterator uninitialized_move(_InputIterator __ifirst, _InputIterator __ilast, 305 _ForwardIterator __ofirst) { 306 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 307 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; 308 309 auto __result = _VSTD::__uninitialized_move<_ValueType>(_VSTD::move(__ifirst), _VSTD::move(__ilast), 310 _VSTD::move(__ofirst), __unreachable_sentinel(), __iter_move); 311 return _VSTD::move(__result.second); 312 } 313 314 // uninitialized_move_n 315 316 template <class _ValueType, class _InputIterator, class _Size, class _ForwardIterator, class _Sentinel, class _IterMove> 317 inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> 318 __uninitialized_move_n(_InputIterator __ifirst, _Size __n, 319 _ForwardIterator __ofirst, _Sentinel __olast, _IterMove __iter_move) { 320 auto __idx = __ofirst; 321 #ifndef _LIBCPP_NO_EXCEPTIONS 322 try { 323 #endif 324 for (; __n > 0 && __idx != __olast; ++__idx, (void)++__ifirst, --__n) 325 ::new (_VSTD::__voidify(*__idx)) _ValueType(__iter_move(__ifirst)); 326 #ifndef _LIBCPP_NO_EXCEPTIONS 327 } catch (...) { 328 _VSTD::__destroy(__ofirst, __idx); 329 throw; 330 } 331 #endif 332 333 return {_VSTD::move(__ifirst), _VSTD::move(__idx)}; 334 } 335 336 template <class _InputIterator, class _Size, class _ForwardIterator> 337 inline _LIBCPP_HIDE_FROM_ABI pair<_InputIterator, _ForwardIterator> 338 uninitialized_move_n(_InputIterator __ifirst, _Size __n, _ForwardIterator __ofirst) { 339 using _ValueType = typename iterator_traits<_ForwardIterator>::value_type; 340 auto __iter_move = [](auto&& __iter) -> decltype(auto) { return _VSTD::move(*__iter); }; 341 342 return _VSTD::__uninitialized_move_n<_ValueType>(_VSTD::move(__ifirst), __n, _VSTD::move(__ofirst), 343 __unreachable_sentinel(), __iter_move); 344 } 345 346 #endif // _LIBCPP_STD_VER > 14 347 348 _LIBCPP_END_NAMESPACE_STD 349 350 #endif // _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H 351