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