parallel_backend_utils.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 __par_backend
  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. template <class _MoveValues, class _MoveSequences>
  35. struct __serial_move_merge
  36. {
  37. const std::size_t _M_nmerge;
  38. _MoveValues _M_move_values;
  39. _MoveSequences _M_move_sequences;
  40. explicit __serial_move_merge(std::size_t __nmerge, _MoveValues __move_values, _MoveSequences __move_sequences)
  41. : _M_nmerge(__nmerge), _M_move_values(__move_values), _M_move_sequences(__move_sequences)
  42. {
  43. }
  44. template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
  45. void
  46. operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
  47. _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp)
  48. {
  49. auto __n = _M_nmerge;
  50. _PSTL_ASSERT(__n > 0);
  51. if (__xs != __xe)
  52. {
  53. if (__ys != __ye)
  54. {
  55. for (;;)
  56. {
  57. if (__comp(*__ys, *__xs))
  58. {
  59. _M_move_values(__ys, __zs);
  60. ++__zs, --__n;
  61. if (++__ys == __ye)
  62. {
  63. break;
  64. }
  65. else if (__n == 0)
  66. {
  67. __zs = _M_move_sequences(__ys, __ye, __zs);
  68. break;
  69. }
  70. else
  71. {
  72. }
  73. }
  74. else
  75. {
  76. _M_move_values(__xs, __zs);
  77. ++__zs, --__n;
  78. if (++__xs == __xe)
  79. {
  80. _M_move_sequences(__ys, __ye, __zs);
  81. return;
  82. }
  83. else if (__n == 0)
  84. {
  85. __zs = _M_move_sequences(__xs, __xe, __zs);
  86. _M_move_sequences(__ys, __ye, __zs);
  87. return;
  88. }
  89. else
  90. {
  91. }
  92. }
  93. }
  94. }
  95. __ys = __xs;
  96. __ye = __xe;
  97. }
  98. _M_move_sequences(__ys, __ye, __zs);
  99. }
  100. };
  101. template <typename _RandomAccessIterator1, typename _OutputIterator>
  102. void
  103. __init_buf(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _OutputIterator __zs, bool __bMove)
  104. {
  105. const _OutputIterator __ze = __zs + (__xe - __xs);
  106. typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType;
  107. if (__bMove)
  108. {
  109. // Initialize the temporary buffer and move keys to it.
  110. for (; __zs != __ze; ++__xs, ++__zs)
  111. new (&*__zs) _ValueType(std::move(*__xs));
  112. }
  113. else
  114. {
  115. // Initialize the temporary buffer
  116. for (; __zs != __ze; ++__zs)
  117. new (&*__zs) _ValueType;
  118. }
  119. }
  120. // TODO is this actually used anywhere?
  121. template <typename _Buf>
  122. class __stack
  123. {
  124. typedef typename std::iterator_traits<decltype(_Buf(0).get())>::value_type _ValueType;
  125. typedef typename std::iterator_traits<_ValueType*>::difference_type _DifferenceType;
  126. _Buf _M_buf;
  127. _ValueType* _M_ptr;
  128. _DifferenceType _M_maxsize;
  129. __stack(const __stack&) = delete;
  130. void
  131. operator=(const __stack&) = delete;
  132. public:
  133. __stack(_DifferenceType __max_size) : _M_buf(__max_size), _M_maxsize(__max_size) { _M_ptr = _M_buf.get(); }
  134. ~__stack()
  135. {
  136. _PSTL_ASSERT(size() <= _M_maxsize);
  137. while (!empty())
  138. pop();
  139. }
  140. const _Buf&
  141. buffer() const
  142. {
  143. return _M_buf;
  144. }
  145. size_t
  146. size() const
  147. {
  148. _PSTL_ASSERT(_M_ptr - _M_buf.get() <= _M_maxsize);
  149. _PSTL_ASSERT(_M_ptr - _M_buf.get() >= 0);
  150. return _M_ptr - _M_buf.get();
  151. }
  152. bool
  153. empty() const
  154. {
  155. _PSTL_ASSERT(_M_ptr >= _M_buf.get());
  156. return _M_ptr == _M_buf.get();
  157. }
  158. void
  159. push(const _ValueType& __v)
  160. {
  161. _PSTL_ASSERT(size() < _M_maxsize);
  162. new (_M_ptr) _ValueType(__v);
  163. ++_M_ptr;
  164. }
  165. const _ValueType&
  166. top() const
  167. {
  168. return *(_M_ptr - 1);
  169. }
  170. void
  171. pop()
  172. {
  173. _PSTL_ASSERT(_M_ptr > _M_buf.get());
  174. --_M_ptr;
  175. (*_M_ptr).~_ValueType();
  176. }
  177. };
  178. } // namespace __par_backend
  179. } // namespace __pstl
  180. #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */