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