[libc++][pstl] Implement tag dispatching mechanism for Parallel STL

Implement the mechanism that simplifies the execution policy/iterator
category dispatching and allows to implement customizations for
the parallel algorithms with adding custom tags

Reviewed By: rodgert, MikeDvorskiy

Differential Revision: https://reviews.llvm.org/D104492
This commit is contained in:
Ruslan Arutyunyan 2022-01-28 03:54:27 +03:00
parent 912f1c8ce3
commit 843c12d6a0
23 changed files with 2253 additions and 2356 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,88 +26,20 @@ inline namespace v1
// 2.4, Sequential execution policy // 2.4, Sequential execution policy
class sequenced_policy class sequenced_policy
{ {
public:
// For internal use only
static constexpr std::false_type
__allow_unsequenced()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
}; };
// 2.5, Parallel execution policy // 2.5, Parallel execution policy
class parallel_policy class parallel_policy
{ {
public:
// For internal use only
static constexpr std::false_type
__allow_unsequenced()
{
return std::false_type{};
}
static constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
static constexpr std::true_type
__allow_parallel()
{
return std::true_type{};
}
}; };
// 2.6, Parallel+Vector execution policy // 2.6, Parallel+Vector execution policy
class parallel_unsequenced_policy class parallel_unsequenced_policy
{ {
public:
// For internal use only
static constexpr std::true_type
__allow_unsequenced()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_vector()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_parallel()
{
return std::true_type{};
}
}; };
class unsequenced_policy class unsequenced_policy
{ {
public:
// For internal use only
static constexpr std::true_type
__allow_unsequenced()
{
return std::true_type{};
}
static constexpr std::true_type
__allow_vector()
{
return std::true_type{};
}
static constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
}; };
// 2.8, Execution policy objects // 2.8, Execution policy objects
@ -153,6 +85,12 @@ template <class ExecPolicy, class T>
using __enable_if_execution_policy = using __enable_if_execution_policy =
typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<ExecPolicy>::type>::value, typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<ExecPolicy>::type>::value,
T>::type; T>::type;
template <class _IsVector>
struct __serial_tag;
template <class _IsVector>
struct __parallel_tag;
} // namespace __internal } // namespace __internal
} // namespace __pstl } // namespace __pstl

View File

@ -23,76 +23,76 @@ namespace __pstl
namespace __internal namespace __internal
{ {
using namespace __pstl::execution; template <typename _IteratorTag, typename... _IteratorTypes>
using __are_iterators_of = std::conjunction<
std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t<_IteratorTypes>>::iterator_category>...>;
template <typename _IteratorType> template <typename... _IteratorTypes>
struct __is_random_access_iterator using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
: std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category,
std::random_access_iterator_tag> struct __serial_backend_tag
{
};
struct __tbb_backend_tag
{
};
struct __openmp_backend_tag
{ {
}; };
template <typename Policy> #if defined(_PSTL_PAR_BACKEND_TBB)
struct __policy_traits using __par_backend_tag = __tbb_backend_tag;
#elif defined(_PSTL_PAR_BACKEND_OPENMP)
using __par_backend_tag = __openmp_backend_tag;
#elif defined(_PSTL_PAR_BACKEND_SERIAL)
using __par_backend_tag = __serial_backend_tag;
#else
# error "A parallel backend must be specified";
#endif
template <class _IsVector>
struct __serial_tag
{ {
using __is_vector = _IsVector;
}; };
template <> template <class _IsVector>
struct __policy_traits<sequenced_policy> struct __parallel_tag
{ {
typedef std::false_type __allow_parallel; using __is_vector = _IsVector;
typedef std::false_type __allow_unsequenced; // backend tag can be change depending on
typedef std::false_type __allow_vector; // TBB availability in the environment
using __backend_tag = __par_backend_tag;
}; };
template <> template <class _IsVector, class... _IteratorTypes>
struct __policy_traits<unsequenced_policy> using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
{ __parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type;
typedef std::false_type __allow_parallel;
typedef std::true_type __allow_unsequenced;
typedef std::true_type __allow_vector;
};
template <> template <class... _IteratorTypes>
struct __policy_traits<parallel_policy> __serial_tag</*_IsVector = */ std::false_type>
{ __select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
typedef std::true_type __allow_parallel;
typedef std::false_type __allow_unsequenced;
typedef std::false_type __allow_vector;
};
template <>
struct __policy_traits<parallel_unsequenced_policy>
{
typedef std::true_type __allow_parallel;
typedef std::true_type __allow_unsequenced;
typedef std::true_type __allow_vector;
};
template <typename _ExecutionPolicy>
using __allow_vector =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector;
template <typename _ExecutionPolicy>
using __allow_unsequenced =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
template <typename _ExecutionPolicy>
using __allow_parallel =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
template <typename _ExecutionPolicy, typename... _IteratorTypes>
typename std::conjunction<__allow_vector<_ExecutionPolicy>,
__is_random_access_iterator<_IteratorTypes>...>::type
__is_vectorization_preferred(_ExecutionPolicy&&)
{ {
return {}; return {};
} }
template <typename _ExecutionPolicy, typename... _IteratorTypes> template <class... _IteratorTypes>
typename std::conjunction<__allow_parallel<_ExecutionPolicy>, __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
__is_random_access_iterator<_IteratorTypes>...>::type __select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
__is_parallelization_preferred(_ExecutionPolicy&&) {
return {};
}
template <class... _IteratorTypes>
__tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...)
{
return {};
}
template <class... _IteratorTypes>
__tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
{ {
return {}; return {};
} }

View File

@ -32,10 +32,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{ {
return __pstl::__internal::__pattern_any_of( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_any_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __pred);
} }
// [alg.all_of] // [alg.all_of]
@ -62,20 +62,19 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Function>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f)
{ {
__pstl::__internal::__pattern_walk1( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __f,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __f);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function> template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f) for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f)
{ {
return __pstl::__internal::__pattern_walk1_n( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __n, __f,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __f);
} }
// [alg.find] // [alg.find]
@ -84,10 +83,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{ {
return __pstl::__internal::__pattern_find_if( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_find_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __last, __pred);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
@ -111,12 +110,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
_ForwardIterator2 __s_last, _BinaryPredicate __pred) _ForwardIterator2 __s_last, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_find_end( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_find_end(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __last, __s_first, __s_last, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -134,12 +131,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_find_first_of( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_find_first_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __last, __s_first, __s_last, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -156,23 +151,20 @@ template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
return __pstl::__internal::__pattern_adjacent_find( return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<_ValueType>(), __last, std::equal_to<_ValueType>(), /*first_semantic*/ false);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
/*first_semantic*/ false);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_adjacent_find( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __last, __pred, /*first_semantic*/ false);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
/*first_semantic*/ false);
} }
// [alg.count] // [alg.count]
@ -185,12 +177,11 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
typename iterator_traits<_ForwardIterator>::difference_type> typename iterator_traits<_ForwardIterator>::difference_type>
count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
return __pstl::__internal::__pattern_count( return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](const _ValueType& __x) { return __value == __x; });
[&__value](const _ValueType& __x) { return __value == __x; },
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
@ -198,10 +189,9 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
typename iterator_traits<_ForwardIterator>::difference_type> typename iterator_traits<_ForwardIterator>::difference_type>
count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{ {
return __pstl::__internal::__pattern_count( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __pred);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
// [alg.search] // [alg.search]
@ -211,12 +201,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
_ForwardIterator2 __s_last, _BinaryPredicate __pred) _ForwardIterator2 __s_last, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_search( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_search(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__exec), __s_first, __s_last, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -232,10 +220,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count,
const _Tp& __value, _BinaryPredicate __pred) const _Tp& __value, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_search_n( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_search_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __last, __count, __value, __pred);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
@ -253,34 +241,28 @@ template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterato
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result)
{ {
const auto __is_vector = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec); using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
return __pstl::__internal::__pattern_walk2_brick( return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res)
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector); { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
},
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result) copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result)
{ {
const auto __is_vector = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec); using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
return __pstl::__internal::__pattern_walk2_brick_n( return __pstl::__internal::__pattern_walk2_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[__is_vector](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) { [](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res)
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector); { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
},
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
@ -288,12 +270,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
_Predicate __pred) _Predicate __pred)
{ {
return __pstl::__internal::__pattern_copy_if( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_copy_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __last, __result, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
// [alg.swap] // [alg.swap]
@ -305,16 +285,16 @@ swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardItera
{ {
typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
return __pstl::__internal::__pattern_walk2(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
[](_ReferenceType1 __x, _ReferenceType2 __y) {
using std::swap; return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
swap(__x, __y); __last1, __first2,
}, [](_ReferenceType1 __x, _ReferenceType2 __y)
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( {
__exec), using std::swap;
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( swap(__x, __y);
__exec)); });
} }
// [alg.transform] // [alg.transform]
@ -326,13 +306,12 @@ transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator
{ {
typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; typedef typename iterator_traits<_ForwardIterator1>::reference _InputType;
typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType;
return __pstl::__internal::__pattern_walk2(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
[__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); },
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__exec), __result,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( [__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); });
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
@ -344,13 +323,12 @@ transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterato
typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type; typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type;
typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type; typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type;
typedef typename iterator_traits<_ForwardIterator>::reference _OutputType; typedef typename iterator_traits<_ForwardIterator>::reference _OutputType;
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
return __pstl::__internal::__pattern_walk3( return __pstl::__internal::__pattern_walk3(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result,
[__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); }, [__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); });
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
// [alg.replace] // [alg.replace]
@ -361,16 +339,17 @@ replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator
const _Tp& __new_value) const _Tp& __new_value)
{ {
typedef typename iterator_traits<_ForwardIterator>::reference _ElementType; typedef typename iterator_traits<_ForwardIterator>::reference _ElementType;
__pstl::__internal::__pattern_walk1(
std::forward<_ExecutionPolicy>(__exec), __first, __last, auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
[&__pred, &__new_value](_ElementType __elem) {
if (__pred(__elem)) __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
{ [&__pred, &__new_value](_ElementType __elem)
__elem = __new_value; {
} if (__pred(__elem))
}, {
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __elem = __new_value;
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); }
});
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
@ -389,13 +368,12 @@ replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIt
{ {
typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; typedef typename iterator_traits<_ForwardIterator1>::reference _InputType;
typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType;
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
return __pstl::__internal::__pattern_walk2( return __pstl::__internal::__pattern_walk2(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; }, [__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; });
__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> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
@ -413,10 +391,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{ {
__pstl::__internal::__pattern_fill( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __value,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __pstl::__internal::__pattern_fill(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __value);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
@ -426,10 +404,10 @@ fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const
if (__count <= 0) if (__count <= 0)
return __first; return __first;
return __pstl::__internal::__pattern_fill_n( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __count, __value,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_fill_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __count, __value);
} }
// [alg.generate] // [alg.generate]
@ -437,10 +415,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g)
{ {
__pstl::__internal::__pattern_generate( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __g,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __g);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator> template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
@ -450,10 +428,10 @@ generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _
if (__count <= 0) if (__count <= 0)
return __first; return __first;
return __pstl::__internal::__pattern_generate_n( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __count, __g,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_generate_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __count, __g);
} }
// [alg.remove] // [alg.remove]
@ -479,10 +457,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_remove_if( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_remove_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __last, __pred);
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
@ -499,10 +477,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_unique( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_unique(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __pred);
} }
template <class _ExecutionPolicy, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator>
@ -517,12 +495,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
_BinaryPredicate __pred) _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_unique_copy( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_unique_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __last, __result, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -538,10 +514,9 @@ template <class _ExecutionPolicy, class _BidirectionalIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last)
{ {
__pstl::__internal::__pattern_reverse( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
} }
template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator> template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
@ -549,12 +524,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
_ForwardIterator __d_first) _ForwardIterator __d_first)
{ {
return __pstl::__internal::__pattern_reverse_copy( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>( return __pstl::__internal::__pattern_reverse_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __last, __d_first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(
__exec));
} }
// [alg.rotate] // [alg.rotate]
@ -563,10 +536,10 @@ template <class _ExecutionPolicy, class _ForwardIterator>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
{ {
return __pstl::__internal::__pattern_rotate( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_rotate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __middle, __last);
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -574,12 +547,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last, rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last,
_ForwardIterator2 __result) _ForwardIterator2 __result)
{ {
return __pstl::__internal::__pattern_rotate_copy( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_rotate_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__exec), __middle, __last, __result);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
// [alg.partitions] // [alg.partitions]
@ -588,20 +559,19 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_is_partitioned( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, return __pstl::__internal::__pattern_is_partitioned(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __last, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_partition( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), return __pstl::__internal::__pattern_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); __last, __pred);
} }
template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
@ -609,10 +579,9 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Bidirectiona
stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
_UnaryPredicate __pred) _UnaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_stable_partition( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, return __pstl::__internal::__pattern_stable_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), __first, __last, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardIterator1, class _ForwardIterator2, template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardIterator1, class _ForwardIterator2,
@ -621,12 +590,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_Fo
partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
_ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred) _ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_partition_copy( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1, return __pstl::__internal::__pattern_partition_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
_ForwardIterator2>(__exec), __last, __out_true, __out_false, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1,
_ForwardIterator2>(__exec));
} }
// [alg.sort] // [alg.sort]
@ -635,12 +602,11 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
return __pstl::__internal::__pattern_sort( return __pstl::__internal::__pattern_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, __comp, typename std::is_move_constructible<_InputType>::type());
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
typename std::is_move_constructible<_InputType>::type());
} }
template <class _ExecutionPolicy, class _RandomAccessIterator> template <class _ExecutionPolicy, class _RandomAccessIterator>
@ -657,10 +623,10 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_stable_sort( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), return __pstl::__internal::__pattern_stable_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); __last, __comp);
} }
template <class _ExecutionPolicy, class _RandomAccessIterator> template <class _ExecutionPolicy, class _RandomAccessIterator>
@ -678,12 +644,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_Fo
mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _BinaryPredicate __pred) _ForwardIterator2 __last2, _BinaryPredicate __pred)
{ {
return __pstl::__internal::__pattern_mismatch( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_mismatch(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
__exec), __last1, __first2, __last2, __pred);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
@ -720,10 +684,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_BinaryPredicate __p) _BinaryPredicate __p)
{ {
return __pstl::__internal::__pattern_equal( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); __last1, __first2, __p);
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -738,10 +702,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _BinaryPredicate __p) _ForwardIterator2 __last2, _BinaryPredicate __p)
{ {
return __pstl::__internal::__pattern_equal( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); __last1, __first2, __last2, __p);
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -757,17 +721,14 @@ template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterato
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first)
{ {
const auto __is_vector = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec); using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
return __pstl::__internal::__pattern_walk2_brick( return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
[__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res)
return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector); { return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{}); });
},
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
// [partial.sort] // [partial.sort]
@ -777,10 +738,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle,
_RandomAccessIterator __last, _Compare __comp) _RandomAccessIterator __last, _Compare __comp)
{ {
__pstl::__internal::__pattern_partial_sort( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), __pstl::__internal::__pattern_partial_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); __middle, __last, __comp);
} }
template <class _ExecutionPolicy, class _RandomAccessIterator> template <class _ExecutionPolicy, class _RandomAccessIterator>
@ -799,12 +760,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccess
partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
_RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_partial_sort_copy( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>( return __pstl::__internal::__pattern_partial_sort_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__exec), __first, __last, __d_first, __d_last, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator> template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
@ -821,11 +780,11 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{ {
const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp), const _ForwardIterator __res =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
/*first_semantic*/ false); /*first_semantic*/ false);
return __res == __last ? __last : std::next(__res); return __res == __last ? __last : std::next(__res);
} }
@ -841,12 +800,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_adjacent_find( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__reorder_pred<_Compare>(__comp), __last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), /*or_semantic*/ true) == __last;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
/*or_semantic*/ true) == __last;
} }
template <class _ExecutionPolicy, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator>
@ -864,12 +821,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp) _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp)
{ {
return __pstl::__internal::__pattern_merge( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __d_first);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, return __pstl::__internal::__pattern_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
_ForwardIterator>(__exec), __last1, __first2, __last2, __d_first, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
@ -886,10 +841,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle,
_BidirectionalIterator __last, _Compare __comp) _BidirectionalIterator __last, _Compare __comp)
{ {
__pstl::__internal::__pattern_inplace_merge( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), __pstl::__internal::__pattern_inplace_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); __middle, __last, __comp);
} }
template <class _ExecutionPolicy, class _BidirectionalIterator> template <class _ExecutionPolicy, class _BidirectionalIterator>
@ -908,12 +863,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _Compare __comp) _ForwardIterator2 __last2, _Compare __comp)
{ {
return __pstl::__internal::__pattern_includes( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_includes(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
__exec), __last1, __first2, __last2, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
@ -932,12 +885,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
{ {
return __pstl::__internal::__pattern_set_union( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, return __pstl::__internal::__pattern_set_union(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
_ForwardIterator>(__exec), __last1, __first2, __last2, __result, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
@ -957,12 +908,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
{ {
return __pstl::__internal::__pattern_set_intersection( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, return __pstl::__internal::__pattern_set_intersection(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
_ForwardIterator>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
@ -982,12 +931,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
{ {
return __pstl::__internal::__pattern_set_difference( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, return __pstl::__internal::__pattern_set_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
_ForwardIterator>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
@ -1008,12 +955,10 @@ set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result,
_Compare __comp) _Compare __comp)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
return __pstl::__internal::__pattern_set_symmetric_difference( return __pstl::__internal::__pattern_set_symmetric_difference(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
_ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
@ -1030,10 +975,10 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_is_heap_until( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), return __pstl::__internal::__pattern_is_heap_until(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); __last, __comp);
} }
template <class _ExecutionPolicy, class _RandomAccessIterator> template <class _ExecutionPolicy, class _RandomAccessIterator>
@ -1065,10 +1010,9 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_min_element( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, return __pstl::__internal::__pattern_min_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __last, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator>
@ -1100,10 +1044,9 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
{ {
return __pstl::__internal::__pattern_minmax_element( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, return __pstl::__internal::__pattern_minmax_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __last, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator> template <class _ExecutionPolicy, class _ForwardIterator>
@ -1121,10 +1064,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last, _Compare __comp) _RandomAccessIterator __last, _Compare __comp)
{ {
__pstl::__internal::__pattern_nth_element( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), __pstl::__internal::__pattern_nth_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth,
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); __last, __comp);
} }
template <class _ExecutionPolicy, class _RandomAccessIterator> template <class _ExecutionPolicy, class _RandomAccessIterator>
@ -1143,12 +1086,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp)
{ {
return __pstl::__internal::__pattern_lexicographical_compare( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_lexicographical_compare(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__exec), __first1, __last1, __first2, __last2, __comp);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>

View File

@ -34,28 +34,25 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk2_brick( return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector); { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
},
__is_parallel);
}, },
[&]() { [&]()
return __pstl::__internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, {
__result, return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) { __last, __result,
::new (std::addressof(__val2)) _ValueType2(__val1); [](_ReferenceType1 __val1, _ReferenceType2 __val2)
}, { ::new (std::addressof(__val2)) _ValueType2(__val1); });
__is_vector, __is_parallel);
}); });
} }
@ -68,27 +65,25 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk2_brick_n( return __pstl::__internal::__pattern_walk2_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { [](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector); { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
},
__is_parallel);
}, },
[&]() { [&]()
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, {
[](_ReferenceType1 __val1, _ReferenceType2 __val2) { return __pstl::__internal::__pattern_walk2_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
::new (std::addressof(__val2)) _ValueType2(__val1); __first, __n, __result,
}, [](_ReferenceType1 __val1, _ReferenceType2 __val2)
__is_vector, __is_parallel); { ::new (std::addressof(__val2)) _ValueType2(__val1); });
}); });
} }
@ -103,28 +98,25 @@ uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk2_brick( return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector); { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
},
__is_parallel);
}, },
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk2( return __pstl::__internal::__pattern_walk2(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) { [](_ReferenceType1 __val1, _ReferenceType2 __val2)
::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
},
__is_vector, __is_parallel);
}); });
} }
@ -137,28 +129,25 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk2_brick_n( return __pstl::__internal::__pattern_walk2_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { [](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector); { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
},
__is_parallel);
}, },
[&]() { [&]()
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, {
[](_ReferenceType1 __val1, _ReferenceType2 __val2) { return __pstl::__internal::__pattern_walk2_n(
::new (std::addressof(__val2)) __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
_ValueType2(std::move(__val1)); [](_ReferenceType1 __val1, _ReferenceType2 __val2)
}, { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
__is_vector, __is_parallel);
}); });
} }
@ -171,26 +160,24 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__pstl::__internal::__invoke_if_else( __pstl::__internal::__invoke_if_else(
std::is_arithmetic<_ValueType>(), std::is_arithmetic<_ValueType>(),
[&]() { [&]()
{
__pstl::__internal::__pattern_walk_brick( __pstl::__internal::__pattern_walk_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) { [&__value](_ForwardIterator __begin, _ForwardIterator __end)
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector); { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); });
},
__is_parallel);
}, },
[&]() { [&]()
__pstl::__internal::__pattern_walk1( {
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector, [&__value](_ReferenceType __val)
__is_parallel); { ::new (std::addressof(__val)) _ValueType(__value); });
}); });
} }
@ -201,26 +188,24 @@ uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::is_arithmetic<_ValueType>(), std::is_arithmetic<_ValueType>(),
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk_brick_n( return __pstl::__internal::__pattern_walk_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
[&__value, &__is_vector](_ForwardIterator __begin, _Size __count) { [&__value](_ForwardIterator __begin, _Size __count)
return __pstl::__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 __pstl::__internal::__pattern_walk1_n( return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector, [&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); });
__is_parallel);
}); });
} }
@ -233,16 +218,15 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() { __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); __pstl::__internal::__pattern_walk1(
}); __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { __val.~_ValueType(); });
});
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size> template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
@ -252,17 +236,15 @@ destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); }, std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); },
[&]() { [&]()
return __pstl::__internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, {
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__is_parallel); __first, __n,
[](_ReferenceType __val) { __val.~_ValueType(); });
}); });
} }
@ -275,16 +257,15 @@ uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __fi
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() { __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); __pstl::__internal::__pattern_walk1(
}); __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; });
});
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Size> template <class _ExecutionPolicy, class _ForwardIterator, class _Size>
@ -294,17 +275,15 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); }, std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk1_n( return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector, __is_parallel); [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; });
}); });
} }
@ -317,25 +296,24 @@ uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __firs
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__pstl::__internal::__invoke_if_else( __pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(), std::is_trivial<_ValueType>(),
[&]() { [&]()
__pstl::__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last, {
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) { __pstl::__internal::__pattern_walk_brick(
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
__is_vector); [](_ForwardIterator __begin, _ForwardIterator __end)
}, { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); });
__is_parallel);
}, },
[&]() { [&]()
__pstl::__internal::__pattern_walk1( {
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel); [](_ReferenceType __val)
{ ::new (std::addressof(__val)) _ValueType(); });
}); });
} }
@ -346,25 +324,24 @@ uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __fi
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
const auto __is_parallel = auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __pstl::__internal::__invoke_if_else( return __pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(), std::is_trivial<_ValueType>(),
[&]() { [&]()
return __pstl::__internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, {
[__is_vector](_ForwardIterator __begin, _Size __count) { return __pstl::__internal::__pattern_walk_brick_n(
return __pstl::__internal::__brick_fill_n( __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
__begin, __count, _ValueType(), __is_vector); [](_ForwardIterator __begin, _Size __count)
}, { return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); });
__is_parallel);
}, },
[&]() { [&]()
{
return __pstl::__internal::__pattern_walk1_n( return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel); [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); });
}); });
} }

View File

@ -59,14 +59,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init) _ForwardIterator2 __first2, _Tp __init)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
return __pstl::__internal::__pattern_transform_reduce( return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, std::plus<_InputType>(), __first1, __last1, __first2, __init, std::plus<_InputType>(),
std::multiplies<_InputType>(), std::multiplies<_InputType>());
__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, template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
@ -75,12 +73,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
{ {
return __pstl::__internal::__pattern_transform_reduce( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2, return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( __first1, __last1, __first2, __init, __binary_op1,
__exec), __binary_op2);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation> template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
@ -88,10 +84,9 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
_BinaryOperation __binary_op, _UnaryOperation __unary_op) _BinaryOperation __binary_op, _UnaryOperation __unary_op)
{ {
return __pstl::__internal::__pattern_transform_reduce( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op, return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), __first, __last, __init, __binary_op, __unary_op);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
} }
// [exclusive.scan] // [exclusive.scan]
@ -101,12 +96,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init) _ForwardIterator2 __result, _Tp __init)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
using namespace __pstl; using namespace __pstl;
return __internal::__pattern_transform_scan( return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init, __result, __pstl::__internal::__no_op(), __init, std::plus<_Tp>(),
std::plus<_Tp>(), /*inclusive=*/std::false_type(), /*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> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
@ -114,12 +109,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op) _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op)
{ {
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
using namespace __pstl; using namespace __pstl;
return __internal::__pattern_transform_scan( return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init, __result, __pstl::__internal::__no_op(), __init, __binary_op,
__binary_op, /*inclusive=*/std::false_type(), /*inclusive=*/std::false_type());
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
} }
// [inclusive.scan] // [inclusive.scan]
@ -161,13 +156,11 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op,
_UnaryOperation __unary_op) _UnaryOperation __unary_op)
{ {
return __pstl::__internal::__pattern_transform_scan( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
/*inclusive=*/std::false_type(), return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( __last, __result, __unary_op, __init, __binary_op,
__exec), /*inclusive=*/std::false_type());
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
// [transform.inclusive.scan] // [transform.inclusive.scan]
@ -179,13 +172,11 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op,
_Tp __init) _Tp __init)
{ {
return __pstl::__internal::__pattern_transform_scan( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
/*inclusive=*/std::true_type(), return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( __last, __result, __unary_op, __init, __binary_op,
__exec), /*inclusive=*/std::true_type());
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation, template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation,
@ -218,12 +209,10 @@ adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Forwa
if (__first == __last) if (__first == __last)
return __d_first; return __d_first;
return __pstl::__internal::__pattern_adjacent_difference( auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op,
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( return __pstl::__internal::__pattern_adjacent_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
__exec), __first, __last, __d_first, __op);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>

View File

@ -37,19 +37,17 @@ _Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardItera
_BinaryOperation2, _BinaryOperation2,
/*__is_vector=*/std::false_type) noexcept; /*__is_vector=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp,
class _BinaryOperation2, class _IsVector> class _BinaryOperation1, class _BinaryOperation2>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp,
_BinaryOperation1, _BinaryOperation2, _IsVector, _BinaryOperation1, _BinaryOperation2) noexcept;
/*is_parallel=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
class _BinaryOperation1, class _BinaryOperation2, class _IsVector> class _Tp, class _BinaryOperation1, class _BinaryOperation2>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, __pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1,
_Tp, _BinaryOperation1, _BinaryOperation2, _IsVector __is_vector, _RandomAccessIterator1, _RandomAccessIterator2, _Tp, _BinaryOperation1, _BinaryOperation2);
/*is_parallel=*/std::true_type);
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// transform_reduce (version with unary and binary functions) // transform_reduce (version with unary and binary functions)
@ -63,19 +61,17 @@ template <class _ForwardIterator, class _Tp, class _BinaryOperation, class _Unar
_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation, _Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation,
/*is_vector=*/std::false_type) noexcept; /*is_vector=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation,
class _IsVector> class _UnaryOperation>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
_UnaryOperation, _IsVector, _UnaryOperation) noexcept;
/*is_parallel=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation, class _UnaryOperation, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation,
class _IsVector> class _UnaryOperation>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation, __pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator,
_UnaryOperation, _IsVector, _Tp, _BinaryOperation, _UnaryOperation);
/*is_parallel=*/std::true_type);
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// transform_exclusive_scan // transform_exclusive_scan
@ -93,24 +89,23 @@ std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _R
_UnaryOperation, _Tp, _BinaryOperation, _UnaryOperation, _Tp, _BinaryOperation,
/*Inclusive*/ std::true_type) noexcept; /*Inclusive*/ std::true_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation,
class _BinaryOperation, class _Inclusive, class _IsVector> class _Tp, class _BinaryOperation, class _Inclusive>
_OutputIterator _OutputIterator
__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, _Tp, __pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation,
_BinaryOperation, _Inclusive, _IsVector, _Tp, _BinaryOperation, _Inclusive) noexcept;
/*is_parallel=*/std::false_type) noexcept;
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _BinaryOperation, class _Inclusive, class _IsVector> class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, __pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&&, _RandomAccessIterator,
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type); _RandomAccessIterator, _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive);
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _BinaryOperation, class _Inclusive, class _IsVector> class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, __pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator,
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type); _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive);
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// adjacent_difference // adjacent_difference
@ -125,17 +120,16 @@ _OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccess
_BinaryOperation, _BinaryOperation,
/*is_vector*/ std::true_type) noexcept; /*is_vector*/ std::true_type) noexcept;
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
class _IsVector>
_OutputIterator _OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation, __pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator,
_IsVector, /*is_parallel*/ std::false_type) noexcept; _BinaryOperation) noexcept;
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _IsVector> class _BinaryOperation>
_OutputIterator _OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, __pattern_adjacent_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator,
_BinaryOperation, _IsVector, /*is_parallel*/ std::true_type); _RandomAccessIterator, _OutputIterator, _BinaryOperation);
} // namespace __internal } // namespace __internal
} // namespace __pstl } // namespace __pstl

View File

@ -54,38 +54,42 @@ __brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1
[=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); }); [=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); });
} }
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp,
class _BinaryOperation2, class _IsVector> class _BinaryOperation1, class _BinaryOperation2>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2, _IsVector __is_vector, _BinaryOperation2 __binary_op2) noexcept
/*is_parallel=*/std::false_type) noexcept
{ {
return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, __is_vector); return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2,
typename _Tag::__is_vector{});
} }
template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
class _BinaryOperation1, class _BinaryOperation2, class _IsVector> class _Tp, class _BinaryOperation1, class _BinaryOperation2>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, __pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1,
_RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init,
_BinaryOperation2 __binary_op2, _IsVector __is_vector, /*is_parallel=*/std::true_type) _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
{ {
return __internal::__except_handler([&]() { using __backend_tag = typename decltype(__tag)::__backend_tag;
return __par_backend::__parallel_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, return __internal::__except_handler(
[__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable { [&]()
return __binary_op2(*__i, *(__first2 + (__i - __first1))); {
}, return __par_backend::__parallel_transform_reduce(
__init, __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
__binary_op1, // Combine [__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable
[__first1, __first2, __binary_op1, __binary_op2, { return __binary_op2(*__i, *(__first2 + (__i - __first1))); },
__is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp { __init,
return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, __binary_op1, __binary_op1, // Combine
__binary_op2, __is_vector); [__first1, __first2, __binary_op1, __binary_op2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j,
}); _Tp __init) -> _Tp
}); {
return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init,
__binary_op1, __binary_op2, _IsVector{});
});
});
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -112,31 +116,35 @@ __brick_transform_reduce(_RandomAccessIterator __first, _RandomAccessIterator __
[=, &__unary_op](_DifferenceType __i) { return __unary_op(__first[__i]); }); [=, &__unary_op](_DifferenceType __i) { return __unary_op(__first[__i]); });
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation,
class _IsVector> class _UnaryOperation>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, __pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
_BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector, _BinaryOperation __binary_op, _UnaryOperation __unary_op) noexcept
/*is_parallel=*/std::false_type) noexcept
{ {
return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, __is_vector); return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op,
typename _Tag::__is_vector{});
} }
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation, class _UnaryOperation, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation,
class _IsVector> class _UnaryOperation>
_Tp _Tp
__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, __pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
_Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector, _RandomAccessIterator __last, _Tp __init, _BinaryOperation __binary_op,
/*is_parallel=*/std::true_type) _UnaryOperation __unary_op)
{ {
return __internal::__except_handler([&]() { using __backend_tag = typename decltype(__tag)::__backend_tag;
return __par_backend::__parallel_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first, __last, return __internal::__except_handler(
[__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op, [&]()
[__unary_op, __binary_op, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { {
return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, __is_vector); return __par_backend::__parallel_transform_reduce(
}); __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last,
}); [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op,
[__unary_op, __binary_op](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) {
return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, _IsVector{});
});
});
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -212,55 +220,62 @@ __brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __la
/*is_vector=*/std::false_type()); /*is_vector=*/std::false_type());
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation,
class _BinaryOperation, class _Inclusive, class _IsVector> class _Tp, class _BinaryOperation, class _Inclusive>
_OutputIterator _OutputIterator
__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, __pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op,
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept _Inclusive) noexcept
{ {
return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(),
__is_vector) typename _Tag::__is_vector{})
.first; .first;
} }
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _BinaryOperation, class _Inclusive, class _IsVector> class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, __pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::true_type) _BinaryOperation __binary_op, _Inclusive)
{ {
using __backend_tag = typename decltype(__tag)::__backend_tag;
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
return __internal::__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, __par_backend::__parallel_transform_scan(
__binary_op, __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __last - __first,
[__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) { [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init,
// Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan. __binary_op,
return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op, [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init)
__unary_op, {
/*__is_vector*/ std::false_type()); // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan.
}, return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op,
[__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __j, __unary_op,
_Tp __init) { /*__is_vector*/ std::false_type());
return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op, },
__init, __binary_op, _Inclusive(), __is_vector) [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init)
.second; {
}); return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
return __result + (__last - __first); __init, __binary_op, _Inclusive(), _IsVector{})
}); .second;
});
return __result + (__last - __first);
});
} }
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _BinaryOperation, class _Inclusive, class _IsVector> class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type
__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, __pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::true_type) _BinaryOperation __binary_op, _Inclusive)
{ {
using __backend_tag = typename decltype(__tag)::__backend_tag;
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
_DifferenceType __n = __last - __first; _DifferenceType __n = __last - __first;
@ -268,26 +283,31 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
{ {
return __result; return __result;
} }
return __internal::__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) { __par_backend::__parallel_strict_scan(
return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i, __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, __init,
__unary_op, _Tp{}, __binary_op, _Inclusive(), __is_vector) [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len)
.second; {
}, return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i,
__binary_op, __unary_op, _Tp{}, __binary_op, _Inclusive(), _IsVector{})
[__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) { .second;
return *(std::transform(__result + __i, __result + __i + __len, __result + __i, },
[&__initial, &__binary_op](const _Tp& __x) { __binary_op,
_PSTL_PRAGMA_FORCEINLINE [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial)
return __binary_op(__initial, __x); {
}) - return *(std::transform(__result + __i, __result + __i + __len, __result + __i,
1); [&__initial, &__binary_op](const _Tp& __x)
}, {
[](_Tp) {}); _PSTL_PRAGMA_FORCEINLINE
return __result + (__last - __first); return __binary_op(__initial, __x);
}); }) -
1);
},
[](_Tp) {});
return __result + (__last - __first);
});
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -320,37 +340,38 @@ __brick_adjacent_difference(_RandomAccessIterator1 __first, _RandomAccessIterato
[&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); }); [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); });
} }
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation, template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
class _IsVector>
_OutputIterator _OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, __pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
_OutputIterator __d_first, _BinaryOperation __op, _IsVector __is_vector, _OutputIterator __d_first, _BinaryOperation __op) noexcept
/*is_parallel*/ std::false_type) noexcept
{ {
return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, __is_vector); return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{});
} }
template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryOperation, template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
class _IsVector> class _BinaryOperation>
_RandomAccessIterator2 _RandomAccessIterator2
__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, __pattern_adjacent_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec,
_RandomAccessIterator2 __d_first, _BinaryOperation __op, _IsVector __is_vector, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
/*is_parallel=*/std::true_type) _RandomAccessIterator2 __d_first, _BinaryOperation __op)
{ {
_PSTL_ASSERT(__first != __last); _PSTL_ASSERT(__first != __last);
typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
using __backend_tag = typename decltype(__tag)::__backend_tag;
*__d_first = *__first; *__d_first = *__first;
__par_backend::__parallel_for( __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last - 1,
std::forward<_ExecutionPolicy>(__exec), __first, __last - 1, [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e)
[&__op, __is_vector, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { {
_RandomAccessIterator2 __d_b = __d_first + (__b - __first); _RandomAccessIterator2 __d_b = __d_first + (__b - __first);
__internal::__brick_walk3( __internal::__brick_walk3(
__b, __e, __b + 1, __d_b + 1, __b, __e, __b + 1, __d_b + 1,
[&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); }, [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z)
__is_vector); { __z = __op(__y, __x); },
}); _IsVector{});
});
return __d_first + (__last - __first); return __d_first + (__last - __first);
} }

View File

@ -42,7 +42,7 @@ __parallel_for_body(_Index __first, _Index __last, _Fp __f)
template <class _ExecutionPolicy, class _Index, class _Fp> template <class _ExecutionPolicy, class _Index, class _Fp>
void void
__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) __parallel_for(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
{ {
if (omp_in_parallel()) if (omp_in_parallel())
{ {

View File

@ -31,7 +31,7 @@ __parallel_invoke_body(_F1&& __f1, _F2&& __f2)
template <class _ExecutionPolicy, typename _F1, typename _F2> template <class _ExecutionPolicy, typename _F1, typename _F2>
void void
__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) __parallel_invoke(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
{ {
if (omp_in_parallel()) if (omp_in_parallel())
{ {

View File

@ -64,9 +64,9 @@ __parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessI
template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2, template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge> typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
void void
__parallel_merge(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, __parallel_merge(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs,
_RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
_LeafMerge __leaf_merge) _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
{ {
std::size_t __size_x = __xe - __xs; std::size_t __size_x = __xe - __xs;

View File

@ -45,8 +45,8 @@ __parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __la
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction> template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
_Value _Value
__parallel_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity, __parallel_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
_RealBody __real_body, _Reduction __reduction) _RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction)
{ {
// We don't create a nested parallel region in an existing parallel region: // We don't create a nested parallel region in an existing parallel region:
// just create tasks. // just create tasks.

View File

@ -97,8 +97,8 @@ __parallel_strict_scan_body(_Index __n, _Tp __initial, _Rp __reduce, _Cp __combi
template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
void void
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, __parallel_strict_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
_Ap __apex) _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
{ {
if (__n <= __default_chunk_size) if (__n <= __default_chunk_size)
{ {

View File

@ -20,8 +20,9 @@ namespace __omp_backend
template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort> template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
void void
__parallel_stable_partial_sort(_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, __parallel_stable_partial_sort(__pstl::__internal::__openmp_backend_tag, _RandomAccessIterator __xs,
_LeafSort __leaf_sort, std::size_t /* __nsort */) _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
std::size_t /* __nsort */)
{ {
// TODO: "Parallel partial sort needs to be implemented."); // TODO: "Parallel partial sort needs to be implemented.");
__leaf_sort(__xs, __xe, __comp); __leaf_sort(__xs, __xe, __comp);

View File

@ -115,8 +115,9 @@ __parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
void void
__parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs, _RandomAccessIterator __xe, __parallel_stable_sort(__pstl::__internal::__openmp_backend_tag __tag, _ExecutionPolicy&& /*__exec*/,
_Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0) _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
std::size_t __nsort = 0)
{ {
auto __count = static_cast<std::size_t>(__xe - __xs); auto __count = static_cast<std::size_t>(__xe - __xs);
if (__count <= __default_chunk_size || __nsort < __count) if (__count <= __default_chunk_size || __nsort < __count)
@ -136,7 +137,7 @@ __parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs
} }
else else
{ {
__pstl::__omp_backend::__parallel_stable_partial_sort(__xs, __xe, __comp, __leaf_sort, __nsort); __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
} }
} }
else else
@ -149,7 +150,7 @@ __parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs
} }
else else
{ {
__pstl::__omp_backend::__parallel_stable_partial_sort(__xs, __xe, __comp, __leaf_sort, __nsort); __pstl::__omp_backend::__parallel_stable_partial_sort(__tag, __xs, __xe, __comp, __leaf_sort, __nsort);
} }
} }
} }

View File

@ -81,8 +81,9 @@ __transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __l
template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner, template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner,
class _Reduction> class _Reduction>
_Value _Value
__parallel_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, __parallel_transform_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
_UnaryOp __unary_op, _Value __init, _Combiner __combiner, _Reduction __reduction) _RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, _Combiner __combiner,
_Reduction __reduction)
{ {
_Value __result = __init; _Value __result = __init;
if (omp_in_parallel()) if (omp_in_parallel())

View File

@ -20,8 +20,8 @@ namespace __omp_backend
template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp> template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
_Tp _Tp
__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up /* __u */, _Tp __init, _Cp /* __combine */, __parallel_transform_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */,
_Rp /* __brick_reduce */, _Sp __scan) _Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan)
{ {
// TODO: parallelize this function. // TODO: parallelize this function.
return __scan(_Index(0), __n, __init); return __scan(_Index(0), __n, __init);

View File

@ -54,15 +54,15 @@ __cancel_execution()
template <class _ExecutionPolicy, class _Index, class _Fp> template <class _ExecutionPolicy, class _Index, class _Fp>
void void
__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) __parallel_for(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
{ {
__f(__first, __last); __f(__first, __last);
} }
template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction> template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
_Value _Value
__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity, __parallel_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
const _RealBody& __real_body, const _Reduction&) const _Value& __identity, const _RealBody& __real_body, const _Reduction&)
{ {
if (__first == __last) if (__first == __last)
{ {
@ -76,16 +76,16 @@ __parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Valu
template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce> template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce>
_Tp _Tp
__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp, __parallel_transform_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
_Reduce __reduce) _UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce)
{ {
return __reduce(__first, __last, __init); return __reduce(__first, __last, __init);
} }
template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
void void
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, __parallel_strict_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
_Ap __apex) _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
{ {
_Tp __sum = __initial; _Tp __sum = __initial;
if (__n) if (__n)
@ -97,15 +97,16 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu
template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan> template <class _ExecutionPolicy, class _Index, class _UnaryOp, class _Tp, class _BinaryOp, class _Reduce, class _Scan>
_Tp _Tp
__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _UnaryOp, _Tp __init, _BinaryOp, _Reduce, _Scan __scan) __parallel_transform_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _UnaryOp,
_Tp __init, _BinaryOp, _Reduce, _Scan __scan)
{ {
return __scan(_Index(0), __n, __init); return __scan(_Index(0), __n, __init);
} }
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
void void
__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, __parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
_LeafSort __leaf_sort, std::size_t = 0) _RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0)
{ {
__leaf_sort(__first, __last, __comp); __leaf_sort(__first, __last, __comp);
} }
@ -113,16 +114,16 @@ __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _Rando
template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2, template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge> typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
void void
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, __parallel_merge(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __first1,
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2,
_Compare __comp, _LeafMerge __leaf_merge) _RandomAccessIterator3 __outit, _Compare __comp, _LeafMerge __leaf_merge)
{ {
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp); __leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
} }
template <class _ExecutionPolicy, typename _F1, typename _F2> template <class _ExecutionPolicy, typename _F1, typename _F2>
void void
__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) __parallel_invoke(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
{ {
std::forward<_F1>(__f1)(); std::forward<_F1>(__f1)();
std::forward<_F2>(__f2)(); std::forward<_F2>(__f2)();

View File

@ -102,7 +102,7 @@ class __parallel_for_body
// wrapper over tbb::parallel_for // wrapper over tbb::parallel_for
template <class _ExecutionPolicy, class _Index, class _Fp> template <class _ExecutionPolicy, class _Index, class _Fp>
void void
__parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f) __parallel_for(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
{ {
tbb::this_task_arena::isolate([=]() { tbb::this_task_arena::isolate([=]() {
tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f)); tbb::parallel_for(tbb::blocked_range<_Index>(__first, __last), __parallel_for_body<_Index, _Fp>(__f));
@ -113,8 +113,8 @@ __parallel_for(_ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
// wrapper over tbb::parallel_reduce // wrapper over tbb::parallel_reduce
template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction> template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
_Value _Value
__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity, __parallel_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
const _RealBody& __real_body, const _Reduction& __reduction) const _Value& __identity, const _RealBody& __real_body, const _Reduction& __reduction)
{ {
return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value { return tbb::this_task_arena::isolate([__first, __last, &__identity, &__real_body, &__reduction]() -> _Value {
return tbb::parallel_reduce( return tbb::parallel_reduce(
@ -194,8 +194,8 @@ struct __par_trans_red_body
template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp> template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp>
_Tp _Tp
__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _Up __u, _Tp __init, _Cp __combine, __parallel_transform_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
_Rp __brick_reduce) _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce)
{ {
__tbb_backend::__par_trans_red_body<_Index, _Up, _Tp, _Cp, _Rp> __body(__u, __init, __combine, __brick_reduce); __tbb_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 // The grain size of 3 is used in order to provide mininum 2 elements for each body
@ -357,8 +357,8 @@ __downsweep(_Index __i, _Index __m, _Index __tilesize, _Tp* __r, _Index __lastsi
// T must have a trivial constructor and destructor. // T must have a trivial constructor and destructor.
template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap> template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
void void
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan, __parallel_strict_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
_Ap __apex) _Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
{ {
tbb::this_task_arena::isolate([=, &__combine]() { tbb::this_task_arena::isolate([=, &__combine]() {
if (__n > 1) if (__n > 1)
@ -397,8 +397,8 @@ __parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __redu
template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp> template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
_Tp _Tp
__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce, __parallel_transform_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init,
_Sp __scan) _Cp __combine, _Rp __brick_reduce, _Sp __scan)
{ {
__trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan); __trans_scan_body<_Index, _Up, _Tp, _Cp, _Rp, _Sp> __body(__u, __init, __combine, __brick_reduce, __scan);
auto __range = tbb::blocked_range<_Index>(0, __n); auto __range = tbb::blocked_range<_Index>(0, __n);
@ -1157,8 +1157,8 @@ __stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort> template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
void void
__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, __parallel_stable_sort(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __xs,
_LeafSort __leaf_sort, std::size_t __nsort = 0) _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0)
{ {
tbb::this_task_arena::isolate([=, &__nsort]() { tbb::this_task_arena::isolate([=, &__nsort]() {
//sorting based on task tree and parallel merge //sorting based on task tree and parallel merge
@ -1251,9 +1251,9 @@ operator()(__task* __self)
template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2, template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge> typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
void void
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, __parallel_merge(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs,
_RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
_LeafMerge __leaf_merge) _RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
{ {
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1; typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2; typedef typename std::iterator_traits<_RandomAccessIterator2>::difference_type _DifferenceType2;
@ -1282,7 +1282,7 @@ __parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessI
//------------------------------------------------------------------------ //------------------------------------------------------------------------
template <class _ExecutionPolicy, typename _F1, typename _F2> template <class _ExecutionPolicy, typename _F1, typename _F2>
void void
__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2) __parallel_invoke(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
{ {
//TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future //TODO: a version of tbb::this_task_arena::isolate with variadic arguments pack should be added in the future
tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); }); tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); });

View File

@ -28,17 +28,19 @@ namespace __internal
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
/** Return extremum value returned by brick f[i,j) for subranges [i,j) of [first,last) /** Return extremum value returned by brick f[i,j) for subranges [i,j) of [first,last)
Each f[i,j) must return a value in [i,j). */ Each f[i,j) must return a value in [i,j). */
template <class _ExecutionPolicy, class _Index, class _Brick, class _Compare> template <class _BackendTag, class _ExecutionPolicy, class _Index, class _Brick, class _Compare>
_Index _Index
__parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f, _Compare __comp, bool __b_first) __parallel_find(_BackendTag __tag, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f,
_Compare __comp, bool __b_first)
{ {
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType; typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
const _DifferenceType __n = __last - __first; const _DifferenceType __n = __last - __first;
_DifferenceType __initial_dist = __b_first ? __n : -1; _DifferenceType __initial_dist = __b_first ? __n : -1;
std::atomic<_DifferenceType> __extremum(__initial_dist); std::atomic<_DifferenceType> __extremum(__initial_dist);
// TODO: find out what is better here: parallel_for or parallel_reduce // TODO: find out what is better here: parallel_for or parallel_reduce
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, __par_backend::__parallel_for(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__comp, __f, __first, &__extremum](_Index __i, _Index __j) { [__comp, __f, __first, &__extremum](_Index __i, _Index __j)
{
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of // See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
// why using a shared variable scales fairly well in this situation. // why using a shared variable scales fairly well in this situation.
if (__comp(__i - __first, __extremum)) if (__comp(__i - __first, __extremum))
@ -63,13 +65,14 @@ __parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick
// parallel_or // parallel_or
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//! Return true if brick f[i,j) returns true for some subrange [i,j) of [first,last) //! Return true if brick f[i,j) returns true for some subrange [i,j) of [first,last)
template <class _ExecutionPolicy, class _Index, class _Brick> template <class _BackendTag, class _ExecutionPolicy, class _Index, class _Brick>
bool bool
__parallel_or(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f) __parallel_or(_BackendTag __tag, _ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick __f)
{ {
std::atomic<bool> __found(false); std::atomic<bool> __found(false);
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, __par_backend::__parallel_for(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__f, &__found](_Index __i, _Index __j) { [__f, &__found](_Index __i, _Index __j)
{
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j)) if (!__found.load(std::memory_order_relaxed) && __f(__i, __j))
{ {
__found.store(true, std::memory_order_relaxed); __found.store(true, std::memory_order_relaxed);

View File

@ -14,16 +14,6 @@
struct CustomPolicy struct CustomPolicy
{ {
constexpr std::false_type
__allow_vector()
{
return std::false_type{};
}
constexpr std::false_type
__allow_parallel()
{
return std::false_type{};
}
} policy; } policy;
int32_t int32_t

View File

@ -1305,7 +1305,11 @@ static void
invoke_if(Policy&&, F f) invoke_if(Policy&&, F f)
{ {
#if defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) #if defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN)
__pstl::__internal::invoke_if_not(__pstl::__internal::allow_unsequenced<Policy>(), f); using decay_policy = typename std::decay<Policy>::type;
using allow_unsequenced =
std::integral_constant<bool, (std::is_same<decay_policy, std::execution::unsequenced_policy>::value ||
std::is_same<decay_policy, std::execution::parallel_unsequenced_policy>::value)>;
__pstl::__internal::__invoke_if_not(allow_unsequenced{}, f);
#else #else
f(); f();
#endif #endif