parallel_backend_utils.h 8.9 KB

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