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 _PSTL_GLUE_MEMORY_IMPL_H
11 #define _PSTL_GLUE_MEMORY_IMPL_H
12
13 #include "pstl_config.h"
14
15 #include "execution_defs.h"
16 #include "utils.h"
17 #include "algorithm_fwd.h"
18
19 #include "execution_impl.h"
20
21 _PSTL_HIDE_FROM_ABI_PUSH
22
23 namespace std
24 {
25
26 // [uninitialized.copy]
27
28 template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
29 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_copy(_ExecutionPolicy && __exec,_InputIterator __first,_InputIterator __last,_ForwardIterator __result)30 uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result)
31 {
32 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
33 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
34 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
35 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
36
37 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
38
39 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
40
41 return __pstl::__internal::__invoke_if_else(
42 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
43 [&]()
44 {
45 return __pstl::__internal::__pattern_walk2_brick(
46 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
47 [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
48 { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
49 },
50 [&]()
51 {
52 return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
53 __last, __result,
54 [](_ReferenceType1 __val1, _ReferenceType2 __val2)
55 { ::new (std::addressof(__val2)) _ValueType2(__val1); });
56 });
57 }
58
59 template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
60 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_copy_n(_ExecutionPolicy && __exec,_InputIterator __first,_Size __n,_ForwardIterator __result)61 uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result)
62 {
63 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
64 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
65 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
66 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
67
68 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
69
70 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
71
72 return __pstl::__internal::__invoke_if_else(
73 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
74 [&]()
75 {
76 return __pstl::__internal::__pattern_walk2_brick_n(
77 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
78 [](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
79 { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
80 },
81 [&]()
82 {
83 return __pstl::__internal::__pattern_walk2_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
84 __first, __n, __result,
85 [](_ReferenceType1 __val1, _ReferenceType2 __val2)
86 { ::new (std::addressof(__val2)) _ValueType2(__val1); });
87 });
88 }
89
90 // [uninitialized.move]
91
92 template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
93 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_move(_ExecutionPolicy && __exec,_InputIterator __first,_InputIterator __last,_ForwardIterator __result)94 uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result)
95 {
96 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
97 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
98 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
99 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
100
101 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
102
103 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
104
105 return __pstl::__internal::__invoke_if_else(
106 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
107 [&]()
108 {
109 return __pstl::__internal::__pattern_walk2_brick(
110 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
111 [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
112 { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
113 },
114 [&]()
115 {
116 return __pstl::__internal::__pattern_walk2(
117 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
118 [](_ReferenceType1 __val1, _ReferenceType2 __val2)
119 { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
120 });
121 }
122
123 template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
124 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_move_n(_ExecutionPolicy && __exec,_InputIterator __first,_Size __n,_ForwardIterator __result)125 uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result)
126 {
127 typedef typename iterator_traits<_InputIterator>::value_type _ValueType1;
128 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
129 typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
130 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
131
132 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
133
134 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
135
136 return __pstl::__internal::__invoke_if_else(
137 std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
138 [&]()
139 {
140 return __pstl::__internal::__pattern_walk2_brick_n(
141 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
142 [](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
143 { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
144 },
145 [&]()
146 {
147 return __pstl::__internal::__pattern_walk2_n(
148 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
149 [](_ReferenceType1 __val1, _ReferenceType2 __val2)
150 { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
151 });
152 }
153
154 // [uninitialized.fill]
155
156 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
157 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_fill(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)158 uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
159 {
160 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
161 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
162
163 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
164
165 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
166
167 __pstl::__internal::__invoke_if_else(
168 std::is_arithmetic<_ValueType>(),
169 [&]()
170 {
171 __pstl::__internal::__pattern_walk_brick(
172 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
173 [&__value](_ForwardIterator __begin, _ForwardIterator __end)
174 { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); });
175 },
176 [&]()
177 {
178 __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
179 [&__value](_ReferenceType __val)
180 { ::new (std::addressof(__val)) _ValueType(__value); });
181 });
182 }
183
184 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
185 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_fill_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __n,const _Tp & __value)186 uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value)
187 {
188 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
189 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
190
191 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
192
193 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
194
195 return __pstl::__internal::__invoke_if_else(
196 std::is_arithmetic<_ValueType>(),
197 [&]()
198 {
199 return __pstl::__internal::__pattern_walk_brick_n(
200 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
201 [&__value](_ForwardIterator __begin, _Size __count)
202 { return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{}); });
203 },
204 [&]()
205 {
206 return __pstl::__internal::__pattern_walk1_n(
207 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
208 [&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); });
209 });
210 }
211
212 // [specialized.destroy]
213
214 template <class _ExecutionPolicy, class _ForwardIterator>
215 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
destroy(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)216 destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
217 {
218 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
219 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
220
221 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
222
223 __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(),
224 [&]()
225 {
226 __pstl::__internal::__pattern_walk1(
227 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
228 [](_ReferenceType __val) { __val.~_ValueType(); });
229 });
230 }
231
232 template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
233 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
destroy_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __n)234 destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
235 {
236 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
237 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
238
239 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
240
241 return __pstl::__internal::__invoke_if_else(
242 std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); },
243 [&]()
244 {
245 return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
246 __first, __n,
247 [](_ReferenceType __val) { __val.~_ValueType(); });
248 });
249 }
250
251 // [uninitialized.construct.default]
252
253 template <class _ExecutionPolicy, class _ForwardIterator>
254 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_default_construct(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)255 uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
256 {
257 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
258 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
259
260 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
261
262 __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(),
263 [&]()
264 {
265 __pstl::__internal::__pattern_walk1(
266 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
267 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; });
268 });
269 }
270
271 template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
272 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_default_construct_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __n)273 uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
274 {
275 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
276 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
277
278 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
279
280 return __pstl::__internal::__invoke_if_else(
281 std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
282 [&]()
283 {
284 return __pstl::__internal::__pattern_walk1_n(
285 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
286 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; });
287 });
288 }
289
290 // [uninitialized.construct.value]
291
292 template <class _ExecutionPolicy, class _ForwardIterator>
293 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
uninitialized_value_construct(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)294 uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
295 {
296 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
297 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
298
299 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
300
301 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
302
303 __pstl::__internal::__invoke_if_else(
304 std::is_trivial<_ValueType>(),
305 [&]()
306 {
307 __pstl::__internal::__pattern_walk_brick(
308 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
309 [](_ForwardIterator __begin, _ForwardIterator __end)
310 { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); });
311 },
312 [&]()
313 {
314 __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
315 [](_ReferenceType __val)
316 { ::new (std::addressof(__val)) _ValueType(); });
317 });
318 }
319
320 template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
321 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
uninitialized_value_construct_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __n)322 uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
323 {
324 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
325 typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
326
327 auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
328
329 using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
330
331 return __pstl::__internal::__invoke_if_else(
332 std::is_trivial<_ValueType>(),
333 [&]()
334 {
335 return __pstl::__internal::__pattern_walk_brick_n(
336 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
337 [](_ForwardIterator __begin, _Size __count)
338 { return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); });
339 },
340 [&]()
341 {
342 return __pstl::__internal::__pattern_walk1_n(
343 __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
344 [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); });
345 });
346 }
347
348 } // namespace std
349
350 _PSTL_HIDE_FROM_ABI_POP
351
352 #endif /* _PSTL_GLUE_MEMORY_IMPL_H */
353