[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:
parent
912f1c8ce3
commit
843c12d6a0
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -26,88 +26,20 @@ inline namespace v1
|
|||
// 2.4, Sequential execution 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
|
||||
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
|
||||
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
|
||||
{
|
||||
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
|
||||
|
@ -153,6 +85,12 @@ template <class ExecPolicy, class T>
|
|||
using __enable_if_execution_policy =
|
||||
typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<ExecPolicy>::type>::value,
|
||||
T>::type;
|
||||
|
||||
template <class _IsVector>
|
||||
struct __serial_tag;
|
||||
template <class _IsVector>
|
||||
struct __parallel_tag;
|
||||
|
||||
} // namespace __internal
|
||||
|
||||
} // namespace __pstl
|
||||
|
|
|
@ -23,76 +23,76 @@ namespace __pstl
|
|||
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>
|
||||
struct __is_random_access_iterator
|
||||
: std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category,
|
||||
std::random_access_iterator_tag>
|
||||
template <typename... _IteratorTypes>
|
||||
using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
|
||||
|
||||
struct __serial_backend_tag
|
||||
{
|
||||
};
|
||||
struct __tbb_backend_tag
|
||||
{
|
||||
};
|
||||
struct __openmp_backend_tag
|
||||
{
|
||||
};
|
||||
|
||||
template <typename Policy>
|
||||
struct __policy_traits
|
||||
#if defined(_PSTL_PAR_BACKEND_TBB)
|
||||
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 <>
|
||||
struct __policy_traits<sequenced_policy>
|
||||
template <class _IsVector>
|
||||
struct __parallel_tag
|
||||
{
|
||||
typedef std::false_type __allow_parallel;
|
||||
typedef std::false_type __allow_unsequenced;
|
||||
typedef std::false_type __allow_vector;
|
||||
using __is_vector = _IsVector;
|
||||
// backend tag can be change depending on
|
||||
// TBB availability in the environment
|
||||
using __backend_tag = __par_backend_tag;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct __policy_traits<unsequenced_policy>
|
||||
{
|
||||
typedef std::false_type __allow_parallel;
|
||||
typedef std::true_type __allow_unsequenced;
|
||||
typedef std::true_type __allow_vector;
|
||||
};
|
||||
template <class _IsVector, class... _IteratorTypes>
|
||||
using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
|
||||
__parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type;
|
||||
|
||||
template <>
|
||||
struct __policy_traits<parallel_policy>
|
||||
{
|
||||
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&&)
|
||||
template <class... _IteratorTypes>
|
||||
__serial_tag</*_IsVector = */ std::false_type>
|
||||
__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename _ExecutionPolicy, typename... _IteratorTypes>
|
||||
typename std::conjunction<__allow_parallel<_ExecutionPolicy>,
|
||||
__is_random_access_iterator<_IteratorTypes>...>::type
|
||||
__is_parallelization_preferred(_ExecutionPolicy&&)
|
||||
template <class... _IteratorTypes>
|
||||
__serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
|
||||
__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
|
||||
{
|
||||
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 {};
|
||||
}
|
||||
|
|
|
@ -32,10 +32,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
|
||||
any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_any_of(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_any_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__pred);
|
||||
}
|
||||
|
||||
// [alg.all_of]
|
||||
|
@ -62,20 +62,19 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Function>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
||||
for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f)
|
||||
{
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __f,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __f);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
|
||||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f)
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __f,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
__f);
|
||||
}
|
||||
|
||||
// [alg.find]
|
||||
|
@ -84,10 +83,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_find_if(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_find_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __s_last, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_find_end(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
|
||||
|
||||
return __pstl::__internal::__pattern_find_end(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __s_first, __s_last, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_find_first_of(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
|
||||
|
||||
return __pstl::__internal::__pattern_find_first_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __s_first, __s_last, __pred);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||
|
@ -156,23 +151,20 @@ template <class _ExecutionPolicy, class _ForwardIterator>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
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;
|
||||
return __pstl::__internal::__pattern_adjacent_find(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<_ValueType>(),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
/*first_semantic*/ false);
|
||||
return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, std::equal_to<_ValueType>(), /*first_semantic*/ false);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
|
||||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_adjacent_find(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
/*first_semantic*/ false);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pred, /*first_semantic*/ false);
|
||||
}
|
||||
|
||||
// [alg.count]
|
||||
|
@ -185,12 +177,11 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
|
|||
typename iterator_traits<_ForwardIterator>::difference_type>
|
||||
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;
|
||||
return __pstl::__internal::__pattern_count(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](const _ValueType& __x) { return __value == __x; },
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](const _ValueType& __x) { return __value == __x; });
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
|
||||
|
@ -198,10 +189,9 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
|
|||
typename iterator_traits<_ForwardIterator>::difference_type>
|
||||
count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_count(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__pred);
|
||||
}
|
||||
|
||||
// [alg.search]
|
||||
|
@ -211,12 +201,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
|
|||
search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
|
||||
_ForwardIterator2 __s_last, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_search(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first);
|
||||
|
||||
return __pstl::__internal::__pattern_search(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__s_first, __s_last, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
const _Tp& __value, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_search_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_search_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __count, __value, __pred);
|
||||
}
|
||||
|
||||
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>
|
||||
copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result)
|
||||
{
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
|
||||
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res)
|
||||
{ return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2>
|
||||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
|
||||
copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result)
|
||||
{
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__pattern_walk2_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[__is_vector](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) {
|
||||
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
},
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res)
|
||||
{ return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
|
||||
}
|
||||
|
||||
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,
|
||||
_Predicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_copy_if(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_copy_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __result, __pred);
|
||||
}
|
||||
|
||||
// [alg.swap]
|
||||
|
@ -305,16 +285,16 @@ swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardItera
|
|||
{
|
||||
typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
|
||||
return __pstl::__internal::__pattern_walk2(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2,
|
||||
[](_ReferenceType1 __x, _ReferenceType2 __y) {
|
||||
using std::swap;
|
||||
swap(__x, __y);
|
||||
},
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2,
|
||||
[](_ReferenceType1 __x, _ReferenceType2 __y)
|
||||
{
|
||||
using std::swap;
|
||||
swap(__x, __y);
|
||||
});
|
||||
}
|
||||
|
||||
// [alg.transform]
|
||||
|
@ -326,13 +306,12 @@ transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator
|
|||
{
|
||||
typedef typename iterator_traits<_ForwardIterator1>::reference _InputType;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType;
|
||||
return __pstl::__internal::__pattern_walk2(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); },
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__result,
|
||||
[__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); });
|
||||
}
|
||||
|
||||
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<_ForwardIterator2>::reference _Input2Type;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _OutputType;
|
||||
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_walk3(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result,
|
||||
[__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));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result,
|
||||
[__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); });
|
||||
}
|
||||
|
||||
// [alg.replace]
|
||||
|
@ -361,16 +339,17 @@ replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator
|
|||
const _Tp& __new_value)
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ElementType;
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__pred, &__new_value](_ElementType __elem) {
|
||||
if (__pred(__elem))
|
||||
{
|
||||
__elem = __new_value;
|
||||
}
|
||||
},
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__pred, &__new_value](_ElementType __elem)
|
||||
{
|
||||
if (__pred(__elem))
|
||||
{
|
||||
__elem = __new_value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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<_ForwardIterator2>::reference _OutputType;
|
||||
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_walk2(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__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));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; });
|
||||
}
|
||||
|
||||
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>
|
||||
fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
|
||||
{
|
||||
__pstl::__internal::__pattern_fill(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __value,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_fill(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__value);
|
||||
}
|
||||
|
||||
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)
|
||||
return __first;
|
||||
|
||||
return __pstl::__internal::__pattern_fill_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __count, __value,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_fill_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__count, __value);
|
||||
}
|
||||
|
||||
// [alg.generate]
|
||||
|
@ -437,10 +415,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
||||
generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g)
|
||||
{
|
||||
__pstl::__internal::__pattern_generate(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __g,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__g);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
|
||||
|
@ -450,10 +428,10 @@ generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _
|
|||
if (__count <= 0)
|
||||
return __first;
|
||||
|
||||
return __pstl::__internal::__pattern_generate_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __count, __g,
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_generate_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__count, __g);
|
||||
}
|
||||
|
||||
// [alg.remove]
|
||||
|
@ -479,10 +457,10 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_remove_if(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_remove_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pred);
|
||||
}
|
||||
|
||||
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>
|
||||
unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_unique(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_unique(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_unique_copy(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_unique_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __result, __pred);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||
|
@ -538,10 +514,9 @@ template <class _ExecutionPolicy, class _BidirectionalIterator>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
||||
reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last)
|
||||
{
|
||||
__pstl::__internal::__pattern_reverse(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator __d_first)
|
||||
{
|
||||
return __pstl::__internal::__pattern_reverse_copy(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
|
||||
|
||||
return __pstl::__internal::__pattern_reverse_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __d_first);
|
||||
}
|
||||
|
||||
// [alg.rotate]
|
||||
|
@ -563,10 +536,10 @@ template <class _ExecutionPolicy, class _ForwardIterator>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
|
||||
{
|
||||
return __pstl::__internal::__pattern_rotate(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_rotate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__middle, __last);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __result)
|
||||
{
|
||||
return __pstl::__internal::__pattern_rotate_copy(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_rotate_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__middle, __last, __result);
|
||||
}
|
||||
|
||||
// [alg.partitions]
|
||||
|
@ -588,20 +559,19 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
|
||||
is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_is_partitioned(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_is_partitioned(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pred);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
|
||||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_partition(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_UnaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_stable_partition(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_stable_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first, __last, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_partition_copy(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1,
|
||||
_ForwardIterator2>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1,
|
||||
_ForwardIterator2>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false);
|
||||
|
||||
return __pstl::__internal::__pattern_partition_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __out_true, __out_false, __pred);
|
||||
}
|
||||
|
||||
// [alg.sort]
|
||||
|
@ -635,12 +602,11 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
||||
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;
|
||||
return __pstl::__internal::__pattern_sort(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
typename std::is_move_constructible<_InputType>::type());
|
||||
return __pstl::__internal::__pattern_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__comp, typename std::is_move_constructible<_InputType>::type());
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator>
|
||||
|
@ -657,10 +623,10 @@ template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
||||
stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_stable_sort(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_stable_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __pred)
|
||||
{
|
||||
return __pstl::__internal::__pattern_mismatch(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_mismatch(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __last2, __pred);
|
||||
}
|
||||
|
||||
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,
|
||||
_BinaryPredicate __p)
|
||||
{
|
||||
return __pstl::__internal::__pattern_equal(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __p);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __last2, _BinaryPredicate __p)
|
||||
{
|
||||
return __pstl::__internal::__pattern_equal(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __last2, __p);
|
||||
}
|
||||
|
||||
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>
|
||||
move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first)
|
||||
{
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
|
||||
[__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
|
||||
return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
|
||||
[](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res)
|
||||
{ return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{}); });
|
||||
}
|
||||
|
||||
// [partial.sort]
|
||||
|
@ -777,10 +738,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
|
|||
partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle,
|
||||
_RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
__pstl::__internal::__pattern_partial_sort(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_partial_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__middle, __last, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_partial_sort_copy(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
|
||||
|
||||
return __pstl::__internal::__pattern_partial_sort_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first, __last, __d_first, __d_last, __comp);
|
||||
}
|
||||
|
||||
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>
|
||||
is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
/*first_semantic*/ false);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
const _ForwardIterator __res =
|
||||
__pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
|
||||
/*first_semantic*/ false);
|
||||
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>
|
||||
is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_adjacent_find(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__pstl::__internal::__reorder_pred<_Compare>(__comp),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
/*or_semantic*/ true) == __last;
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
|
||||
/*or_semantic*/ true) == __last;
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_merge(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
|
||||
_ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
|
||||
_ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __d_first);
|
||||
|
||||
return __pstl::__internal::__pattern_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __last2, __d_first, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_BidirectionalIterator __last, _Compare __comp)
|
||||
{
|
||||
__pstl::__internal::__pattern_inplace_merge(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_inplace_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__middle, __last, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __last2, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_includes(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_includes(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __last2, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_set_union(
|
||||
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));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_set_union(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1,
|
||||
__last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_set_intersection(
|
||||
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));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_set_intersection(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_set_difference(
|
||||
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));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_set_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_Compare __comp)
|
||||
{
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_set_symmetric_difference(
|
||||
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));
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp);
|
||||
}
|
||||
|
||||
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>
|
||||
is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_is_heap_until(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__pattern_is_heap_until(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __comp);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator>
|
||||
|
@ -1065,10 +1010,9 @@ template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
|
|||
__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
|
||||
min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_min_element(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_min_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __comp);
|
||||
}
|
||||
|
||||
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>>
|
||||
minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_minmax_element(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_minmax_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_RandomAccessIterator __last, _Compare __comp)
|
||||
{
|
||||
__pstl::__internal::__pattern_nth_element(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__pstl::__internal::__pattern_nth_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth,
|
||||
__last, __comp);
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp)
|
||||
{
|
||||
return __pstl::__internal::__pattern_lexicographical_compare(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
return __pstl::__internal::__pattern_lexicographical_compare(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first1, __last1, __first2, __last2, __comp);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||
|
|
|
@ -34,28 +34,25 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
|
|||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
|
||||
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
|
||||
{ return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
return __pstl::__internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2)
|
||||
{ ::new (std::addressof(__val2)) _ValueType2(__val1); });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -68,27 +65,25 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
|
|||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
|
||||
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
|
||||
{ return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(__val1);
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2)
|
||||
{ ::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<_ForwardIterator>::reference _ReferenceType2;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
|
||||
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res)
|
||||
{ return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2)
|
||||
{ ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -137,28 +129,25 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
|
|||
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
|
||||
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_InputIterator __begin, _Size __sz, _ForwardIterator __res)
|
||||
{ return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
|
||||
::new (std::addressof(__val2))
|
||||
_ValueType2(std::move(__val1));
|
||||
},
|
||||
__is_vector, __is_parallel);
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk2_n(
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
|
||||
[](_ReferenceType1 __val1, _ReferenceType2 __val2)
|
||||
{ ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -171,26 +160,24 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward
|
|||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
__pstl::__internal::__invoke_if_else(
|
||||
std::is_arithmetic<_ValueType>(),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
__pstl::__internal::__pattern_walk_brick(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](_ForwardIterator __begin, _ForwardIterator __end)
|
||||
{ __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
|
||||
__is_parallel);
|
||||
[&]()
|
||||
{
|
||||
__pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[&__value](_ReferenceType __val)
|
||||
{ ::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>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_arithmetic<_ValueType>(),
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk_brick_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value, &__is_vector](_ForwardIterator __begin, _Size __count) {
|
||||
return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value](_ForwardIterator __begin, _Size __count)
|
||||
{ return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
|
||||
__is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -233,16 +218,15 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __
|
|||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__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::__invoke_if_not(std::is_trivially_destructible<_ValueType>(),
|
||||
[&]()
|
||||
{
|
||||
__pstl::__internal::__pattern_walk1(
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ReferenceType __val) { __val.~_ValueType(); });
|
||||
});
|
||||
}
|
||||
|
||||
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>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
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,
|
||||
__is_parallel);
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__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>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
__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::__invoke_if_not(std::is_trivial<_ValueType>(),
|
||||
[&]()
|
||||
{
|
||||
__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>
|
||||
|
@ -294,17 +275,15 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __
|
|||
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
|
||||
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector, __is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_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>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
__pstl::__internal::__invoke_if_else(
|
||||
std::is_trivial<_ValueType>(),
|
||||
[&]() {
|
||||
__pstl::__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
|
||||
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(),
|
||||
__is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
[&]()
|
||||
{
|
||||
__pstl::__internal::__pattern_walk_brick(
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[](_ForwardIterator __begin, _ForwardIterator __end)
|
||||
{ __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
__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(); });
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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>::reference _ReferenceType;
|
||||
|
||||
const auto __is_parallel =
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
const auto __is_vector =
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
|
||||
using __is_vector = typename decltype(__dispatch_tag)::__is_vector;
|
||||
|
||||
return __pstl::__internal::__invoke_if_else(
|
||||
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::__brick_fill_n(
|
||||
__begin, __count, _ValueType(), __is_vector);
|
||||
},
|
||||
__is_parallel);
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk_brick_n(
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ForwardIterator __begin, _Size __count)
|
||||
{ return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); });
|
||||
},
|
||||
[&]() {
|
||||
[&]()
|
||||
{
|
||||
return __pstl::__internal::__pattern_walk1_n(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel);
|
||||
__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n,
|
||||
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -59,14 +59,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
|
|||
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
|
||||
_ForwardIterator2 __first2, _Tp __init)
|
||||
{
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, std::plus<_InputType>(),
|
||||
std::multiplies<_InputType>(),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first1, __last1, __first2, __init, std::plus<_InputType>(),
|
||||
std::multiplies<_InputType>());
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
|
||||
{
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2);
|
||||
return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first1, __last1, __first2, __init, __binary_op1,
|
||||
__binary_op2);
|
||||
}
|
||||
|
||||
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,
|
||||
_BinaryOperation __binary_op, _UnaryOperation __unary_op)
|
||||
{
|
||||
return __pstl::__internal::__pattern_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first);
|
||||
return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first, __last, __init, __binary_op, __unary_op);
|
||||
}
|
||||
|
||||
// [exclusive.scan]
|
||||
|
@ -101,12 +96,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
|
|||
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
|
||||
_ForwardIterator2 __result, _Tp __init)
|
||||
{
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
|
||||
std::plus<_Tp>(), /*inclusive=*/std::false_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__result, __pstl::__internal::__no_op(), __init, std::plus<_Tp>(),
|
||||
/*inclusive=*/std::false_type());
|
||||
}
|
||||
|
||||
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,
|
||||
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op)
|
||||
{
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
using namespace __pstl;
|
||||
return __internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
|
||||
__binary_op, /*inclusive=*/std::false_type(),
|
||||
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
|
||||
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
|
||||
return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
__result, __pstl::__internal::__no_op(), __init, __binary_op,
|
||||
/*inclusive=*/std::false_type());
|
||||
}
|
||||
|
||||
// [inclusive.scan]
|
||||
|
@ -161,13 +156,11 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
|
|||
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op,
|
||||
_UnaryOperation __unary_op)
|
||||
{
|
||||
return __pstl::__internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::false_type(),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::false_type());
|
||||
}
|
||||
|
||||
// [transform.inclusive.scan]
|
||||
|
@ -179,13 +172,11 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
|
|||
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op,
|
||||
_Tp __init)
|
||||
{
|
||||
return __pstl::__internal::__pattern_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::true_type(),
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result);
|
||||
|
||||
return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first,
|
||||
__last, __result, __unary_op, __init, __binary_op,
|
||||
/*inclusive=*/std::true_type());
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation,
|
||||
|
@ -218,12 +209,10 @@ adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Forwa
|
|||
if (__first == __last)
|
||||
return __d_first;
|
||||
|
||||
return __pstl::__internal::__pattern_adjacent_difference(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op,
|
||||
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec),
|
||||
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
|
||||
__exec));
|
||||
auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first);
|
||||
|
||||
return __pstl::__internal::__pattern_adjacent_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec),
|
||||
__first, __last, __d_first, __op);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||
|
|
|
@ -37,19 +37,17 @@ _Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardItera
|
|||
_BinaryOperation2,
|
||||
/*__is_vector=*/std::false_type) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
|
||||
class _BinaryOperation2, class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp,
|
||||
class _BinaryOperation1, class _BinaryOperation2>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp,
|
||||
_BinaryOperation1, _BinaryOperation2, _IsVector,
|
||||
/*is_parallel=*/std::false_type) noexcept;
|
||||
__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp,
|
||||
_BinaryOperation1, _BinaryOperation2) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp,
|
||||
class _BinaryOperation1, class _BinaryOperation2, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
|
||||
class _Tp, class _BinaryOperation1, class _BinaryOperation2>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
|
||||
_Tp, _BinaryOperation1, _BinaryOperation2, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::true_type);
|
||||
__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1,
|
||||
_RandomAccessIterator1, _RandomAccessIterator2, _Tp, _BinaryOperation1, _BinaryOperation2);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// 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,
|
||||
/*is_vector=*/std::false_type) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation,
|
||||
class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation,
|
||||
class _UnaryOperation>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
|
||||
_UnaryOperation, _IsVector,
|
||||
/*is_parallel=*/std::false_type) noexcept;
|
||||
__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
|
||||
_UnaryOperation) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation, class _UnaryOperation,
|
||||
class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation,
|
||||
class _UnaryOperation>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation,
|
||||
_UnaryOperation, _IsVector,
|
||||
/*is_parallel=*/std::true_type);
|
||||
__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator,
|
||||
_Tp, _BinaryOperation, _UnaryOperation);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// transform_exclusive_scan
|
||||
|
@ -93,24 +89,23 @@ std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _R
|
|||
_UnaryOperation, _Tp, _BinaryOperation,
|
||||
/*Inclusive*/ std::true_type) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation,
|
||||
class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
_OutputIterator
|
||||
__pattern_transform_scan(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, _Tp,
|
||||
_BinaryOperation, _Inclusive, _IsVector,
|
||||
/*is_parallel=*/std::false_type) noexcept;
|
||||
__pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation,
|
||||
_Tp, _BinaryOperation, _Inclusive) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
|
||||
class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type
|
||||
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
|
||||
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type);
|
||||
__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&&, _RandomAccessIterator,
|
||||
_RandomAccessIterator, _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive);
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
|
||||
class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type
|
||||
__pattern_transform_scan(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
|
||||
_UnaryOperation, _Tp, _BinaryOperation, _Inclusive, _IsVector, /*is_parallel=*/std::true_type);
|
||||
__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator,
|
||||
_OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// adjacent_difference
|
||||
|
@ -125,17 +120,16 @@ _OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccess
|
|||
_BinaryOperation,
|
||||
/*is_vector*/ std::true_type) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation,
|
||||
class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
|
||||
_OutputIterator
|
||||
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
|
||||
_IsVector, /*is_parallel*/ std::false_type) noexcept;
|
||||
__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator,
|
||||
_BinaryOperation) noexcept;
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation,
|
||||
class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
|
||||
class _BinaryOperation>
|
||||
_OutputIterator
|
||||
__pattern_adjacent_difference(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
|
||||
_BinaryOperation, _IsVector, /*is_parallel*/ std::true_type);
|
||||
__pattern_adjacent_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator,
|
||||
_RandomAccessIterator, _OutputIterator, _BinaryOperation);
|
||||
|
||||
} // namespace __internal
|
||||
} // namespace __pstl
|
||||
|
|
|
@ -54,38 +54,42 @@ __brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1
|
|||
[=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); });
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
|
||||
class _BinaryOperation2, class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp,
|
||||
class _BinaryOperation1, class _BinaryOperation2>
|
||||
_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,
|
||||
_BinaryOperation2 __binary_op2, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::false_type) noexcept
|
||||
_BinaryOperation2 __binary_op2) 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,
|
||||
class _BinaryOperation1, class _BinaryOperation2, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
|
||||
class _Tp, class _BinaryOperation1, class _BinaryOperation2>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1,
|
||||
_BinaryOperation2 __binary_op2, _IsVector __is_vector, /*is_parallel=*/std::true_type)
|
||||
__pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init,
|
||||
_BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
|
||||
{
|
||||
return __internal::__except_handler([&]() {
|
||||
return __par_backend::__parallel_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
|
||||
[__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable {
|
||||
return __binary_op2(*__i, *(__first2 + (__i - __first1)));
|
||||
},
|
||||
__init,
|
||||
__binary_op1, // Combine
|
||||
[__first1, __first2, __binary_op1, __binary_op2,
|
||||
__is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp {
|
||||
return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, __binary_op1,
|
||||
__binary_op2, __is_vector);
|
||||
});
|
||||
});
|
||||
using __backend_tag = typename decltype(__tag)::__backend_tag;
|
||||
|
||||
return __internal::__except_handler(
|
||||
[&]()
|
||||
{
|
||||
return __par_backend::__parallel_transform_reduce(
|
||||
__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
|
||||
[__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable
|
||||
{ return __binary_op2(*__i, *(__first2 + (__i - __first1))); },
|
||||
__init,
|
||||
__binary_op1, // Combine
|
||||
[__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]); });
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation,
|
||||
class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation,
|
||||
class _UnaryOperation>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
|
||||
_BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::false_type) noexcept
|
||||
__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
|
||||
_BinaryOperation __binary_op, _UnaryOperation __unary_op) 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,
|
||||
class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _Tp, class _BinaryOperation,
|
||||
class _UnaryOperation>
|
||||
_Tp
|
||||
__pattern_transform_reduce(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
|
||||
_Tp __init, _BinaryOperation __binary_op, _UnaryOperation __unary_op, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::true_type)
|
||||
__pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _Tp __init, _BinaryOperation __binary_op,
|
||||
_UnaryOperation __unary_op)
|
||||
{
|
||||
return __internal::__except_handler([&]() {
|
||||
return __par_backend::__parallel_transform_reduce(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__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);
|
||||
});
|
||||
});
|
||||
using __backend_tag = typename decltype(__tag)::__backend_tag;
|
||||
|
||||
return __internal::__except_handler(
|
||||
[&]()
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryOperation,
|
||||
class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
_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,
|
||||
_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(),
|
||||
__is_vector)
|
||||
typename _Tag::__is_vector{})
|
||||
.first;
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
|
||||
class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
typename std::enable_if<!std::is_floating_point<_Tp>::value, _OutputIterator>::type
|
||||
__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
|
||||
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op,
|
||||
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::true_type)
|
||||
__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
|
||||
_BinaryOperation __binary_op, _Inclusive)
|
||||
{
|
||||
using __backend_tag = typename decltype(__tag)::__backend_tag;
|
||||
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
|
||||
|
||||
return __internal::__except_handler([&]() {
|
||||
__par_backend::__parallel_transform_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __last - __first,
|
||||
[__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init,
|
||||
__binary_op,
|
||||
[__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) {
|
||||
// Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan.
|
||||
return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op,
|
||||
__unary_op,
|
||||
/*__is_vector*/ std::false_type());
|
||||
},
|
||||
[__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __j,
|
||||
_Tp __init) {
|
||||
return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
|
||||
__init, __binary_op, _Inclusive(), __is_vector)
|
||||
.second;
|
||||
});
|
||||
return __result + (__last - __first);
|
||||
});
|
||||
return __internal::__except_handler(
|
||||
[&]()
|
||||
{
|
||||
__par_backend::__parallel_transform_scan(
|
||||
__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __last - __first,
|
||||
[__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init,
|
||||
__binary_op,
|
||||
[__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init)
|
||||
{
|
||||
// Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan.
|
||||
return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op,
|
||||
__unary_op,
|
||||
/*__is_vector*/ std::false_type());
|
||||
},
|
||||
[__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init)
|
||||
{
|
||||
return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op,
|
||||
__init, __binary_op, _Inclusive(), _IsVector{})
|
||||
.second;
|
||||
});
|
||||
return __result + (__last - __first);
|
||||
});
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp,
|
||||
class _BinaryOperation, class _Inclusive, class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
|
||||
class _UnaryOperation, class _Tp, class _BinaryOperation, class _Inclusive>
|
||||
typename std::enable_if<std::is_floating_point<_Tp>::value, _OutputIterator>::type
|
||||
__pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
|
||||
_OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op,
|
||||
_Inclusive, _IsVector __is_vector, /*is_parallel=*/std::true_type)
|
||||
__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init,
|
||||
_BinaryOperation __binary_op, _Inclusive)
|
||||
{
|
||||
using __backend_tag = typename decltype(__tag)::__backend_tag;
|
||||
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
|
||||
_DifferenceType __n = __last - __first;
|
||||
|
||||
|
@ -268,26 +283,31 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
|
|||
{
|
||||
return __result;
|
||||
}
|
||||
return __internal::__except_handler([&]() {
|
||||
__par_backend::__parallel_strict_scan(
|
||||
std::forward<_ExecutionPolicy>(__exec), __n, __init,
|
||||
[__first, __unary_op, __binary_op, __result, __is_vector](_DifferenceType __i, _DifferenceType __len) {
|
||||
return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i,
|
||||
__unary_op, _Tp{}, __binary_op, _Inclusive(), __is_vector)
|
||||
.second;
|
||||
},
|
||||
__binary_op,
|
||||
[__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) {
|
||||
return *(std::transform(__result + __i, __result + __i + __len, __result + __i,
|
||||
[&__initial, &__binary_op](const _Tp& __x) {
|
||||
_PSTL_PRAGMA_FORCEINLINE
|
||||
return __binary_op(__initial, __x);
|
||||
}) -
|
||||
1);
|
||||
},
|
||||
[](_Tp) {});
|
||||
return __result + (__last - __first);
|
||||
});
|
||||
return __internal::__except_handler(
|
||||
[&]()
|
||||
{
|
||||
__par_backend::__parallel_strict_scan(
|
||||
__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, __init,
|
||||
[__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len)
|
||||
{
|
||||
return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i,
|
||||
__unary_op, _Tp{}, __binary_op, _Inclusive(), _IsVector{})
|
||||
.second;
|
||||
},
|
||||
__binary_op,
|
||||
[__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial)
|
||||
{
|
||||
return *(std::transform(__result + __i, __result + __i + __len, __result + __i,
|
||||
[&__initial, &__binary_op](const _Tp& __x)
|
||||
{
|
||||
_PSTL_PRAGMA_FORCEINLINE
|
||||
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); });
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation,
|
||||
class _IsVector>
|
||||
template <class _Tag, class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
|
||||
_OutputIterator
|
||||
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
|
||||
_OutputIterator __d_first, _BinaryOperation __op, _IsVector __is_vector,
|
||||
/*is_parallel*/ std::false_type) noexcept
|
||||
__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
|
||||
_OutputIterator __d_first, _BinaryOperation __op) 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,
|
||||
class _IsVector>
|
||||
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
|
||||
class _BinaryOperation>
|
||||
_RandomAccessIterator2
|
||||
__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
|
||||
_RandomAccessIterator2 __d_first, _BinaryOperation __op, _IsVector __is_vector,
|
||||
/*is_parallel=*/std::true_type)
|
||||
__pattern_adjacent_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec,
|
||||
_RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
|
||||
_RandomAccessIterator2 __d_first, _BinaryOperation __op)
|
||||
{
|
||||
_PSTL_ASSERT(__first != __last);
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
|
||||
|
||||
using __backend_tag = typename decltype(__tag)::__backend_tag;
|
||||
|
||||
*__d_first = *__first;
|
||||
__par_backend::__parallel_for(
|
||||
std::forward<_ExecutionPolicy>(__exec), __first, __last - 1,
|
||||
[&__op, __is_vector, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) {
|
||||
_RandomAccessIterator2 __d_b = __d_first + (__b - __first);
|
||||
__internal::__brick_walk3(
|
||||
__b, __e, __b + 1, __d_b + 1,
|
||||
[&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); },
|
||||
__is_vector);
|
||||
});
|
||||
__par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last - 1,
|
||||
[&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e)
|
||||
{
|
||||
_RandomAccessIterator2 __d_b = __d_first + (__b - __first);
|
||||
__internal::__brick_walk3(
|
||||
__b, __e, __b + 1, __d_b + 1,
|
||||
[&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z)
|
||||
{ __z = __op(__y, __x); },
|
||||
_IsVector{});
|
||||
});
|
||||
return __d_first + (__last - __first);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ __parallel_for_body(_Index __first, _Index __last, _Fp __f)
|
|||
|
||||
template <class _ExecutionPolicy, class _Index, class _Fp>
|
||||
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())
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ __parallel_invoke_body(_F1&& __f1, _F2&& __f2)
|
|||
|
||||
template <class _ExecutionPolicy, typename _F1, typename _F2>
|
||||
void
|
||||
__parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
|
||||
__parallel_invoke(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
|
||||
{
|
||||
if (omp_in_parallel())
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
|
||||
void
|
||||
__parallel_merge(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe,
|
||||
_RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp,
|
||||
_LeafMerge __leaf_merge)
|
||||
__parallel_merge(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&& /*__exec*/, _RandomAccessIterator1 __xs,
|
||||
_RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
|
||||
_RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
|
||||
|
||||
{
|
||||
std::size_t __size_x = __xe - __xs;
|
||||
|
|
|
@ -45,8 +45,8 @@ __parallel_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __la
|
|||
|
||||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Value, typename _RealBody, typename _Reduction>
|
||||
_Value
|
||||
__parallel_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Value __identity,
|
||||
_RealBody __real_body, _Reduction __reduction)
|
||||
__parallel_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _Value __identity, _RealBody __real_body, _Reduction __reduction)
|
||||
{
|
||||
// We don't create a nested parallel region in an existing parallel region:
|
||||
// just create tasks.
|
||||
|
|
|
@ -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>
|
||||
void
|
||||
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan,
|
||||
_Ap __apex)
|
||||
__parallel_strict_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
|
||||
_Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
|
||||
{
|
||||
if (__n <= __default_chunk_size)
|
||||
{
|
||||
|
|
|
@ -20,8 +20,9 @@ namespace __omp_backend
|
|||
|
||||
template <typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
|
||||
void
|
||||
__parallel_stable_partial_sort(_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp,
|
||||
_LeafSort __leaf_sort, std::size_t /* __nsort */)
|
||||
__parallel_stable_partial_sort(__pstl::__internal::__openmp_backend_tag, _RandomAccessIterator __xs,
|
||||
_RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
|
||||
std::size_t /* __nsort */)
|
||||
{
|
||||
// TODO: "Parallel partial sort needs to be implemented.");
|
||||
__leaf_sort(__xs, __xe, __comp);
|
||||
|
|
|
@ -115,8 +115,9 @@ __parallel_stable_sort_body(_RandomAccessIterator __xs, _RandomAccessIterator __
|
|||
|
||||
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
|
||||
void
|
||||
__parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs, _RandomAccessIterator __xe,
|
||||
_Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0)
|
||||
__parallel_stable_sort(__pstl::__internal::__openmp_backend_tag __tag, _ExecutionPolicy&& /*__exec*/,
|
||||
_RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort,
|
||||
std::size_t __nsort = 0)
|
||||
{
|
||||
auto __count = static_cast<std::size_t>(__xe - __xs);
|
||||
if (__count <= __default_chunk_size || __nsort < __count)
|
||||
|
@ -136,7 +137,7 @@ __parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs
|
|||
}
|
||||
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
|
||||
|
@ -149,7 +150,7 @@ __parallel_stable_sort(_ExecutionPolicy&& /*__exec*/, _RandomAccessIterator __xs
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,8 +81,9 @@ __transform_reduce_body(_RandomAccessIterator __first, _RandomAccessIterator __l
|
|||
template <class _ExecutionPolicy, class _RandomAccessIterator, class _UnaryOp, class _Value, class _Combiner,
|
||||
class _Reduction>
|
||||
_Value
|
||||
__parallel_transform_reduce(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last,
|
||||
_UnaryOp __unary_op, _Value __init, _Combiner __combiner, _Reduction __reduction)
|
||||
__parallel_transform_reduce(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _UnaryOp __unary_op, _Value __init, _Combiner __combiner,
|
||||
_Reduction __reduction)
|
||||
{
|
||||
_Value __result = __init;
|
||||
if (omp_in_parallel())
|
||||
|
|
|
@ -20,8 +20,8 @@ namespace __omp_backend
|
|||
|
||||
template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp, class _Sp>
|
||||
_Tp
|
||||
__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up /* __u */, _Tp __init, _Cp /* __combine */,
|
||||
_Rp /* __brick_reduce */, _Sp __scan)
|
||||
__parallel_transform_scan(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __n, _Up /* __u */,
|
||||
_Tp __init, _Cp /* __combine */, _Rp /* __brick_reduce */, _Sp __scan)
|
||||
{
|
||||
// TODO: parallelize this function.
|
||||
return __scan(_Index(0), __n, __init);
|
||||
|
|
|
@ -54,15 +54,15 @@ __cancel_execution()
|
|||
|
||||
template <class _ExecutionPolicy, class _Index, class _Fp>
|
||||
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);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
|
||||
_Value
|
||||
__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity,
|
||||
const _RealBody& __real_body, const _Reduction&)
|
||||
__parallel_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
|
||||
const _Value& __identity, const _RealBody& __real_body, const _Reduction&)
|
||||
{
|
||||
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>
|
||||
_Tp
|
||||
__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _UnaryOp, _Tp __init, _BinaryOp,
|
||||
_Reduce __reduce)
|
||||
__parallel_transform_reduce(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
|
||||
_UnaryOp, _Tp __init, _BinaryOp, _Reduce __reduce)
|
||||
{
|
||||
return __reduce(__first, __last, __init);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
|
||||
void
|
||||
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan,
|
||||
_Ap __apex)
|
||||
__parallel_strict_scan(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
|
||||
_Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
|
||||
{
|
||||
_Tp __sum = __initial;
|
||||
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>
|
||||
_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);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
|
||||
void
|
||||
__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
|
||||
_LeafSort __leaf_sort, std::size_t = 0)
|
||||
__parallel_stable_sort(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __first,
|
||||
_RandomAccessIterator __last, _Compare __comp, _LeafSort __leaf_sort, std::size_t = 0)
|
||||
{
|
||||
__leaf_sort(__first, __last, __comp);
|
||||
}
|
||||
|
@ -113,16 +114,16 @@ __parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _Rando
|
|||
template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
|
||||
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
|
||||
void
|
||||
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
|
||||
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit,
|
||||
_Compare __comp, _LeafMerge __leaf_merge)
|
||||
__parallel_merge(__pstl::__internal::__serial_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __first1,
|
||||
_RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2,
|
||||
_RandomAccessIterator3 __outit, _Compare __comp, _LeafMerge __leaf_merge)
|
||||
{
|
||||
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
|
||||
}
|
||||
|
||||
template <class _ExecutionPolicy, typename _F1, typename _F2>
|
||||
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<_F2>(__f2)();
|
||||
|
|
|
@ -102,7 +102,7 @@ class __parallel_for_body
|
|||
// wrapper over tbb::parallel_for
|
||||
template <class _ExecutionPolicy, class _Index, class _Fp>
|
||||
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::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
|
||||
template <class _ExecutionPolicy, class _Value, class _Index, typename _RealBody, typename _Reduction>
|
||||
_Value
|
||||
__parallel_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, const _Value& __identity,
|
||||
const _RealBody& __real_body, const _Reduction& __reduction)
|
||||
__parallel_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
|
||||
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::parallel_reduce(
|
||||
|
@ -194,8 +194,8 @@ struct __par_trans_red_body
|
|||
|
||||
template <class _ExecutionPolicy, class _Index, class _Up, class _Tp, class _Cp, class _Rp>
|
||||
_Tp
|
||||
__parallel_transform_reduce(_ExecutionPolicy&&, _Index __first, _Index __last, _Up __u, _Tp __init, _Cp __combine,
|
||||
_Rp __brick_reduce)
|
||||
__parallel_transform_reduce(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last,
|
||||
_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);
|
||||
// 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.
|
||||
template <class _ExecutionPolicy, typename _Index, typename _Tp, typename _Rp, typename _Cp, typename _Sp, typename _Ap>
|
||||
void
|
||||
__parallel_strict_scan(_ExecutionPolicy&&, _Index __n, _Tp __initial, _Rp __reduce, _Cp __combine, _Sp __scan,
|
||||
_Ap __apex)
|
||||
__parallel_strict_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Tp __initial,
|
||||
_Rp __reduce, _Cp __combine, _Sp __scan, _Ap __apex)
|
||||
{
|
||||
tbb::this_task_arena::isolate([=, &__combine]() {
|
||||
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>
|
||||
_Tp
|
||||
__parallel_transform_scan(_ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init, _Cp __combine, _Rp __brick_reduce,
|
||||
_Sp __scan)
|
||||
__parallel_transform_scan(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _Index __n, _Up __u, _Tp __init,
|
||||
_Cp __combine, _Rp __brick_reduce, _Sp __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);
|
||||
|
@ -1157,8 +1157,8 @@ __stable_sort_func<_RandomAccessIterator1, _RandomAccessIterator2, _Compare, _Le
|
|||
|
||||
template <class _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _LeafSort>
|
||||
void
|
||||
__parallel_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __xs, _RandomAccessIterator __xe, _Compare __comp,
|
||||
_LeafSort __leaf_sort, std::size_t __nsort = 0)
|
||||
__parallel_stable_sort(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator __xs,
|
||||
_RandomAccessIterator __xe, _Compare __comp, _LeafSort __leaf_sort, std::size_t __nsort = 0)
|
||||
{
|
||||
tbb::this_task_arena::isolate([=, &__nsort]() {
|
||||
//sorting based on task tree and parallel merge
|
||||
|
@ -1251,9 +1251,9 @@ operator()(__task* __self)
|
|||
template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
|
||||
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
|
||||
void
|
||||
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe,
|
||||
_RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp,
|
||||
_LeafMerge __leaf_merge)
|
||||
__parallel_merge(__pstl::__internal::__tbb_backend_tag, _ExecutionPolicy&&, _RandomAccessIterator1 __xs,
|
||||
_RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
|
||||
_RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
|
||||
{
|
||||
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType1;
|
||||
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>
|
||||
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
|
||||
tbb::this_task_arena::isolate([&]() { tbb::parallel_invoke(std::forward<_F1>(__f1), std::forward<_F2>(__f2)); });
|
||||
|
|
|
@ -28,17 +28,19 @@ namespace __internal
|
|||
//-----------------------------------------------------------------------
|
||||
/** 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). */
|
||||
template <class _ExecutionPolicy, class _Index, class _Brick, class _Compare>
|
||||
template <class _BackendTag, class _ExecutionPolicy, class _Index, class _Brick, class _Compare>
|
||||
_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;
|
||||
const _DifferenceType __n = __last - __first;
|
||||
_DifferenceType __initial_dist = __b_first ? __n : -1;
|
||||
std::atomic<_DifferenceType> __extremum(__initial_dist);
|
||||
// TODO: find out what is better here: parallel_for or parallel_reduce
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__comp, __f, __first, &__extremum](_Index __i, _Index __j) {
|
||||
__par_backend::__parallel_for(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__comp, __f, __first, &__extremum](_Index __i, _Index __j)
|
||||
{
|
||||
// See "Reducing Contention Through Priority Updates", PPoPP '13, for discussion of
|
||||
// why using a shared variable scales fairly well in this situation.
|
||||
if (__comp(__i - __first, __extremum))
|
||||
|
@ -63,13 +65,14 @@ __parallel_find(_ExecutionPolicy&& __exec, _Index __first, _Index __last, _Brick
|
|||
// parallel_or
|
||||
//------------------------------------------------------------------------
|
||||
//! 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
|
||||
__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);
|
||||
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__f, &__found](_Index __i, _Index __j) {
|
||||
__par_backend::__parallel_for(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last,
|
||||
[__f, &__found](_Index __i, _Index __j)
|
||||
{
|
||||
if (!__found.load(std::memory_order_relaxed) && __f(__i, __j))
|
||||
{
|
||||
__found.store(true, std::memory_order_relaxed);
|
||||
|
|
|
@ -14,16 +14,6 @@
|
|||
|
||||
struct CustomPolicy
|
||||
{
|
||||
constexpr std::false_type
|
||||
__allow_vector()
|
||||
{
|
||||
return std::false_type{};
|
||||
}
|
||||
constexpr std::false_type
|
||||
__allow_parallel()
|
||||
{
|
||||
return std::false_type{};
|
||||
}
|
||||
} policy;
|
||||
|
||||
int32_t
|
||||
|
|
|
@ -1305,7 +1305,11 @@ static void
|
|||
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)
|
||||
__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
|
||||
f();
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue