[pstl] Qualify calls to internal functions

This guards against unintended ADL issues.
Thanks to Thomas Rogers for the patch.

Differential Revision: https://reviews.llvm.org/D60009

llvm-svn: 357306
This commit is contained in:
Louis Dionne 2019-03-29 20:11:24 +00:00
parent 347a45ccd5
commit c7c6413119
8 changed files with 460 additions and 441 deletions

File diff suppressed because it is too large Load Diff

View File

@ -123,27 +123,27 @@ struct is_execution_policy : std::false_type
};
template <>
struct is_execution_policy<sequenced_policy> : std::true_type
struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type
{
};
#if __PSTL_USE_PAR_POLICIES
template <>
struct is_execution_policy<parallel_policy> : std::true_type
struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type
{
};
template <>
struct is_execution_policy<parallel_unsequenced_policy> : std::true_type
struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type
{
};
#endif
template <>
struct is_execution_policy<unsequenced_policy> : std::true_type
struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type
{
};
#if __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
template <class T>
constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
constexpr bool is_execution_policy_v = __pstl::execution::is_execution_policy<T>::value;
#endif
} // namespace v1

View File

@ -54,8 +54,8 @@ __lazy_or(_Tp __a, std::false_type)
template <typename _IteratorType, typename... _OtherIteratorTypes>
struct __is_random_access_iterator
{
static constexpr bool value =
__is_random_access_iterator<_IteratorType>::value && __is_random_access_iterator<_OtherIteratorTypes...>::value;
static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value &&
__internal::__is_random_access_iterator<_OtherIteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
@ -106,46 +106,54 @@ struct __policy_traits<parallel_unsequenced_policy>
#endif
template <typename _ExecutionPolicy>
using __collector_t = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
using __collector_t =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
template <typename _ExecutionPolicy>
using __allow_vector = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
using __allow_vector =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
template <typename _ExecutionPolicy>
using __allow_unsequenced = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
using __allow_unsequenced =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
template <typename _ExecutionPolicy>
using __allow_parallel = typename __policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
using __allow_parallel =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
template <typename _ExecutionPolicy, typename... _IteratorTypes>
auto
__is_vectorization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__lazy_and(__exec.__allow_vector(), typename __is_random_access_iterator<_IteratorTypes...>::type()))
-> decltype(__internal::__lazy_and(__exec.__allow_vector(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
{
return __lazy_and(__exec.__allow_vector(), typename __is_random_access_iterator<_IteratorTypes...>::type());
return __internal::__lazy_and(__exec.__allow_vector(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename _ExecutionPolicy, typename... _IteratorTypes>
auto
__is_parallelization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__lazy_and(__exec.__allow_parallel(), typename __is_random_access_iterator<_IteratorTypes...>::type()))
-> decltype(__internal::__lazy_and(__exec.__allow_parallel(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
{
return __lazy_and(__exec.__allow_parallel(), typename __is_random_access_iterator<_IteratorTypes...>::type());
return __internal::__lazy_and(__exec.__allow_parallel(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename policy, typename... _IteratorTypes>
struct __prefer_unsequenced_tag
{
static constexpr bool value =
__allow_unsequenced<policy>::value && __is_random_access_iterator<_IteratorTypes...>::value;
static constexpr bool value = __internal::__allow_unsequenced<policy>::value &&
__internal::__is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
template <typename policy, typename... _IteratorTypes>
struct __prefer_parallel_tag
{
static constexpr bool value =
__allow_parallel<policy>::value && __is_random_access_iterator<_IteratorTypes...>::value;
static constexpr bool value = __internal::__allow_parallel<policy>::value &&
__internal::__is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};

View File

@ -358,16 +358,15 @@ replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator
{
using namespace __pstl;
typedef typename iterator_traits<_ForwardIterator>::reference _ElementType;
__internal::__pattern_walk1(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__pred, &__new_value](_ElementType __elem) {
if (__pred(__elem))
{
__elem = __new_value;
}
},
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__pred, &__new_value](_ElementType __elem) {
if (__pred(__elem))
{
__elem = __new_value;
}
},
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>

View File

@ -44,12 +44,11 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
__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 __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(__val1);
},
__is_vector, __is_parallel);
});
}
@ -79,12 +78,11 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
__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 __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);
});
}
@ -116,12 +114,11 @@ uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
__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 __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);
});
}
@ -151,12 +148,11 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
__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 __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);
});
}
@ -173,22 +169,23 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __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);
});
__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);
});
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
@ -234,9 +231,8 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __
const auto __is_vector = __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);
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, __is_parallel);
});
}
@ -254,9 +250,9 @@ destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
return __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 __internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
__is_parallel);
});
}
@ -274,9 +270,9 @@ uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __fi
const auto __is_vector = __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);
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector,
__is_parallel);
});
}
@ -291,13 +287,13 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __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 __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);
});
}
// [uninitialized.construct.value]
@ -316,17 +312,16 @@ uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __firs
__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);
__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);
},
[&]() {
__internal::__pattern_walk1(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _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);
});
}
@ -344,12 +339,12 @@ uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __fi
return __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 __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 __internal::__pattern_walk1_n(

View File

@ -71,7 +71,7 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f
_RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
return __except_handler([&]() {
return __internal::__except_handler([&]() {
return __par_backend::__parallel_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
[__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable {
@ -81,8 +81,8 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __f
__binary_op1, // Combine
[__first1, __first2, __binary_op1, __binary_op2,
__is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp {
return __brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, __binary_op1,
__binary_op2, __is_vector);
return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, __binary_op1,
__binary_op2, __is_vector);
});
});
}
@ -122,7 +122,7 @@ __pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator __first, _Forwar
_BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector,
/*is_parallel=*/std::false_type) noexcept
{
return __brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, __is_vector);
return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, __is_vector);
}
#if __PSTL_USE_PAR_POLICIES
@ -133,12 +133,12 @@ __pattern_transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first,
_BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector,
/*is_parallel=*/std::true_type)
{
return __except_handler([&]() {
return __internal::__except_handler([&]() {
return __par_backend::__parallel_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__unary_op](_ForwardIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op,
[__unary_op, __binary_op, __is_vector](_ForwardIterator __i, _ForwardIterator __j, _Tp __init) {
return __brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, __is_vector);
return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, __is_vector);
});
});
}
@ -201,8 +201,8 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu
_Inclusive());
#else
// We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive() value
return __brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
/*is_vector=*/std::false_type());
return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
/*is_vector=*/std::false_type());
#endif
}
@ -213,8 +213,8 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu
_UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive,
/*is_vector=*/std::true_type) noexcept
{
return __brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
/*is_vector=*/std::false_type());
return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
/*is_vector=*/std::false_type());
}
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
@ -224,7 +224,8 @@ __pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardI
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op,
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
return __brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), __is_vector)
return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
__is_vector)
.first;
}
@ -238,20 +239,21 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
{
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
return __except_handler([&]() {
return __internal::__except_handler([&]() {
__par_backend::__parallel_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __last - __first,
[__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init,
__binary_op,
[__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
// Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan.
return __brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op, __unary_op,
/*__is_vector*/ std::false_type());
return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op,
__unary_op,
/*__is_vector*/ std::false_type());
},
[__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __j,
_Tp __init) {
return __brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op, __init,
__binary_op, _Inclusive(), __is_vector)
return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
__init, __binary_op, _Inclusive(), __is_vector)
.second;
});
return __result + (__last - __first);
@ -274,12 +276,12 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
{
return __result;
}
return __except_handler([&]() {
return __internal::__except_handler([&]() {
__par_backend::parallel_strict_scan(
std::forward<_ExecutionPolicy>(__exec), __n, __init,
[__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __len) {
return __brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i, __unary_op, _Tp{},
__binary_op, _Inclusive(), __is_vector)
return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i,
__unary_op, _Tp{}, __binary_op, _Inclusive(), __is_vector)
.second;
},
__binary_op,
@ -333,7 +335,7 @@ __pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator __first, _For
_OutputIterator __d_first, _BinaryOperation __op, _IsVector __is_vector,
/*is_parallel*/ std::false_type) noexcept
{
return __brick_adjacent_difference(__first, __last, __d_first, __op, __is_vector);
return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, __is_vector);
}
#if __PSTL_USE_PAR_POLICIES
@ -353,7 +355,7 @@ __pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __fir
std::forward<_ExecutionPolicy>(__exec), __first, __last - 1,
[&__op, __is_vector, __d_first, __first](_ForwardIterator1 __b, _ForwardIterator1 __e) {
_ForwardIterator2 __d_b = __d_first + (__b - __first);
__brick_walk3(
__internal::__brick_walk3(
__b, __e, __b + 1, __d_b + 1,
[&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); },
__is_vector);

View File

@ -190,7 +190,7 @@ _Tp
__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _Up __u, _Tp __init, _Cp __combine,
_Rp __brick_reduce)
{
__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce);
__par_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce);
// The grain size of 3 is used in order to provide mininum 2 elements for each body
tbb::this_task_arena::isolate(
[__first, __last, &__body]() { tbb::parallel_reduce(tbb::blocked_range<_Index>(__first, __last, 3), __body); });
@ -304,8 +304,10 @@ __upsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsize
{
_Index __k = __split(__m);
tbb::parallel_invoke(
[=] { __upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
[=] { __upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine); });
[=] { __par_backend::__upsweep(__i, __k, __tilesize, __r, __tilesize, __reduce, __combine); },
[=] {
__par_backend::__upsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize, __reduce, __combine);
});
if (__m == 2 * __k)
__r[__m - 1] = __combine(__r[__k - 1], __r[__m - 1]);
}
@ -321,13 +323,14 @@ __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsi
else
{
const _Index __k = __split(__m);
tbb::parallel_invoke([=] { __downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
// Assumes that __combine never throws.
//TODO: Consider adding a requirement for user functors to be constant.
[=, &__combine] {
__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
__combine(__initial, __r[__k - 1]), __combine, __scan);
});
tbb::parallel_invoke(
[=] { __par_backend::__downsweep(__i, __k, __tilesize, __r, __tilesize, __initial, __combine, __scan); },
// Assumes that __combine never throws.
//TODO: Consider adding a requirement for user functors to be constant.
[=, &__combine] {
__par_backend::__downsweep(__i + __k, __m - __k, __tilesize, __r + __k, __lastsize,
__combine(__initial, __r[__k - 1]), __combine, __scan);
});
}
}
@ -358,7 +361,8 @@ parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce
_Index __m = (__n - 1) / __tilesize;
__buffer<_Tp> __buf(__m + 1);
_Tp* __r = __buf.get();
__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce, __combine);
__par_backend::__upsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __reduce,
__combine);
// When __apex is a no-op and __combine has no side effects, a good optimizer
// should be able to eliminate all code between here and __apex.
@ -369,8 +373,8 @@ parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce
while ((__k &= __k - 1))
__t = __combine(__r[__k - 1], __t);
__apex(__combine(__initial, __t));
__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial, __combine,
__scan);
__par_backend::__downsweep(_Index(0), _Index(__m + 1), __tilesize, __r, __n - __m * __tilesize, __initial,
__combine, __scan);
return;
}
// Fewer than 2 elements in sequence, or out of memory. Handle has single block.
@ -523,7 +527,7 @@ __stable_sort_task<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le
{
_M_leaf_sort(_M_xs, _M_xe, _M_comp);
if (_M_inplace != 2)
__init_buf(_M_xs, _M_xe, _M_zs, _M_inplace == 0);
__par_backend::__init_buf(_M_xs, _M_xe, _M_zs, _M_inplace == 0);
return NULL;
}
else
@ -536,20 +540,21 @@ __stable_sort_task<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le
auto __move_sequences = [](_RandomAccessIterator2 __first1, _RandomAccessIterator2 __last1,
_RandomAccessIterator1 __first2) { return std::move(__first1, __last1, __first2); };
if (_M_inplace == 2)
__m = new (allocate_continuation())
__m = new (tbb::task::allocate_continuation())
__merge_task<_RandomAccessIterator2, _RandomAccessIterator2, _RandomAccessIterator1, _Compare,
__serial_destroy,
__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
_M_zs, __zm, __zm, __ze, _M_xs, _M_comp, __serial_destroy(),
__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(__nmerge, __move_values,
__move_sequences));
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(
__nmerge, __move_values, __move_sequences));
else if (_M_inplace)
__m = new (allocate_continuation())
__m = new (tbb::task::allocate_continuation())
__merge_task<_RandomAccessIterator2, _RandomAccessIterator2, _RandomAccessIterator1, _Compare,
__binary_no_op, __serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
_M_zs, __zm, __zm, __ze, _M_xs, _M_comp, __binary_no_op(),
__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(__nmerge, __move_values,
__move_sequences));
__par_backend::__binary_no_op,
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
_M_zs, __zm, __zm, __ze, _M_xs, _M_comp, __par_backend::__binary_no_op(),
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(
__nmerge, __move_values, __move_sequences));
else
{
auto __move_values = [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = std::move(*__x); };
@ -557,18 +562,19 @@ __stable_sort_task<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le
_RandomAccessIterator2 __first2) {
return std::move(__first1, __last1, __first2);
};
__m = new (allocate_continuation())
__m = new (tbb::task::allocate_continuation())
__merge_task<_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Compare,
__binary_no_op, __serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
_M_xs, __xm, __xm, _M_xe, _M_zs, _M_comp, __binary_no_op(),
__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(__nmerge, __move_values,
__move_sequences));
__par_backend::__binary_no_op,
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>>(
_M_xs, __xm, __xm, _M_xe, _M_zs, _M_comp, __par_backend::__binary_no_op(),
__par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(
__nmerge, __move_values, __move_sequences));
}
__m->set_ref_count(2);
task* __right = new (__m->allocate_child())
__stable_sort_task(__xm, _M_xe, __zm, !_M_inplace, _M_comp, _M_leaf_sort, __nmerge);
spawn(*__right);
recycle_as_child_of(*__m);
tbb::task::spawn(*__right);
tbb::task::recycle_as_child_of(*__m);
_M_xe = __xm;
_M_inplace = !_M_inplace;
}
@ -629,10 +635,10 @@ __parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessI
{
tbb::this_task_arena::isolate([=]() {
typedef __merge_task<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, _Compare,
__binary_no_op, _LeafMerge>
__par_backend::__binary_no_op, _LeafMerge>
_TaskType;
tbb::task::spawn_root_and_wait(*new (tbb::task::allocate_root()) _TaskType(
__xs, __xe, __ys, __ye, __zs, __comp, __binary_no_op(), __leaf_merge));
__xs, __xe, __ys, __ye, __zs, __comp, __par_backend::__binary_no_op(), __leaf_merge));
});
}
}

View File

@ -796,8 +796,9 @@ __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forwa
{
for (; __first != __last; ++__first)
{
if (__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 = __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 =
__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