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