xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/pstl/parallel_backend_utils.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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