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