xref: /llvm-project/pstl/include/pstl/internal/glue_memory_impl.h (revision 843c12d6a0cdfd64c5a92e24eb58ba9ee17ca1ee)
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