| 1 | // -*- C++ -*-
 | 
|---|
| 2 | //===-- parallel_backend_utils.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_PARALLEL_BACKEND_UTILS_H
 | 
|---|
| 11 | #define _PSTL_PARALLEL_BACKEND_UTILS_H
 | 
|---|
| 12 | 
 | 
|---|
| 13 | #include <iterator>
 | 
|---|
| 14 | #include <utility>
 | 
|---|
| 15 | #include "utils.h"
 | 
|---|
| 16 | 
 | 
|---|
| 17 | namespace __pstl
 | 
|---|
| 18 | {
 | 
|---|
| 19 | 
 | 
|---|
| 20 | namespace __utils
 | 
|---|
| 21 | {
 | 
|---|
| 22 | 
 | 
|---|
| 23 | //! Destroy sequence [xs,xe)
 | 
|---|
| 24 | struct __serial_destroy
 | 
|---|
| 25 | {
 | 
|---|
| 26 |     template <typename _RandomAccessIterator>
 | 
|---|
| 27 |     void
 | 
|---|
| 28 |     operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
 | 
|---|
| 29 |     {
 | 
|---|
| 30 |         typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
 | 
|---|
| 31 |         while (__zs != __ze)
 | 
|---|
| 32 |         {
 | 
|---|
| 33 |             --__ze;
 | 
|---|
| 34 |             (*__ze).~_ValueType();
 | 
|---|
| 35 |         }
 | 
|---|
| 36 |     }
 | 
|---|
| 37 | };
 | 
|---|
| 38 | 
 | 
|---|
| 39 | //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
 | 
|---|
| 40 | struct __serial_move_merge
 | 
|---|
| 41 | {
 | 
|---|
| 42 |     const std::size_t _M_nmerge;
 | 
|---|
| 43 | 
 | 
|---|
| 44 |     explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
 | 
|---|
| 45 |     template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
 | 
|---|
| 46 |               class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
 | 
|---|
| 47 |     void
 | 
|---|
| 48 |     operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
 | 
|---|
| 49 |                _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
 | 
|---|
| 50 |                _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
 | 
|---|
| 51 |     {
 | 
|---|
| 52 |         constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
 | 
|---|
| 53 |         constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
 | 
|---|
| 54 | 
 | 
|---|
| 55 |         auto __n = _M_nmerge;
 | 
|---|
| 56 |         _PSTL_ASSERT(__n > 0);
 | 
|---|
| 57 | 
 | 
|---|
| 58 |         auto __nx = __xe - __xs;
 | 
|---|
| 59 |         //auto __ny = __ye - __ys;
 | 
|---|
| 60 |         _RandomAccessIterator3 __zs_beg = __zs;
 | 
|---|
| 61 | 
 | 
|---|
| 62 |         if (__xs != __xe)
 | 
|---|
| 63 |         {
 | 
|---|
| 64 |             if (__ys != __ye)
 | 
|---|
| 65 |             {
 | 
|---|
| 66 |                 for (;;)
 | 
|---|
| 67 |                 {
 | 
|---|
| 68 |                     if (__comp(*__ys, *__xs))
 | 
|---|
| 69 |                     {
 | 
|---|
| 70 |                         const auto __i = __zs - __zs_beg;
 | 
|---|
| 71 |                         if (__i < __nx)
 | 
|---|
| 72 |                             __move_value_x(__ys, __zs);
 | 
|---|
| 73 |                         else
 | 
|---|
| 74 |                             __move_value_y(__ys, __zs);
 | 
|---|
| 75 |                         ++__zs, --__n;
 | 
|---|
| 76 |                         if (++__ys == __ye)
 | 
|---|
| 77 |                         {
 | 
|---|
| 78 |                             break;
 | 
|---|
| 79 |                         }
 | 
|---|
| 80 |                         else if (__n == 0)
 | 
|---|
| 81 |                         {
 | 
|---|
| 82 |                             const auto __j = __zs - __zs_beg;
 | 
|---|
| 83 |                             if (__same_move_seq || __j < __nx)
 | 
|---|
| 84 |                                 __zs = __move_sequence_x(__ys, __ye, __zs);
 | 
|---|
| 85 |                             else
 | 
|---|
| 86 |                                 __zs = __move_sequence_y(__ys, __ye, __zs);
 | 
|---|
| 87 |                             break;
 | 
|---|
| 88 |                         }
 | 
|---|
| 89 |                     }
 | 
|---|
| 90 |                     else
 | 
|---|
| 91 |                     {
 | 
|---|
| 92 |                         const auto __i = __zs - __zs_beg;
 | 
|---|
| 93 |                         if (__same_move_val || __i < __nx)
 | 
|---|
| 94 |                             __move_value_x(__xs, __zs);
 | 
|---|
| 95 |                         else
 | 
|---|
| 96 |                             __move_value_y(__xs, __zs);
 | 
|---|
| 97 |                         ++__zs, --__n;
 | 
|---|
| 98 |                         if (++__xs == __xe)
 | 
|---|
| 99 |                         {
 | 
|---|
| 100 |                             const auto __j = __zs - __zs_beg;
 | 
|---|
| 101 |                             if (__same_move_seq || __j < __nx)
 | 
|---|
| 102 |                                 __move_sequence_x(__ys, __ye, __zs);
 | 
|---|
| 103 |                             else
 | 
|---|
| 104 |                                 __move_sequence_y(__ys, __ye, __zs);
 | 
|---|
| 105 |                             return;
 | 
|---|
| 106 |                         }
 | 
|---|
| 107 |                         else if (__n == 0)
 | 
|---|
| 108 |                         {
 | 
|---|
| 109 |                             const auto __j = __zs - __zs_beg;
 | 
|---|
| 110 |                             if (__same_move_seq || __j < __nx)
 | 
|---|
| 111 |                             {
 | 
|---|
| 112 |                                 __zs = __move_sequence_x(__xs, __xe, __zs);
 | 
|---|
| 113 |                                 __move_sequence_x(__ys, __ye, __zs);
 | 
|---|
| 114 |                             }
 | 
|---|
| 115 |                             else
 | 
|---|
| 116 |                             {
 | 
|---|
| 117 |                                 __zs = __move_sequence_y(__xs, __xe, __zs);
 | 
|---|
| 118 |                                 __move_sequence_y(__ys, __ye, __zs);
 | 
|---|
| 119 |                             }
 | 
|---|
| 120 |                             return;
 | 
|---|
| 121 |                         }
 | 
|---|
| 122 |                     }
 | 
|---|
| 123 |                 }
 | 
|---|
| 124 |             }
 | 
|---|
| 125 |             __ys = __xs;
 | 
|---|
| 126 |             __ye = __xe;
 | 
|---|
| 127 |         }
 | 
|---|
| 128 |         const auto __i = __zs - __zs_beg;
 | 
|---|
| 129 |         if (__same_move_seq || __i < __nx)
 | 
|---|
| 130 |             __move_sequence_x(__ys, __ye, __zs);
 | 
|---|
| 131 |         else
 | 
|---|
| 132 |             __move_sequence_y(__ys, __ye, __zs);
 | 
|---|
| 133 |     }
 | 
|---|
| 134 | };
 | 
|---|
| 135 | 
 | 
|---|
| 136 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
 | 
|---|
| 137 |           typename _CopyConstructRange>
 | 
|---|
| 138 | _OutputIterator
 | 
|---|
| 139 | __set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
 | 
|---|
| 140 |                       _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
 | 
|---|
| 141 |                       _CopyConstructRange __cc_range)
 | 
|---|
| 142 | {
 | 
|---|
| 143 |     using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
 | 
|---|
| 144 | 
 | 
|---|
| 145 |     for (; __first1 != __last1; ++__result)
 | 
|---|
| 146 |     {
 | 
|---|
| 147 |         if (__first2 == __last2)
 | 
|---|
| 148 |             return __cc_range(__first1, __last1, __result);
 | 
|---|
| 149 |         if (__comp(*__first2, *__first1))
 | 
|---|
| 150 |         {
 | 
|---|
| 151 |             ::new (std::addressof(*__result)) _Tp(*__first2);
 | 
|---|
| 152 |             ++__first2;
 | 
|---|
| 153 |         }
 | 
|---|
| 154 |         else
 | 
|---|
| 155 |         {
 | 
|---|
| 156 |             ::new (std::addressof(*__result)) _Tp(*__first1);
 | 
|---|
| 157 |             if (!__comp(*__first1, *__first2))
 | 
|---|
| 158 |                 ++__first2;
 | 
|---|
| 159 |             ++__first1;
 | 
|---|
| 160 |         }
 | 
|---|
| 161 |     }
 | 
|---|
| 162 |     return __cc_range(__first2, __last2, __result);
 | 
|---|
| 163 | }
 | 
|---|
| 164 | 
 | 
|---|
| 165 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
 | 
|---|
| 166 | _OutputIterator
 | 
|---|
| 167 | __set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
 | 
|---|
| 168 |                              _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
 | 
|---|
| 169 | {
 | 
|---|
| 170 |     using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     for (; __first1 != __last1 && __first2 != __last2;)
 | 
|---|
| 173 |     {
 | 
|---|
| 174 |         if (__comp(*__first1, *__first2))
 | 
|---|
| 175 |             ++__first1;
 | 
|---|
| 176 |         else
 | 
|---|
| 177 |         {
 | 
|---|
| 178 |             if (!__comp(*__first2, *__first1))
 | 
|---|
| 179 |             {
 | 
|---|
| 180 |                 ::new (std::addressof(*__result)) _Tp(*__first1);
 | 
|---|
| 181 |                 ++__result;
 | 
|---|
| 182 |                 ++__first1;
 | 
|---|
| 183 |             }
 | 
|---|
| 184 |             ++__first2;
 | 
|---|
| 185 |         }
 | 
|---|
| 186 |     }
 | 
|---|
| 187 |     return __result;
 | 
|---|
| 188 | }
 | 
|---|
| 189 | 
 | 
|---|
| 190 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
 | 
|---|
| 191 |           typename _CopyConstructRange>
 | 
|---|
| 192 | _OutputIterator
 | 
|---|
| 193 | __set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
 | 
|---|
| 194 |                            _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
 | 
|---|
| 195 |                            _CopyConstructRange __cc_range)
 | 
|---|
| 196 | {
 | 
|---|
| 197 |     using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
 | 
|---|
| 198 | 
 | 
|---|
| 199 |     for (; __first1 != __last1;)
 | 
|---|
| 200 |     {
 | 
|---|
| 201 |         if (__first2 == __last2)
 | 
|---|
| 202 |             return __cc_range(__first1, __last1, __result);
 | 
|---|
| 203 | 
 | 
|---|
| 204 |         if (__comp(*__first1, *__first2))
 | 
|---|
| 205 |         {
 | 
|---|
| 206 |             ::new (std::addressof(*__result)) _Tp(*__first1);
 | 
|---|
| 207 |             ++__result;
 | 
|---|
| 208 |             ++__first1;
 | 
|---|
| 209 |         }
 | 
|---|
| 210 |         else
 | 
|---|
| 211 |         {
 | 
|---|
| 212 |             if (!__comp(*__first2, *__first1))
 | 
|---|
| 213 |                 ++__first1;
 | 
|---|
| 214 |             ++__first2;
 | 
|---|
| 215 |         }
 | 
|---|
| 216 |     }
 | 
|---|
| 217 |     return __result;
 | 
|---|
| 218 | }
 | 
|---|
| 219 | template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
 | 
|---|
| 220 |           typename _CopyConstructRange>
 | 
|---|
| 221 | _OutputIterator
 | 
|---|
| 222 | __set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
 | 
|---|
| 223 |                                      _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
 | 
|---|
| 224 |                                      _CopyConstructRange __cc_range)
 | 
|---|
| 225 | {
 | 
|---|
| 226 |     using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
 | 
|---|
| 227 | 
 | 
|---|
| 228 |     for (; __first1 != __last1;)
 | 
|---|
| 229 |     {
 | 
|---|
| 230 |         if (__first2 == __last2)
 | 
|---|
| 231 |             return __cc_range(__first1, __last1, __result);
 | 
|---|
| 232 | 
 | 
|---|
| 233 |         if (__comp(*__first1, *__first2))
 | 
|---|
| 234 |         {
 | 
|---|
| 235 |             ::new (std::addressof(*__result)) _Tp(*__first1);
 | 
|---|
| 236 |             ++__result;
 | 
|---|
| 237 |             ++__first1;
 | 
|---|
| 238 |         }
 | 
|---|
| 239 |         else
 | 
|---|
| 240 |         {
 | 
|---|
| 241 |             if (__comp(*__first2, *__first1))
 | 
|---|
| 242 |             {
 | 
|---|
| 243 |                 ::new (std::addressof(*__result)) _Tp(*__first2);
 | 
|---|
| 244 |                 ++__result;
 | 
|---|
| 245 |             }
 | 
|---|
| 246 |             else
 | 
|---|
| 247 |                 ++__first1;
 | 
|---|
| 248 |             ++__first2;
 | 
|---|
| 249 |         }
 | 
|---|
| 250 |     }
 | 
|---|
| 251 |     return __cc_range(__first2, __last2, __result);
 | 
|---|
| 252 | }
 | 
|---|
| 253 | 
 | 
|---|
| 254 | } // namespace __utils
 | 
|---|
| 255 | } // namespace __pstl
 | 
|---|
| 256 | 
 | 
|---|
| 257 | #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
 | 
|---|