1627f7eb2Smrg // -*- C++ -*-
2627f7eb2Smrg //===-- parallel_backend_utils.h ------------------------------------------===//
3627f7eb2Smrg //
4627f7eb2Smrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5627f7eb2Smrg // See https://llvm.org/LICENSE.txt for license information.
6627f7eb2Smrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7627f7eb2Smrg //
8627f7eb2Smrg //===----------------------------------------------------------------------===//
9627f7eb2Smrg
10*4c3eb207Smrg #ifndef _PSTL_PARALLEL_BACKEND_UTILS_H
11*4c3eb207Smrg #define _PSTL_PARALLEL_BACKEND_UTILS_H
12627f7eb2Smrg
13627f7eb2Smrg #include <iterator>
14627f7eb2Smrg #include <utility>
15627f7eb2Smrg #include "utils.h"
16627f7eb2Smrg
17627f7eb2Smrg namespace __pstl
18627f7eb2Smrg {
19627f7eb2Smrg namespace __par_backend
20627f7eb2Smrg {
21627f7eb2Smrg
22627f7eb2Smrg //! Destroy sequence [xs,xe)
23627f7eb2Smrg struct __serial_destroy
24627f7eb2Smrg {
25627f7eb2Smrg template <typename _RandomAccessIterator>
26627f7eb2Smrg void
operator__serial_destroy27627f7eb2Smrg operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
28627f7eb2Smrg {
29627f7eb2Smrg typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
30627f7eb2Smrg while (__zs != __ze)
31627f7eb2Smrg {
32627f7eb2Smrg --__ze;
33627f7eb2Smrg (*__ze).~_ValueType();
34627f7eb2Smrg }
35627f7eb2Smrg }
36627f7eb2Smrg };
37627f7eb2Smrg
38627f7eb2Smrg //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
39627f7eb2Smrg template <class _MoveValues, class _MoveSequences>
40627f7eb2Smrg struct __serial_move_merge
41627f7eb2Smrg {
42627f7eb2Smrg const std::size_t _M_nmerge;
43627f7eb2Smrg _MoveValues _M_move_values;
44627f7eb2Smrg _MoveSequences _M_move_sequences;
45627f7eb2Smrg
__serial_move_merge__serial_move_merge46627f7eb2Smrg explicit __serial_move_merge(std::size_t __nmerge, _MoveValues __move_values, _MoveSequences __move_sequences)
47627f7eb2Smrg : _M_nmerge(__nmerge), _M_move_values(__move_values), _M_move_sequences(__move_sequences)
48627f7eb2Smrg {
49627f7eb2Smrg }
50627f7eb2Smrg template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
51627f7eb2Smrg void
operator__serial_move_merge52627f7eb2Smrg operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
53627f7eb2Smrg _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp)
54627f7eb2Smrg {
55627f7eb2Smrg auto __n = _M_nmerge;
56*4c3eb207Smrg _PSTL_ASSERT(__n > 0);
57627f7eb2Smrg if (__xs != __xe)
58627f7eb2Smrg {
59627f7eb2Smrg if (__ys != __ye)
60627f7eb2Smrg {
61627f7eb2Smrg for (;;)
62627f7eb2Smrg {
63627f7eb2Smrg if (__comp(*__ys, *__xs))
64627f7eb2Smrg {
65627f7eb2Smrg _M_move_values(__ys, __zs);
66627f7eb2Smrg ++__zs, --__n;
67627f7eb2Smrg if (++__ys == __ye)
68627f7eb2Smrg {
69627f7eb2Smrg break;
70627f7eb2Smrg }
71627f7eb2Smrg else if (__n == 0)
72627f7eb2Smrg {
73627f7eb2Smrg __zs = _M_move_sequences(__ys, __ye, __zs);
74627f7eb2Smrg break;
75627f7eb2Smrg }
76627f7eb2Smrg else
77627f7eb2Smrg {
78627f7eb2Smrg }
79627f7eb2Smrg }
80627f7eb2Smrg else
81627f7eb2Smrg {
82627f7eb2Smrg _M_move_values(__xs, __zs);
83627f7eb2Smrg ++__zs, --__n;
84627f7eb2Smrg if (++__xs == __xe)
85627f7eb2Smrg {
86627f7eb2Smrg _M_move_sequences(__ys, __ye, __zs);
87627f7eb2Smrg return;
88627f7eb2Smrg }
89627f7eb2Smrg else if (__n == 0)
90627f7eb2Smrg {
91627f7eb2Smrg __zs = _M_move_sequences(__xs, __xe, __zs);
92627f7eb2Smrg _M_move_sequences(__ys, __ye, __zs);
93627f7eb2Smrg return;
94627f7eb2Smrg }
95627f7eb2Smrg else
96627f7eb2Smrg {
97627f7eb2Smrg }
98627f7eb2Smrg }
99627f7eb2Smrg }
100627f7eb2Smrg }
101627f7eb2Smrg __ys = __xs;
102627f7eb2Smrg __ye = __xe;
103627f7eb2Smrg }
104627f7eb2Smrg _M_move_sequences(__ys, __ye, __zs);
105627f7eb2Smrg }
106627f7eb2Smrg };
107627f7eb2Smrg
108627f7eb2Smrg template <typename _RandomAccessIterator1, typename _OutputIterator>
109627f7eb2Smrg void
__init_buf(_RandomAccessIterator1 __xs,_RandomAccessIterator1 __xe,_OutputIterator __zs,bool __bMove)110627f7eb2Smrg __init_buf(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _OutputIterator __zs, bool __bMove)
111627f7eb2Smrg {
112627f7eb2Smrg const _OutputIterator __ze = __zs + (__xe - __xs);
113627f7eb2Smrg typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType;
114627f7eb2Smrg if (__bMove)
115627f7eb2Smrg {
116627f7eb2Smrg // Initialize the temporary buffer and move keys to it.
117627f7eb2Smrg for (; __zs != __ze; ++__xs, ++__zs)
118627f7eb2Smrg new (&*__zs) _ValueType(std::move(*__xs));
119627f7eb2Smrg }
120627f7eb2Smrg else
121627f7eb2Smrg {
122627f7eb2Smrg // Initialize the temporary buffer
123627f7eb2Smrg for (; __zs != __ze; ++__zs)
124627f7eb2Smrg new (&*__zs) _ValueType;
125627f7eb2Smrg }
126627f7eb2Smrg }
127627f7eb2Smrg
128627f7eb2Smrg // TODO is this actually used anywhere?
129627f7eb2Smrg template <typename _Buf>
130627f7eb2Smrg class __stack
131627f7eb2Smrg {
132627f7eb2Smrg typedef typename std::iterator_traits<decltype(_Buf(0).get())>::value_type _ValueType;
133627f7eb2Smrg typedef typename std::iterator_traits<_ValueType*>::difference_type _DifferenceType;
134627f7eb2Smrg
135627f7eb2Smrg _Buf _M_buf;
136627f7eb2Smrg _ValueType* _M_ptr;
137627f7eb2Smrg _DifferenceType _M_maxsize;
138627f7eb2Smrg
139627f7eb2Smrg __stack(const __stack&) = delete;
140627f7eb2Smrg void
141627f7eb2Smrg operator=(const __stack&) = delete;
142627f7eb2Smrg
143627f7eb2Smrg public:
__stack(_DifferenceType __max_size)144627f7eb2Smrg __stack(_DifferenceType __max_size) : _M_buf(__max_size), _M_maxsize(__max_size) { _M_ptr = _M_buf.get(); }
145627f7eb2Smrg
~__stack()146627f7eb2Smrg ~__stack()
147627f7eb2Smrg {
148*4c3eb207Smrg _PSTL_ASSERT(size() <= _M_maxsize);
149627f7eb2Smrg while (!empty())
150627f7eb2Smrg pop();
151627f7eb2Smrg }
152627f7eb2Smrg
153627f7eb2Smrg const _Buf&
buffer()154627f7eb2Smrg buffer() const
155627f7eb2Smrg {
156627f7eb2Smrg return _M_buf;
157627f7eb2Smrg }
158627f7eb2Smrg size_t
size()159627f7eb2Smrg size() const
160627f7eb2Smrg {
161*4c3eb207Smrg _PSTL_ASSERT(_M_ptr - _M_buf.get() <= _M_maxsize);
162*4c3eb207Smrg _PSTL_ASSERT(_M_ptr - _M_buf.get() >= 0);
163627f7eb2Smrg return _M_ptr - _M_buf.get();
164627f7eb2Smrg }
165627f7eb2Smrg bool
empty()166627f7eb2Smrg empty() const
167627f7eb2Smrg {
168*4c3eb207Smrg _PSTL_ASSERT(_M_ptr >= _M_buf.get());
169627f7eb2Smrg return _M_ptr == _M_buf.get();
170627f7eb2Smrg }
171627f7eb2Smrg void
push(const _ValueType & __v)172627f7eb2Smrg push(const _ValueType& __v)
173627f7eb2Smrg {
174*4c3eb207Smrg _PSTL_ASSERT(size() < _M_maxsize);
175627f7eb2Smrg new (_M_ptr) _ValueType(__v);
176627f7eb2Smrg ++_M_ptr;
177627f7eb2Smrg }
178627f7eb2Smrg const _ValueType&
top()179627f7eb2Smrg top() const
180627f7eb2Smrg {
181627f7eb2Smrg return *(_M_ptr - 1);
182627f7eb2Smrg }
183627f7eb2Smrg void
pop()184627f7eb2Smrg pop()
185627f7eb2Smrg {
186*4c3eb207Smrg _PSTL_ASSERT(_M_ptr > _M_buf.get());
187627f7eb2Smrg --_M_ptr;
188627f7eb2Smrg (*_M_ptr).~_ValueType();
189627f7eb2Smrg }
190627f7eb2Smrg };
191627f7eb2Smrg
192627f7eb2Smrg } // namespace __par_backend
193627f7eb2Smrg } // namespace __pstl
194627f7eb2Smrg
195*4c3eb207Smrg #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
196