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
16namespace std
17{
18
19// [uninitialized.copy]
20
21template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
22__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
23uninitialized_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
55template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
56__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
57uninitialized_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
90template <class _ExecutionPolicy, class _InputIterator, class _ForwardIterator>
91__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
92uninitialized_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
124template <class _ExecutionPolicy, class _InputIterator, class _Size, class _ForwardIterator>
125__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
126uninitialized_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
160template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
161__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
162uninitialized_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
190template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
191__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
192uninitialized_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
222template <class _ExecutionPolicy, class _ForwardIterator>
223__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
224destroy(_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
241template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
242__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
243destroy_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
264template <class _ExecutionPolicy, class _ForwardIterator>
265__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
266uninitialized_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
283template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
284__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
285uninitialized_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
306template <class _ExecutionPolicy, class _ForwardIterator>
307__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
308uninitialized_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
335template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
336__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
337uninitialized_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

source code of include/c++/11/pstl/glue_memory_impl.h