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