1181254a7Smrg // -*- C++ -*-
2181254a7Smrg //===-- parallel_backend_utils.h ------------------------------------------===//
3181254a7Smrg //
4181254a7Smrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5181254a7Smrg // See https://llvm.org/LICENSE.txt for license information.
6181254a7Smrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7181254a7Smrg //
8181254a7Smrg //===----------------------------------------------------------------------===//
9181254a7Smrg
10fb8a8121Smrg #ifndef _PSTL_PARALLEL_BACKEND_UTILS_H
11fb8a8121Smrg #define _PSTL_PARALLEL_BACKEND_UTILS_H
12181254a7Smrg
13181254a7Smrg #include <iterator>
14181254a7Smrg #include <utility>
15181254a7Smrg #include "utils.h"
16181254a7Smrg
17181254a7Smrg namespace __pstl
18181254a7Smrg {
19*b1e83836Smrg
20*b1e83836Smrg namespace __utils
21181254a7Smrg {
22181254a7Smrg
23181254a7Smrg //! Destroy sequence [xs,xe)
24181254a7Smrg struct __serial_destroy
25181254a7Smrg {
26181254a7Smrg template <typename _RandomAccessIterator>
27181254a7Smrg void
operator__serial_destroy28181254a7Smrg operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
29181254a7Smrg {
30181254a7Smrg typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
31181254a7Smrg while (__zs != __ze)
32181254a7Smrg {
33181254a7Smrg --__ze;
34181254a7Smrg (*__ze).~_ValueType();
35181254a7Smrg }
36181254a7Smrg }
37181254a7Smrg };
38181254a7Smrg
39181254a7Smrg //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
40181254a7Smrg struct __serial_move_merge
41181254a7Smrg {
42181254a7Smrg const std::size_t _M_nmerge;
43181254a7Smrg
__serial_move_merge__serial_move_merge44*b1e83836Smrg explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
45*b1e83836Smrg template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
46*b1e83836Smrg class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
47181254a7Smrg void
operator__serial_move_merge48181254a7Smrg operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
49*b1e83836Smrg _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
50*b1e83836Smrg _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
51181254a7Smrg {
52*b1e83836Smrg constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
53*b1e83836Smrg constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
54*b1e83836Smrg
55181254a7Smrg auto __n = _M_nmerge;
56fb8a8121Smrg _PSTL_ASSERT(__n > 0);
57*b1e83836Smrg
58*b1e83836Smrg auto __nx = __xe - __xs;
59*b1e83836Smrg //auto __ny = __ye - __ys;
60*b1e83836Smrg _RandomAccessIterator3 __zs_beg = __zs;
61*b1e83836Smrg
62181254a7Smrg if (__xs != __xe)
63181254a7Smrg {
64181254a7Smrg if (__ys != __ye)
65181254a7Smrg {
66181254a7Smrg for (;;)
67181254a7Smrg {
68181254a7Smrg if (__comp(*__ys, *__xs))
69181254a7Smrg {
70*b1e83836Smrg const auto __i = __zs - __zs_beg;
71*b1e83836Smrg if (__i < __nx)
72*b1e83836Smrg __move_value_x(__ys, __zs);
73*b1e83836Smrg else
74*b1e83836Smrg __move_value_y(__ys, __zs);
75181254a7Smrg ++__zs, --__n;
76181254a7Smrg if (++__ys == __ye)
77181254a7Smrg {
78181254a7Smrg break;
79181254a7Smrg }
80181254a7Smrg else if (__n == 0)
81181254a7Smrg {
82*b1e83836Smrg const auto __j = __zs - __zs_beg;
83*b1e83836Smrg if (__same_move_seq || __j < __nx)
84*b1e83836Smrg __zs = __move_sequence_x(__ys, __ye, __zs);
85*b1e83836Smrg else
86*b1e83836Smrg __zs = __move_sequence_y(__ys, __ye, __zs);
87181254a7Smrg break;
88181254a7Smrg }
89181254a7Smrg }
90181254a7Smrg else
91181254a7Smrg {
92*b1e83836Smrg const auto __i = __zs - __zs_beg;
93*b1e83836Smrg if (__same_move_val || __i < __nx)
94*b1e83836Smrg __move_value_x(__xs, __zs);
95*b1e83836Smrg else
96*b1e83836Smrg __move_value_y(__xs, __zs);
97181254a7Smrg ++__zs, --__n;
98181254a7Smrg if (++__xs == __xe)
99181254a7Smrg {
100*b1e83836Smrg const auto __j = __zs - __zs_beg;
101*b1e83836Smrg if (__same_move_seq || __j < __nx)
102*b1e83836Smrg __move_sequence_x(__ys, __ye, __zs);
103*b1e83836Smrg else
104*b1e83836Smrg __move_sequence_y(__ys, __ye, __zs);
105181254a7Smrg return;
106181254a7Smrg }
107181254a7Smrg else if (__n == 0)
108181254a7Smrg {
109*b1e83836Smrg const auto __j = __zs - __zs_beg;
110*b1e83836Smrg if (__same_move_seq || __j < __nx)
111*b1e83836Smrg {
112*b1e83836Smrg __zs = __move_sequence_x(__xs, __xe, __zs);
113*b1e83836Smrg __move_sequence_x(__ys, __ye, __zs);
114181254a7Smrg }
115181254a7Smrg else
116181254a7Smrg {
117*b1e83836Smrg __zs = __move_sequence_y(__xs, __xe, __zs);
118*b1e83836Smrg __move_sequence_y(__ys, __ye, __zs);
119*b1e83836Smrg }
120*b1e83836Smrg return;
121181254a7Smrg }
122181254a7Smrg }
123181254a7Smrg }
124181254a7Smrg }
125181254a7Smrg __ys = __xs;
126181254a7Smrg __ye = __xe;
127181254a7Smrg }
128*b1e83836Smrg const auto __i = __zs - __zs_beg;
129*b1e83836Smrg if (__same_move_seq || __i < __nx)
130*b1e83836Smrg __move_sequence_x(__ys, __ye, __zs);
131*b1e83836Smrg else
132*b1e83836Smrg __move_sequence_y(__ys, __ye, __zs);
133181254a7Smrg }
134181254a7Smrg };
135181254a7Smrg
136*b1e83836Smrg template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
137*b1e83836Smrg typename _CopyConstructRange>
138*b1e83836Smrg _OutputIterator
__set_union_construct(_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_OutputIterator __result,_Compare __comp,_CopyConstructRange __cc_range)139*b1e83836Smrg __set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
140*b1e83836Smrg _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
141*b1e83836Smrg _CopyConstructRange __cc_range)
142181254a7Smrg {
143*b1e83836Smrg using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
144*b1e83836Smrg
145*b1e83836Smrg for (; __first1 != __last1; ++__result)
146181254a7Smrg {
147*b1e83836Smrg if (__first2 == __last2)
148*b1e83836Smrg return __cc_range(__first1, __last1, __result);
149*b1e83836Smrg if (__comp(*__first2, *__first1))
150*b1e83836Smrg {
151*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first2);
152*b1e83836Smrg ++__first2;
153181254a7Smrg }
154181254a7Smrg else
155181254a7Smrg {
156*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first1);
157*b1e83836Smrg if (!__comp(*__first1, *__first2))
158*b1e83836Smrg ++__first2;
159*b1e83836Smrg ++__first1;
160181254a7Smrg }
161181254a7Smrg }
162*b1e83836Smrg return __cc_range(__first2, __last2, __result);
163*b1e83836Smrg }
164181254a7Smrg
165*b1e83836Smrg template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
166*b1e83836Smrg _OutputIterator
__set_intersection_construct(_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_OutputIterator __result,_Compare __comp)167*b1e83836Smrg __set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
168*b1e83836Smrg _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
169181254a7Smrg {
170*b1e83836Smrg using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
171181254a7Smrg
172*b1e83836Smrg for (; __first1 != __last1 && __first2 != __last2;)
173181254a7Smrg {
174*b1e83836Smrg if (__comp(*__first1, *__first2))
175*b1e83836Smrg ++__first1;
176*b1e83836Smrg else
177*b1e83836Smrg {
178*b1e83836Smrg if (!__comp(*__first2, *__first1))
179*b1e83836Smrg {
180*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first1);
181*b1e83836Smrg ++__result;
182*b1e83836Smrg ++__first1;
183*b1e83836Smrg }
184*b1e83836Smrg ++__first2;
185*b1e83836Smrg }
186*b1e83836Smrg }
187*b1e83836Smrg return __result;
188181254a7Smrg }
189181254a7Smrg
190*b1e83836Smrg template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
191*b1e83836Smrg typename _CopyConstructRange>
192*b1e83836Smrg _OutputIterator
__set_difference_construct(_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_OutputIterator __result,_Compare __comp,_CopyConstructRange __cc_range)193*b1e83836Smrg __set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
194*b1e83836Smrg _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
195*b1e83836Smrg _CopyConstructRange __cc_range)
196181254a7Smrg {
197*b1e83836Smrg using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
198181254a7Smrg
199*b1e83836Smrg for (; __first1 != __last1;)
200*b1e83836Smrg {
201*b1e83836Smrg if (__first2 == __last2)
202*b1e83836Smrg return __cc_range(__first1, __last1, __result);
203*b1e83836Smrg
204*b1e83836Smrg if (__comp(*__first1, *__first2))
205*b1e83836Smrg {
206*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first1);
207*b1e83836Smrg ++__result;
208*b1e83836Smrg ++__first1;
209*b1e83836Smrg }
210*b1e83836Smrg else
211*b1e83836Smrg {
212*b1e83836Smrg if (!__comp(*__first2, *__first1))
213*b1e83836Smrg ++__first1;
214*b1e83836Smrg ++__first2;
215*b1e83836Smrg }
216*b1e83836Smrg }
217*b1e83836Smrg return __result;
218*b1e83836Smrg }
219*b1e83836Smrg template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
220*b1e83836Smrg typename _CopyConstructRange>
221*b1e83836Smrg _OutputIterator
__set_symmetric_difference_construct(_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_OutputIterator __result,_Compare __comp,_CopyConstructRange __cc_range)222*b1e83836Smrg __set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
223*b1e83836Smrg _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
224*b1e83836Smrg _CopyConstructRange __cc_range)
225*b1e83836Smrg {
226*b1e83836Smrg using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
227*b1e83836Smrg
228*b1e83836Smrg for (; __first1 != __last1;)
229*b1e83836Smrg {
230*b1e83836Smrg if (__first2 == __last2)
231*b1e83836Smrg return __cc_range(__first1, __last1, __result);
232*b1e83836Smrg
233*b1e83836Smrg if (__comp(*__first1, *__first2))
234*b1e83836Smrg {
235*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first1);
236*b1e83836Smrg ++__result;
237*b1e83836Smrg ++__first1;
238*b1e83836Smrg }
239*b1e83836Smrg else
240*b1e83836Smrg {
241*b1e83836Smrg if (__comp(*__first2, *__first1))
242*b1e83836Smrg {
243*b1e83836Smrg ::new (std::addressof(*__result)) _Tp(*__first2);
244*b1e83836Smrg ++__result;
245*b1e83836Smrg }
246*b1e83836Smrg else
247*b1e83836Smrg ++__first1;
248*b1e83836Smrg ++__first2;
249*b1e83836Smrg }
250*b1e83836Smrg }
251*b1e83836Smrg return __cc_range(__first2, __last2, __result);
252*b1e83836Smrg }
253*b1e83836Smrg
254*b1e83836Smrg } // namespace __utils
255181254a7Smrg } // namespace __pstl
256181254a7Smrg
257fb8a8121Smrg #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
258