mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-16 13:01:21 +08:00
libstdc++: Rebase include/pstl to current upstream
From llvm-project/pstl @ 0b2e0e80d96 libstdc++-v3/ChangeLog: * include/pstl/algorithm_impl.h: Update file. * include/pstl/execution_impl.h: Likewise. * include/pstl/glue_algorithm_impl.h: Likewise. * include/pstl/glue_memory_impl.h: Likewise. * include/pstl/glue_numeric_impl.h: Likewise. * include/pstl/memory_impl.h: Likewise. * include/pstl/numeric_impl.h: Likewise. * include/pstl/parallel_backend.h: Likewise. * include/pstl/parallel_backend_serial.h: Likewise. * include/pstl/parallel_backend_tbb.h: Likewise. * include/pstl/parallel_backend_utils.h: Likewise. * include/pstl/pstl_config.h: Likewise. * include/pstl/unseq_backend_simd.h: Likewise.
This commit is contained in:
parent
310fe80bab
commit
e957b86ca2
@ -402,9 +402,7 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _
|
||||
if (__last1 - __first1 != __last2 - __first2)
|
||||
return false;
|
||||
|
||||
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2,
|
||||
__internal::__not_pred<_BinaryPredicate>(__p))
|
||||
.first == __last1;
|
||||
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
|
||||
@ -454,8 +452,7 @@ bool
|
||||
__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
|
||||
_BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept
|
||||
{
|
||||
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, __not_pred<_BinaryPredicate>(__p))
|
||||
.first == __last1;
|
||||
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
|
||||
@ -599,21 +596,19 @@ _RandomAccessIterator
|
||||
__find_subrange(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __global_last,
|
||||
_Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector) noexcept
|
||||
{
|
||||
if (__global_last - __first < __count || __count < 1)
|
||||
if (static_cast<_Size>(__global_last - __first) < __count || __count < 1)
|
||||
{
|
||||
return __last; // According to the standard last shall be returned when count < 1
|
||||
}
|
||||
|
||||
auto __n = __global_last - __first;
|
||||
auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred);
|
||||
while (__first != __last && (__global_last - __first >= __count))
|
||||
while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count))
|
||||
{
|
||||
__first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector);
|
||||
|
||||
// check that all of elements in [first+1, first+count) equal to value
|
||||
if (__first != __last && (__global_last - __first >= __count) &&
|
||||
!__internal::__brick_any_of(__first + 1, __first + __count,
|
||||
__not_pred<decltype(__unary_pred)>(__unary_pred), __is_vector))
|
||||
if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) &&
|
||||
!__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector))
|
||||
{
|
||||
return __first;
|
||||
}
|
||||
@ -821,7 +816,7 @@ __pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Ra
|
||||
_Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::true_type) noexcept
|
||||
{
|
||||
if (__last - __first == __count)
|
||||
if (static_cast<_Size>(__last - __first) == __count)
|
||||
{
|
||||
const bool __result = !__internal::__pattern_any_of(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
@ -903,6 +898,36 @@ __brick_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _Outpu
|
||||
[](_RandomAccessIterator __first, _OutputIterator __result) { *__result = std::move(*__first); });
|
||||
}
|
||||
|
||||
struct __brick_move_destroy
|
||||
{
|
||||
template <typename _Iterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::true_type) const
|
||||
{
|
||||
using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;
|
||||
|
||||
return __unseq_backend::__simd_assign(__first, __last - __first, __result,
|
||||
[](_Iterator __first, _OutputIterator __result) {
|
||||
*__result = std::move(*__first);
|
||||
(*__first).~_IteratorValueType();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename _Iterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::false_type) const
|
||||
{
|
||||
using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;
|
||||
|
||||
for (; __first != __last; ++__first, ++__result)
|
||||
{
|
||||
*__result = std::move(*__first);
|
||||
(*__first).~_IteratorValueType();
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// swap_ranges
|
||||
//------------------------------------------------------------------------
|
||||
@ -1224,10 +1249,16 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI
|
||||
[&__m](_DifferenceType __total) { __m = __total; });
|
||||
|
||||
// 3. Elements from result are moved to [first, last)
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
|
||||
[__result, __first, __is_vector](_Tp* __i, _Tp* __j) {
|
||||
__internal::__brick_move(__i, __j, __first + (__i - __result), __is_vector);
|
||||
});
|
||||
__par_backend::__parallel_for(
|
||||
std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
|
||||
[__result, __first, __is_vector](_Tp* __i, _Tp* __j) {
|
||||
__invoke_if_else(
|
||||
std::is_trivial<_Tp>(),
|
||||
[&]() { __brick_move(__i, __j, __first + (__i - __result), __is_vector); },
|
||||
[&]() {
|
||||
__brick_move_destroy()(__i, __j, __first + (__i - __result), __is_vector);
|
||||
});
|
||||
});
|
||||
return __first + __m;
|
||||
});
|
||||
}
|
||||
@ -1576,8 +1607,8 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt
|
||||
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m),
|
||||
[__first, __result, __is_vector](_Tp* __b, _Tp* __e) {
|
||||
__internal::__brick_move(__b, __e, __first + (__b - __result),
|
||||
__is_vector);
|
||||
__brick_move_destroy()(
|
||||
__b, __e, __first + (__b - __result), __is_vector);
|
||||
});
|
||||
|
||||
return __first + (__last - __middle);
|
||||
@ -1602,7 +1633,7 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt
|
||||
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
|
||||
[__n, __m, __first, __result, __is_vector](_Tp* __b, _Tp* __e) {
|
||||
__internal::__brick_move(
|
||||
__brick_move_destroy()(
|
||||
__b, __e, __first + ((__n - __m) + (__b - __result)), __is_vector);
|
||||
});
|
||||
|
||||
@ -1764,7 +1795,7 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F
|
||||
{
|
||||
// find first element that don't satisfy pred
|
||||
_ForwardIterator __x =
|
||||
__internal::__brick_find_if(__i + 1, __j, __not_pred<_UnaryPredicate>(__pred), __is_vector);
|
||||
__internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), __is_vector);
|
||||
if (__x != __j)
|
||||
{
|
||||
// find first element after "x" that satisfy pred
|
||||
@ -2087,8 +2118,7 @@ __pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Random
|
||||
__internal::__except_handler([&]() {
|
||||
__par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
[](_RandomAccessIterator __first, _RandomAccessIterator __last,
|
||||
_Compare __comp) { std::sort(__first, __last, __comp); },
|
||||
__last - __first);
|
||||
_Compare __comp) { std::sort(__first, __last, __comp); });
|
||||
});
|
||||
}
|
||||
|
||||
@ -2135,6 +2165,9 @@ __pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _Compare __comp, _IsVector, /*is_parallel=*/std::true_type)
|
||||
{
|
||||
const auto __n = __middle - __first;
|
||||
if (__n == 0)
|
||||
return;
|
||||
|
||||
__internal::__except_handler([&]() {
|
||||
__par_backend::__parallel_stable_sort(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
@ -2223,8 +2256,13 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first,
|
||||
// 3. Move elements from temporary __buffer to output
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2,
|
||||
[__r, __d_first, __is_vector](_T1* __i, _T1* __j) {
|
||||
__internal::__brick_move(__i, __j, __d_first + (__i - __r), __is_vector);
|
||||
__brick_move_destroy()(
|
||||
__i, __j, __d_first + (__i - __r), __is_vector);
|
||||
});
|
||||
__par_backend::__parallel_for(
|
||||
std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1,
|
||||
[__is_vector](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, __is_vector); });
|
||||
|
||||
return __d_first + __n2;
|
||||
}
|
||||
});
|
||||
@ -2244,7 +2282,7 @@ __brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _Binary
|
||||
template <class _ForwardIterator, class _BinaryPredicate>
|
||||
_ForwardIterator
|
||||
__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
|
||||
/* IsVector = */ std::false_type, bool __or_semantic) noexcept
|
||||
/* IsVector = */ std::false_type, bool) noexcept
|
||||
{
|
||||
return std::adjacent_find(__first, __last, __pred);
|
||||
}
|
||||
@ -2670,16 +2708,14 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __firs
|
||||
[__n, __move_values, __move_sequences](_BidirectionalIterator __f1, _BidirectionalIterator __l1,
|
||||
_BidirectionalIterator __f2, _BidirectionalIterator __l2, _Tp* __f3,
|
||||
_Compare __comp) {
|
||||
auto __func = __par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(
|
||||
__n, __move_values, __move_sequences);
|
||||
__func(__f1, __l1, __f2, __l2, __f3, __comp);
|
||||
(__utils::__serial_move_merge(__n))(__f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values,
|
||||
__move_sequences, __move_sequences);
|
||||
return __f3 + (__l1 - __f1) + (__l2 - __f2);
|
||||
});
|
||||
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n,
|
||||
[__r, __first, __is_vector](_Tp* __i, _Tp* __j) {
|
||||
__internal::__brick_move(__i, __j, __first + (__i - __r), __is_vector);
|
||||
});
|
||||
__par_backend::__parallel_for(
|
||||
std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first, __is_vector](_Tp* __i, _Tp* __j) {
|
||||
__brick_move_destroy()(__i, __j, __first + (__i - __r), __is_vector);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -2689,7 +2725,7 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __firs
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
|
||||
bool
|
||||
__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
|
||||
/*is_parallel=*/std::false_type) noexcept
|
||||
{
|
||||
@ -2699,7 +2735,7 @@ __pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwa
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
|
||||
bool
|
||||
__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector __is_vector,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
|
||||
/*is_parallel=*/std::true_type)
|
||||
{
|
||||
if (__first2 >= __last2)
|
||||
@ -2761,7 +2797,7 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
|
||||
_SizeFunction __size_func, _SetOP __set_op, _IsVector __is_vector)
|
||||
{
|
||||
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
|
||||
|
||||
struct _SetRange
|
||||
{
|
||||
@ -2776,7 +2812,7 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
|
||||
const _DifferenceType __n1 = __last1 - __first1;
|
||||
const _DifferenceType __n2 = __last2 - __first2;
|
||||
|
||||
__par_backend::__buffer<_T> __buf(__size_func(__n1, __n2));
|
||||
__par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2));
|
||||
|
||||
return __internal::__except_handler([&__exec, __n1, __first1, __last1, __first2, __last2, __result, __is_vector,
|
||||
__comp, __size_func, __set_op, &__buf]() {
|
||||
@ -2784,8 +2820,9 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
|
||||
_DifferenceType __m{};
|
||||
auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan
|
||||
if (!__s.empty())
|
||||
__internal::__brick_move(__buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len),
|
||||
__result + __s.__pos, __is_vector);
|
||||
__brick_move_destroy()(__buffer + __s.__buf_pos,
|
||||
__buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos,
|
||||
__is_vector);
|
||||
};
|
||||
__par_backend::__parallel_strict_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0},
|
||||
@ -2971,6 +3008,17 @@ __brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forwar
|
||||
return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
template <typename _IsVector>
|
||||
struct __BrickCopyConstruct
|
||||
{
|
||||
template <typename _ForwardIterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result)
|
||||
{
|
||||
return __brick_uninitialized_copy(__first, __last, __result, _IsVector());
|
||||
}
|
||||
};
|
||||
|
||||
template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
|
||||
_OutputIterator
|
||||
__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
@ -3007,12 +3055,14 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forw
|
||||
if (__n1 + __n2 <= __set_algo_cut_off)
|
||||
return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
|
||||
return __internal::__parallel_set_union_op(
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
|
||||
return __parallel_set_union_op(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
|
||||
_T* __result,
|
||||
_Compare __comp) { return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); },
|
||||
_Tp* __result, _Compare __comp) {
|
||||
return __pstl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp,
|
||||
__BrickCopyConstruct<_IsVector>());
|
||||
},
|
||||
__is_vector);
|
||||
}
|
||||
|
||||
@ -3056,7 +3106,7 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
|
||||
_Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
|
||||
{
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
|
||||
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
|
||||
|
||||
const auto __n1 = __last1 - __first1;
|
||||
@ -3086,8 +3136,9 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
|
||||
std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, __comp,
|
||||
[](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _T* __result, _Compare __comp) {
|
||||
return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
|
||||
return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result,
|
||||
__comp);
|
||||
},
|
||||
__is_vector);
|
||||
}
|
||||
@ -3100,8 +3151,9 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, __comp,
|
||||
[](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _T* __result, _Compare __comp) {
|
||||
return std::set_intersection(__first2, __last2, __first1, __last1, __result, __comp);
|
||||
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
|
||||
return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result,
|
||||
__comp);
|
||||
},
|
||||
__is_vector);
|
||||
return __result;
|
||||
@ -3151,7 +3203,7 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
|
||||
_Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
|
||||
{
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
|
||||
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
|
||||
|
||||
const auto __n1 = __last1 - __first1;
|
||||
@ -3193,13 +3245,15 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
|
||||
std::true_type());
|
||||
|
||||
if (__n1 + __n2 > __set_algo_cut_off)
|
||||
return __internal::__parallel_set_op(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
|
||||
[](_DifferenceType __n, _DifferenceType __m) { return __n; },
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _T* __result,
|
||||
_Compare __comp) { return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); },
|
||||
__is_vector);
|
||||
return __parallel_set_op(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
|
||||
__comp, [](_DifferenceType __n, _DifferenceType) { return __n; },
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
|
||||
return __pstl::__utils::__set_difference_construct(
|
||||
__first1, __last1, __first2, __last2, __result, __comp,
|
||||
__BrickCopyConstruct<_IsVector>());
|
||||
},
|
||||
__is_vector);
|
||||
|
||||
// use serial algorithm
|
||||
return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
@ -3254,12 +3308,13 @@ __pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1
|
||||
if (__n1 + __n2 <= __set_algo_cut_off)
|
||||
return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
|
||||
return __internal::__parallel_set_union_op(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
|
||||
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
|
||||
_T* __result, _Compare __comp) {
|
||||
return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
|
||||
_Tp* __result, _Compare __comp) {
|
||||
return __pstl::__utils::__set_symmetric_difference_construct(__first1, __last1, __first2, __last2, __result,
|
||||
__comp, __BrickCopyConstruct<_IsVector>());
|
||||
},
|
||||
__is_vector);
|
||||
}
|
||||
@ -3443,14 +3498,14 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F
|
||||
std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, std::make_pair(__first, __first),
|
||||
[=](_ForwardIterator __begin, _ForwardIterator __end, _Result __init) -> _Result {
|
||||
const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, __is_vector);
|
||||
return std::make_pair(__internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
|
||||
__internal::__cmp_iterators_by_values(__init.second, __subresult.second,
|
||||
__not_pred<_Compare>(__comp)));
|
||||
return std::make_pair(
|
||||
__internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
|
||||
__internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp)));
|
||||
},
|
||||
[=](_Result __p1, _Result __p2) -> _Result {
|
||||
return std::make_pair(
|
||||
__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp),
|
||||
__internal::__cmp_iterators_by_values(__p2.second, __p1.second, __not_pred<_Compare>(__comp)));
|
||||
__internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp)));
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -3487,7 +3542,7 @@ __brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forward
|
||||
_ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::true_type) noexcept
|
||||
{
|
||||
auto __n = std::min(__last1 - __first1, __last2 - __first2);
|
||||
return __unseq_backend::__simd_first(__first1, __n, __first2, __not_pred<_Predicate>(__pred));
|
||||
return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate, class _IsVector>
|
||||
|
@ -28,7 +28,7 @@ template <typename _Tp>
|
||||
std::false_type __lazy_and(_Tp, std::false_type)
|
||||
{
|
||||
return std::false_type{};
|
||||
};
|
||||
}
|
||||
|
||||
template <typename _Tp>
|
||||
inline _Tp
|
||||
@ -41,7 +41,7 @@ template <typename _Tp>
|
||||
std::true_type __lazy_or(_Tp, std::true_type)
|
||||
{
|
||||
return std::true_type{};
|
||||
};
|
||||
}
|
||||
|
||||
template <typename _Tp>
|
||||
inline _Tp
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,29 +26,29 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
|
||||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel =
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_brick(
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
|
||||
return __internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
return __pstl::__internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,29 +60,28 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
|
||||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel =
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_brick_n(
|
||||
return __pstl::__internal::__pattern_walk2_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
|
||||
return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -96,29 +95,29 @@ uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
|
||||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel =
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_brick(
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
|
||||
return __internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
return __pstl::__internal::__pattern_walk2(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -130,29 +129,29 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
|
||||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel =
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_brick_n(
|
||||
return __pstl::__internal::__pattern_walk2_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
|
||||
return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2))
|
||||
_ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -164,28 +163,28 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
__internal::__invoke_if_else(std::is_arithmetic<_ValueType>(),
|
||||
[&]() {
|
||||
__internal::__pattern_walk_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last,
|
||||
[&__value](_ReferenceType __val) {
|
||||
::new (std::addressof(__val)) _ValueType(__value);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
__pstl::__internal::__invoke_if_else(
|
||||
std::is_arithmetic<_ValueType>(),
|
||||
[&]() {
|
||||
__pstl::__internal::__pattern_walk_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
|
||||
__is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
|
||||
@ -194,23 +193,24 @@ uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_arithmetic<_ValueType>(),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk_brick_n(
|
||||
return __pstl::__internal::__pattern_walk_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value, &__is_vector](_ForwardIterator __begin, _Size __count) {
|
||||
return __internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector);
|
||||
return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk1_n(
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
|
||||
__is_parallel);
|
||||
@ -225,14 +225,16 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
|
||||
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, __is_parallel);
|
||||
__pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
|
||||
__pstl::__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
|
||||
__is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -242,17 +244,18 @@ destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); },
|
||||
[&]() {
|
||||
return __internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
|
||||
__is_parallel);
|
||||
return __pstl::__internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
|
||||
__is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -264,15 +267,16 @@ uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __fi
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
|
||||
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector,
|
||||
__is_parallel);
|
||||
__pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
|
||||
__pstl::__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; },
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -282,18 +286,19 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
|
||||
[&]() {
|
||||
return __internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; },
|
||||
__is_vector, __is_parallel);
|
||||
});
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
|
||||
[&]() {
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
// [uninitialized.construct.value]
|
||||
@ -304,24 +309,26 @@ uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __firs
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
__internal::__invoke_if_else(
|
||||
__pstl::__internal::__invoke_if_else(
|
||||
std::is_trivial<_ValueType>(),
|
||||
[&]() {
|
||||
__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__pstl::__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(),
|
||||
__is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); },
|
||||
__is_vector, __is_parallel);
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel);
|
||||
});
|
||||
}
|
||||
|
||||
@ -331,23 +338,24 @@ uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __fi
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
using namespace __pstl;
|
||||
|
||||
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
|
||||
return __internal::__invoke_if_else(
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_trivial<_ValueType>(),
|
||||
[&]() {
|
||||
return __internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[__is_vector](_ForwardIterator __begin, _Size __count) {
|
||||
return __internal::__brick_fill_n(__begin, __count,
|
||||
_ValueType(), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
return __pstl::__internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[__is_vector](_ForwardIterator __begin, _Size __count) {
|
||||
return __pstl::__internal::__brick_fill_n(
|
||||
__begin, __count, _ValueType(), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
},
|
||||
[&]() {
|
||||
return __internal::__pattern_walk1_n(
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel);
|
||||
});
|
||||
|
@ -55,12 +55,13 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forward
|
||||
_ForwardIterator2 __first2, _Tp __init)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_reduce(
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, std::plus<_InputType>(),
|
||||
std::multiplies<_InputType>(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
|
||||
@ -69,11 +70,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
|
||||
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
|
||||
{
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_reduce(
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2,
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
|
||||
@ -81,11 +83,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
|
||||
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
|
||||
_BinaryOperation __binary_op, _UnaryOperation __unary_op)
|
||||
{
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_reduce(
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op,
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
}
|
||||
|
||||
// [exclusive.scan]
|
||||
@ -95,8 +96,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
|
||||
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
|
||||
_ForwardIterator2 __result, _Tp __init)
|
||||
{
|
||||
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
|
||||
std::plus<_Tp>(), __pstl::__internal::__no_op());
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
|
||||
std::plus<_Tp>(), /*inclusive=*/std::false_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
|
||||
@ -104,8 +109,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
|
||||
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
|
||||
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op)
|
||||
{
|
||||
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
|
||||
__binary_op, __pstl::__internal::__no_op());
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
|
||||
__binary_op, /*inclusive=*/std::false_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
}
|
||||
|
||||
// [inclusive.scan]
|
||||
@ -147,12 +156,13 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
|
||||
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op,
|
||||
_UnaryOperation __unary_op)
|
||||
{
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
return __pstl::__internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::false_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
}
|
||||
|
||||
// [transform.inclusive.scan]
|
||||
@ -164,12 +174,13 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
|
||||
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op,
|
||||
_Tp __init)
|
||||
{
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
return __pstl::__internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::true_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation,
|
||||
@ -202,11 +213,12 @@ adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Forwa
|
||||
if (__first == __last)
|
||||
return __d_first;
|
||||
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_adjacent_difference(
|
||||
return __pstl::__internal::__pattern_adjacent_difference(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op,
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||
|
@ -23,31 +23,82 @@ namespace __internal
|
||||
// uninitialized_move
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
template <class _ForwardIterator, class _OutputIterator>
|
||||
template <typename _ForwardIterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
|
||||
/*vector=*/std::false_type) noexcept
|
||||
{
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType2;
|
||||
using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
for (; __first != __last; ++__first, ++__result)
|
||||
{
|
||||
::new (std::addressof(*__result)) _ValueType2(std::move(*__first));
|
||||
::new (std::addressof(*__result)) _ValueType(std::move(*__first));
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _OutputIterator>
|
||||
template <typename _ForwardIterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
|
||||
/*vector=*/std::true_type) noexcept
|
||||
{
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type __ValueType2;
|
||||
typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType1;
|
||||
typedef typename std::iterator_traits<_OutputIterator>::reference _ReferenceType2;
|
||||
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
|
||||
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
|
||||
|
||||
return __unseq_backend::__simd_walk_2(
|
||||
__first, __last - __first, __result,
|
||||
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType2(std::move(__x)); });
|
||||
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(std::move(__x)); });
|
||||
}
|
||||
|
||||
template <typename _Iterator>
|
||||
void
|
||||
__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept
|
||||
{
|
||||
using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
|
||||
|
||||
for (; __first != __last; ++__first)
|
||||
__first->~_ValueType();
|
||||
}
|
||||
|
||||
template <typename _Iterator>
|
||||
void
|
||||
__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::true_type) noexcept
|
||||
{
|
||||
using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
|
||||
using _ReferenceType = typename std::iterator_traits<_Iterator>::reference;
|
||||
|
||||
__unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); });
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// uninitialized copy
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
template <typename _ForwardIterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
|
||||
/*vector=*/std::false_type) noexcept
|
||||
{
|
||||
using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
for (; __first != __last; ++__first, ++__result)
|
||||
{
|
||||
::new (std::addressof(*__result)) _ValueType(*__first);
|
||||
}
|
||||
return __result;
|
||||
}
|
||||
|
||||
template <typename _ForwardIterator, typename _OutputIterator>
|
||||
_OutputIterator
|
||||
__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
|
||||
/*vector=*/std::true_type) noexcept
|
||||
{
|
||||
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
|
||||
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
|
||||
|
||||
return __unseq_backend::__simd_walk_2(
|
||||
__first, __last - __first, __result,
|
||||
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(__x); });
|
||||
}
|
||||
|
||||
} // namespace __internal
|
||||
|
@ -93,11 +93,7 @@ _Tp
|
||||
__brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op,
|
||||
_UnaryOperation __unary_op, /*is_vector=*/std::false_type) noexcept
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
__init = __binary_op(__init, __unary_op(*__first));
|
||||
}
|
||||
return __init;
|
||||
return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op);
|
||||
}
|
||||
|
||||
template <class _ForwardIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
|
||||
@ -284,7 +280,7 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
|
||||
}) -
|
||||
1);
|
||||
},
|
||||
[](_Tp __res) {});
|
||||
[](_Tp) {});
|
||||
return __result + (__last - __first);
|
||||
});
|
||||
}
|
||||
|
@ -12,8 +12,16 @@
|
||||
|
||||
#if defined(_PSTL_PAR_BACKEND_SERIAL)
|
||||
# include "parallel_backend_serial.h"
|
||||
namespace __pstl
|
||||
{
|
||||
namespace __par_backend = __serial_backend;
|
||||
}
|
||||
#elif defined(_PSTL_PAR_BACKEND_TBB)
|
||||
# include "parallel_backend_tbb.h"
|
||||
namespace __pstl
|
||||
{
|
||||
namespace __par_backend = __tbb_backend;
|
||||
}
|
||||
#else
|
||||
_PSTL_PRAGMA_MESSAGE("Parallel backend was not specified");
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
namespace __pstl
|
||||
{
|
||||
namespace __serial
|
||||
namespace __serial_backend
|
||||
{
|
||||
|
||||
template <typename _Tp>
|
||||
@ -110,10 +110,10 @@ template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _Ran
|
||||
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
|
||||
void
|
||||
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __out,
|
||||
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit,
|
||||
_Compare __comp, _LeafMerge __leaf_merge)
|
||||
{
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __out, __comp);
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, typename _F1, typename _F2>
|
||||
@ -124,7 +124,7 @@ __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
|
||||
std::forward<_F2>(__f2)();
|
||||
}
|
||||
|
||||
} // namespace __serial
|
||||
} // namespace __serial_backend
|
||||
} // namespace __pstl
|
||||
|
||||
namespace __pstl
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,7 +16,8 @@
|
||||
|
||||
namespace __pstl
|
||||
{
|
||||
namespace __par_backend
|
||||
|
||||
namespace __utils
|
||||
{
|
||||
|
||||
//! Destroy sequence [xs,xe)
|
||||
@ -36,24 +37,28 @@ struct __serial_destroy
|
||||
};
|
||||
|
||||
//! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
|
||||
template <class _MoveValues, class _MoveSequences>
|
||||
struct __serial_move_merge
|
||||
{
|
||||
const std::size_t _M_nmerge;
|
||||
_MoveValues _M_move_values;
|
||||
_MoveSequences _M_move_sequences;
|
||||
|
||||
explicit __serial_move_merge(std::size_t __nmerge, _MoveValues __move_values, _MoveSequences __move_sequences)
|
||||
: _M_nmerge(__nmerge), _M_move_values(__move_values), _M_move_sequences(__move_sequences)
|
||||
{
|
||||
}
|
||||
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
|
||||
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)
|
||||
_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)
|
||||
@ -62,7 +67,11 @@ struct __serial_move_merge
|
||||
{
|
||||
if (__comp(*__ys, *__xs))
|
||||
{
|
||||
_M_move_values(__ys, __zs);
|
||||
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)
|
||||
{
|
||||
@ -70,126 +79,179 @@ struct __serial_move_merge
|
||||
}
|
||||
else if (__n == 0)
|
||||
{
|
||||
__zs = _M_move_sequences(__ys, __ye, __zs);
|
||||
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
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_M_move_values(__xs, __zs);
|
||||
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)
|
||||
{
|
||||
_M_move_sequences(__ys, __ye, __zs);
|
||||
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)
|
||||
{
|
||||
__zs = _M_move_sequences(__xs, __xe, __zs);
|
||||
_M_move_sequences(__ys, __ye, __zs);
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
__ys = __xs;
|
||||
__ye = __xe;
|
||||
}
|
||||
_M_move_sequences(__ys, __ye, __zs);
|
||||
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 _RandomAccessIterator1, typename _OutputIterator>
|
||||
void
|
||||
__init_buf(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _OutputIterator __zs, bool __bMove)
|
||||
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)
|
||||
{
|
||||
const _OutputIterator __ze = __zs + (__xe - __xs);
|
||||
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType;
|
||||
if (__bMove)
|
||||
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
|
||||
for (; __first1 != __last1; ++__result)
|
||||
{
|
||||
// Initialize the temporary buffer and move keys to it.
|
||||
for (; __zs != __ze; ++__xs, ++__zs)
|
||||
new (&*__zs) _ValueType(std::move(*__xs));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize the temporary buffer
|
||||
for (; __zs != __ze; ++__zs)
|
||||
new (&*__zs) _ValueType;
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO is this actually used anywhere?
|
||||
template <typename _Buf>
|
||||
class __stack
|
||||
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)
|
||||
{
|
||||
typedef typename std::iterator_traits<decltype(_Buf(0).get())>::value_type _ValueType;
|
||||
typedef typename std::iterator_traits<_ValueType*>::difference_type _DifferenceType;
|
||||
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
|
||||
|
||||
_Buf _M_buf;
|
||||
_ValueType* _M_ptr;
|
||||
_DifferenceType _M_maxsize;
|
||||
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;
|
||||
}
|
||||
|
||||
__stack(const __stack&) = delete;
|
||||
void
|
||||
operator=(const __stack&) = delete;
|
||||
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;
|
||||
|
||||
public:
|
||||
__stack(_DifferenceType __max_size) : _M_buf(__max_size), _M_maxsize(__max_size) { _M_ptr = _M_buf.get(); }
|
||||
for (; __first1 != __last1;)
|
||||
{
|
||||
if (__first2 == __last2)
|
||||
return __cc_range(__first1, __last1, __result);
|
||||
|
||||
~__stack()
|
||||
{
|
||||
_PSTL_ASSERT(size() <= _M_maxsize);
|
||||
while (!empty())
|
||||
pop();
|
||||
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;
|
||||
|
||||
const _Buf&
|
||||
buffer() const
|
||||
for (; __first1 != __last1;)
|
||||
{
|
||||
return _M_buf;
|
||||
}
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
_PSTL_ASSERT(_M_ptr - _M_buf.get() <= _M_maxsize);
|
||||
_PSTL_ASSERT(_M_ptr - _M_buf.get() >= 0);
|
||||
return _M_ptr - _M_buf.get();
|
||||
}
|
||||
bool
|
||||
empty() const
|
||||
{
|
||||
_PSTL_ASSERT(_M_ptr >= _M_buf.get());
|
||||
return _M_ptr == _M_buf.get();
|
||||
}
|
||||
void
|
||||
push(const _ValueType& __v)
|
||||
{
|
||||
_PSTL_ASSERT(size() < _M_maxsize);
|
||||
new (_M_ptr) _ValueType(__v);
|
||||
++_M_ptr;
|
||||
}
|
||||
const _ValueType&
|
||||
top() const
|
||||
{
|
||||
return *(_M_ptr - 1);
|
||||
}
|
||||
void
|
||||
pop()
|
||||
{
|
||||
_PSTL_ASSERT(_M_ptr > _M_buf.get());
|
||||
--_M_ptr;
|
||||
(*_M_ptr).~_ValueType();
|
||||
}
|
||||
};
|
||||
if (__first2 == __last2)
|
||||
return __cc_range(__first1, __last1, __result);
|
||||
|
||||
} // namespace __par_backend
|
||||
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 */
|
||||
|
@ -11,13 +11,13 @@
|
||||
#define _PSTL_CONFIG_H
|
||||
|
||||
// The version is XYYZ, where X is major, YY is minor, and Z is patch (i.e. X.YY.Z)
|
||||
#define _PSTL_VERSION 9000
|
||||
#define _PSTL_VERSION 12000
|
||||
#define _PSTL_VERSION_MAJOR (_PSTL_VERSION / 1000)
|
||||
#define _PSTL_VERSION_MINOR ((_PSTL_VERSION % 1000) / 10)
|
||||
#define _PSTL_VERSION_PATCH (_PSTL_VERSION % 10)
|
||||
|
||||
#if !defined(_PSTL_PAR_BACKEND_SERIAL) && !defined(_PSTL_PAR_BACKEND_TBB)
|
||||
# error "The parallel backend is neither serial nor TBB"
|
||||
# error "A parallel backend must be specified"
|
||||
#endif
|
||||
|
||||
// Check the user-defined macro for warnings
|
||||
@ -40,6 +40,15 @@
|
||||
#define _PSTL_STRING(x) _PSTL_STRING_AUX(x)
|
||||
#define _PSTL_STRING_CONCAT(x, y) x #y
|
||||
|
||||
#ifdef _PSTL_HIDE_FROM_ABI_PER_TU
|
||||
# define _PSTL_HIDE_FROM_ABI_PUSH \
|
||||
_Pragma("clang attribute push(__attribute__((internal_linkage)), apply_to=any(function,record))")
|
||||
# define _PSTL_HIDE_FROM_ABI_POP _Pragma("clang attribute pop")
|
||||
#else
|
||||
# define _PSTL_HIDE_FROM_ABI_PUSH /* nothing */
|
||||
# define _PSTL_HIDE_FROM_ABI_POP /* nothing */
|
||||
#endif
|
||||
|
||||
// note that when ICC or Clang is in use, _PSTL_GCC_VERSION might not fully match
|
||||
// the actual GCC version on the system.
|
||||
#define _PSTL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
@ -50,7 +59,8 @@
|
||||
#endif
|
||||
|
||||
// Enable SIMD for compilers that support OpenMP 4.0
|
||||
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900)
|
||||
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \
|
||||
defined(__clang__)
|
||||
# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd)
|
||||
# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd)
|
||||
# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM))
|
||||
@ -70,7 +80,7 @@
|
||||
# define _PSTL_PRAGMA_FORCEINLINE
|
||||
#endif
|
||||
|
||||
#if (__INTEL_COMPILER >= 1900) || (_PSTL_GCC_VERSION >= 100000)
|
||||
#if (__INTEL_COMPILER >= 1900)
|
||||
# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM))
|
||||
# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM))
|
||||
# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM))
|
||||
@ -100,11 +110,7 @@
|
||||
# define _PSTL_UDR_PRESENT 0
|
||||
#endif
|
||||
|
||||
#if ((__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626) || _PSTL_GCC_VERSION >= 100000)
|
||||
# define _PSTL_UDS_PRESENT 1
|
||||
#else
|
||||
# define _PSTL_UDS_PRESENT 0
|
||||
#endif
|
||||
#define _PSTL_UDS_PRESENT (__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626)
|
||||
|
||||
#if _PSTL_EARLYEXIT_PRESENT
|
||||
# define _PSTL_PRAGMA_SIMD_EARLYEXIT _PSTL_PRAGMA(omp simd early_exit)
|
||||
|
@ -181,7 +181,7 @@ __simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pr
|
||||
_DifferenceType __i;
|
||||
_PSTL_PRAGMA_VECTOR_UNALIGNED // Do not generate peel loop part
|
||||
_PSTL_PRAGMA_SIMD_REDUCTION(|
|
||||
: __found) for (__i = 0; __i < __block_size; ++__i)
|
||||
: __found) for (__i = 0; __i < __block_size; ++__i)
|
||||
{
|
||||
const _DifferenceType __t = __pred(__first1[__i], __first2[__i]);
|
||||
__lane[__i] = __t;
|
||||
@ -189,14 +189,14 @@ __simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pr
|
||||
}
|
||||
if (__found)
|
||||
{
|
||||
_DifferenceType __i;
|
||||
_DifferenceType __i2;
|
||||
// This will vectorize
|
||||
for (__i = 0; __i < __block_size; ++__i)
|
||||
for (__i2 = 0; __i2 < __block_size; ++__i2)
|
||||
{
|
||||
if (__lane[__i])
|
||||
if (__lane[__i2])
|
||||
break;
|
||||
}
|
||||
return std::make_pair(__first1 + __i, __first2 + __i);
|
||||
return std::make_pair(__first1 + __i2, __first2 + __i2);
|
||||
}
|
||||
__first1 += __block_size;
|
||||
__first2 += __block_size;
|
||||
@ -403,7 +403,7 @@ __simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, boo
|
||||
_DifferenceType __found = 0;
|
||||
_PSTL_PRAGMA_VECTOR_UNALIGNED // Do not generate peel loop part
|
||||
_PSTL_PRAGMA_SIMD_REDUCTION(|
|
||||
: __found) for (__i = 0; __i < __block_size - 1; ++__i)
|
||||
: __found) for (__i = 0; __i < __block_size - 1; ++__i)
|
||||
{
|
||||
//TODO: to improve SIMD vectorization
|
||||
const _DifferenceType __t = __pred(*(__first + __i), *(__first + __i + 1));
|
||||
@ -486,15 +486,15 @@ __simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _Un
|
||||
__lane[__j] = __binary_op(__lane[__j], __f(last_iteration + __j));
|
||||
}
|
||||
// combiner
|
||||
for (_Size __i = 0; __i < __block_size; ++__i)
|
||||
for (_Size __j = 0; __j < __block_size; ++__j)
|
||||
{
|
||||
__init = __binary_op(__init, __lane[__i]);
|
||||
__init = __binary_op(__init, __lane[__j]);
|
||||
}
|
||||
// destroyer
|
||||
_PSTL_PRAGMA_SIMD
|
||||
for (_Size __i = 0; __i < __block_size; ++__i)
|
||||
for (_Size __j = 0; __j < __block_size; ++__j)
|
||||
{
|
||||
__lane[__i].~_Tp();
|
||||
__lane[__j].~_Tp();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -796,8 +796,9 @@ __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forwa
|
||||
{
|
||||
for (; __first != __last; ++__first)
|
||||
{
|
||||
if (__unseq_backend::__simd_or(__s_first, __n2,
|
||||
__internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
|
||||
if (__unseq_backend::__simd_or(
|
||||
__s_first, __n2,
|
||||
__internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
|
||||
{
|
||||
return __first;
|
||||
}
|
||||
@ -807,10 +808,10 @@ __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forwa
|
||||
{
|
||||
for (; __s_first != __s_last; ++__s_first)
|
||||
{
|
||||
const auto __result = __unseq_backend::__simd_first(__first, _DifferencType(0), __n1,
|
||||
[__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
|
||||
return __pred(__it[__i], *__s_first);
|
||||
});
|
||||
const auto __result = __unseq_backend::__simd_first(
|
||||
__first, _DifferencType(0), __n1, [__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
|
||||
return __pred(__it[__i], *__s_first);
|
||||
});
|
||||
if (__result != __last)
|
||||
{
|
||||
return __result;
|
||||
@ -825,9 +826,9 @@ _RandomAccessIterator
|
||||
__simd_remove_if(_RandomAccessIterator __first, _DifferenceType __n, _UnaryPredicate __pred) noexcept
|
||||
{
|
||||
// find first element we need to remove
|
||||
auto __current =
|
||||
__unseq_backend::__simd_first(__first, _DifferenceType(0), __n,
|
||||
[&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
|
||||
auto __current = __unseq_backend::__simd_first(
|
||||
__first, _DifferenceType(0), __n,
|
||||
[&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
|
||||
__n -= __current - __first;
|
||||
|
||||
// if we have in sequence only one element that pred(__current[1]) != false we can exit the function
|
||||
|
Loading…
x
Reference in New Issue
Block a user