| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // -*- C++ -*-
- //===-- parallel_backend_utils.h ------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef _PSTL_PARALLEL_BACKEND_UTILS_H
- #define _PSTL_PARALLEL_BACKEND_UTILS_H
- #include <iterator>
- #include <utility>
- #include "utils.h"
- namespace __pstl
- {
- namespace __utils
- {
- //! Destroy sequence [xs,xe)
- struct __serial_destroy
- {
- template <typename _RandomAccessIterator>
- void
- operator()(_RandomAccessIterator __zs, _RandomAccessIterator __ze)
- {
- typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _ValueType;
- while (__zs != __ze)
- {
- --__ze;
- (*__ze).~_ValueType();
- }
- }
- };
- //! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
- struct __serial_move_merge
- {
- const std::size_t _M_nmerge;
- explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
- template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
- class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
- void
- operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
- _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
- _MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
- {
- constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
- constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
- auto __n = _M_nmerge;
- _PSTL_ASSERT(__n > 0);
- auto __nx = __xe - __xs;
- //auto __ny = __ye - __ys;
- _RandomAccessIterator3 __zs_beg = __zs;
- if (__xs != __xe)
- {
- if (__ys != __ye)
- {
- for (;;)
- {
- if (__comp(*__ys, *__xs))
- {
- const auto __i = __zs - __zs_beg;
- if (__i < __nx)
- __move_value_x(__ys, __zs);
- else
- __move_value_y(__ys, __zs);
- ++__zs, --__n;
- if (++__ys == __ye)
- {
- break;
- }
- else if (__n == 0)
- {
- const auto __j = __zs - __zs_beg;
- if (__same_move_seq || __j < __nx)
- __zs = __move_sequence_x(__ys, __ye, __zs);
- else
- __zs = __move_sequence_y(__ys, __ye, __zs);
- break;
- }
- }
- else
- {
- const auto __i = __zs - __zs_beg;
- if (__same_move_val || __i < __nx)
- __move_value_x(__xs, __zs);
- else
- __move_value_y(__xs, __zs);
- ++__zs, --__n;
- if (++__xs == __xe)
- {
- const auto __j = __zs - __zs_beg;
- if (__same_move_seq || __j < __nx)
- __move_sequence_x(__ys, __ye, __zs);
- else
- __move_sequence_y(__ys, __ye, __zs);
- return;
- }
- else if (__n == 0)
- {
- const auto __j = __zs - __zs_beg;
- if (__same_move_seq || __j < __nx)
- {
- __zs = __move_sequence_x(__xs, __xe, __zs);
- __move_sequence_x(__ys, __ye, __zs);
- }
- else
- {
- __zs = __move_sequence_y(__xs, __xe, __zs);
- __move_sequence_y(__ys, __ye, __zs);
- }
- return;
- }
- }
- }
- }
- __ys = __xs;
- __ye = __xe;
- }
- const auto __i = __zs - __zs_beg;
- if (__same_move_seq || __i < __nx)
- __move_sequence_x(__ys, __ye, __zs);
- else
- __move_sequence_y(__ys, __ye, __zs);
- }
- };
- template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
- typename _CopyConstructRange>
- _OutputIterator
- __set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
- _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
- _CopyConstructRange __cc_range)
- {
- using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
- for (; __first1 != __last1; ++__result)
- {
- if (__first2 == __last2)
- return __cc_range(__first1, __last1, __result);
- if (__comp(*__first2, *__first1))
- {
- ::new (std::addressof(*__result)) _Tp(*__first2);
- ++__first2;
- }
- else
- {
- ::new (std::addressof(*__result)) _Tp(*__first1);
- if (!__comp(*__first1, *__first2))
- ++__first2;
- ++__first1;
- }
- }
- return __cc_range(__first2, __last2, __result);
- }
- template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
- _OutputIterator
- __set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
- _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
- {
- using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
- for (; __first1 != __last1 && __first2 != __last2;)
- {
- if (__comp(*__first1, *__first2))
- ++__first1;
- else
- {
- if (!__comp(*__first2, *__first1))
- {
- ::new (std::addressof(*__result)) _Tp(*__first1);
- ++__result;
- ++__first1;
- }
- ++__first2;
- }
- }
- return __result;
- }
- template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
- typename _CopyConstructRange>
- _OutputIterator
- __set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
- _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
- _CopyConstructRange __cc_range)
- {
- using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
- for (; __first1 != __last1;)
- {
- if (__first2 == __last2)
- return __cc_range(__first1, __last1, __result);
- if (__comp(*__first1, *__first2))
- {
- ::new (std::addressof(*__result)) _Tp(*__first1);
- ++__result;
- ++__first1;
- }
- else
- {
- if (!__comp(*__first2, *__first1))
- ++__first1;
- ++__first2;
- }
- }
- return __result;
- }
- template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
- typename _CopyConstructRange>
- _OutputIterator
- __set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
- _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
- _CopyConstructRange __cc_range)
- {
- using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
- for (; __first1 != __last1;)
- {
- if (__first2 == __last2)
- return __cc_range(__first1, __last1, __result);
- if (__comp(*__first1, *__first2))
- {
- ::new (std::addressof(*__result)) _Tp(*__first1);
- ++__result;
- ++__first1;
- }
- else
- {
- if (__comp(*__first2, *__first1))
- {
- ::new (std::addressof(*__result)) _Tp(*__first2);
- ++__result;
- }
- else
- ++__first1;
- ++__first2;
- }
- }
- return __cc_range(__first2, __last2, __result);
- }
- } // namespace __utils
- } // namespace __pstl
- #endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */
|