xref: /freebsd-src/contrib/llvm-project/libcxx/include/__memory/uninitialized_algorithms.h (revision c9ccf3a32da427475985b85d7df023ccfb138c27)
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