libstdc++: Synchronize PSTL with upstream

This patch rebases the C++17 parallel algorithms implementation (pstl)
against the current upstream version, commit 843c12d6a.

This version does not currently include the recently added OpenMP
backend, that will be considered for a future version.

libstdc++-v3/ChangeLog:
	* include/pstl/algorithm_fwd.h: Synchronize with upstream.
	* include/pstl/algorithm_impl.h: Likewise.
	* include/pstl/execution_defs.h: Likewise.
	* include/pstl/execution_impl.h: Likewise.
	* include/pstl/glue_algorithm_impl.h: Likewise.
	* include/pstl/glue_execution_defs.h: Likewise.
	* include/pstl/glue_memory_impl.h: Likewise.
	* include/pstl/glue_numeric_impl.h: Likewise.
	* include/pstl/memory_impl.h: Likewise.
	* include/pstl/numeric_fwd.h: Likewise.
	* include/pstl/numeric_impl.h: Likewise.
	* include/pstl/parallel_backend.h: Likewise.
	* include/pstl/parallel_backend_serial.h: Likewise.
	* include/pstl/parallel_backend_tbb.h: Likewise.
	* include/pstl/parallel_impl.h: Likewise.
	* include/pstl/pstl_config.h: Likewise.
	* include/pstl/unseq_backend_simd.h: Likewise.
	* include/pstl/utils.h: Likewise.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc:
	Likewise.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc:
	Likewise.
	* testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_merge/merge.cc: Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/includes.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/set.cc:
	Likewise.
	* testsuite/25_algorithms/pstl/alg_sorting/sort.cc:
	Likewise.
	* testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc:
	Likewise.
	* testsuite/26_numerics/pstl/numeric_ops/reduce.cc:
	Likewise.
	* testsuite/26_numerics/pstl/numeric_ops/scan.cc:
	Likewise.
	* testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc:
	Likewise.
	* testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc:
	Likewise.
	* testsuite/util/pstl/test_utils.h:
	Likewise.
This commit is contained in:
Thomas Rodgers 2023-06-26 11:30:21 -07:00
parent 3a39a31b8a
commit 3162ca09db
72 changed files with 3367 additions and 3319 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -22,88 +22,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
@ -135,7 +67,7 @@ struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_ty
{
};
#if _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
#if defined (_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT)
template <class _Tp>
constexpr bool is_execution_policy_v = __pstl::execution::is_execution_policy<_Tp>::value;
#endif
@ -155,6 +87,12 @@ using __enable_if_execution_policy =
typename std::enable_if<__pstl::execution::is_execution_policy<typename std::decay<_ExecPolicy>::type>::value,
_Tp>::type;
#endif
template <class _IsVector>
struct __serial_tag;
template <class _IsVector>
struct __parallel_tag;
} // namespace __internal
} // namespace __pstl

View file

@ -20,141 +20,80 @@ 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>...>;
/* predicate */
template <typename... _IteratorTypes>
using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
template <typename _Tp>
std::false_type __lazy_and(_Tp, std::false_type)
struct __serial_backend_tag
{
return std::false_type{};
};
struct __tbb_backend_tag
{
};
struct __openmp_backend_tag
{
};
#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 <class _IsVector>
struct __parallel_tag
{
using __is_vector = _IsVector;
// backend tag can be change depending on
// TBB availability in the environment
using __backend_tag = __par_backend_tag;
};
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 <class... _IteratorTypes>
__serial_tag</*_IsVector = */ std::false_type>
__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
{
return {};
}
template <typename _Tp>
inline _Tp
__lazy_and(_Tp __a, std::true_type)
template <class... _IteratorTypes>
__serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
{
return __a;
return {};
}
template <typename _Tp>
std::true_type __lazy_or(_Tp, std::true_type)
template <class... _IteratorTypes>
__tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...)
{
return std::true_type{};
return {};
}
template <typename _Tp>
inline _Tp
__lazy_or(_Tp __a, std::false_type)
template <class... _IteratorTypes>
__tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
{
return __a;
return {};
}
/* iterator */
template <typename _IteratorType, typename... _OtherIteratorTypes>
struct __is_random_access_iterator
{
static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value &&
__internal::__is_random_access_iterator<_OtherIteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
template <typename _IteratorType>
struct __is_random_access_iterator<_IteratorType>
: std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag>
{
};
/* policy */
template <typename _Policy>
struct __policy_traits
{
};
template <>
struct __policy_traits<sequenced_policy>
{
typedef std::false_type allow_parallel;
typedef std::false_type allow_unsequenced;
typedef std::false_type allow_vector;
};
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 <>
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 __collector_t =
typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type;
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>
auto
__is_vectorization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__internal::__lazy_and(__exec.__allow_vector(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
{
return __internal::__lazy_and(__exec.__allow_vector(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename _ExecutionPolicy, typename... _IteratorTypes>
auto
__is_parallelization_preferred(_ExecutionPolicy&& __exec)
-> decltype(__internal::__lazy_and(__exec.__allow_parallel(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()))
{
return __internal::__lazy_and(__exec.__allow_parallel(),
typename __internal::__is_random_access_iterator<_IteratorTypes...>::type());
}
template <typename __policy, typename... _IteratorTypes>
struct __prefer_unsequenced_tag
{
static constexpr bool value = __internal::__allow_unsequenced<__policy>::value &&
__internal::__is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
template <typename __policy, typename... _IteratorTypes>
struct __prefer_parallel_tag
{
static constexpr bool value = __internal::__allow_parallel<__policy>::value &&
__internal::__is_random_access_iterator<_IteratorTypes...>::value;
typedef std::integral_constant<bool, value> type;
};
} // namespace __internal
} // namespace __pstl

View file

@ -26,10 +26,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]
@ -56,20 +56,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]
@ -78,10 +77,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>
@ -105,12 +104,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>
@ -128,12 +125,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>
@ -150,23 +145,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]
@ -179,12 +171,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>
@ -192,10 +183,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]
@ -205,12 +195,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>
@ -226,10 +214,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>
@ -247,34 +235,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>
@ -282,12 +264,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]
@ -299,16 +279,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]
@ -320,13 +300,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,
@ -338,13 +317,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]
@ -355,16 +333,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>
@ -383,13 +362,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>
@ -407,10 +385,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>
@ -420,10 +398,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]
@ -431,10 +409,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>
@ -444,10 +422,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]
@ -473,10 +451,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>
@ -493,10 +471,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>
@ -511,12 +489,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>
@ -532,10 +508,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>
@ -543,12 +518,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]
@ -557,10 +530,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>
@ -568,12 +541,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]
@ -582,20 +553,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>
@ -603,10 +573,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,
@ -615,12 +584,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]
@ -629,12 +596,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>
@ -651,10 +617,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>
@ -672,12 +638,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>
@ -714,10 +678,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>
@ -732,10 +696,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>
@ -751,17 +715,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]
@ -771,10 +732,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>
@ -793,12 +754,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>
@ -815,11 +774,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);
}
@ -835,12 +794,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>
@ -858,12 +815,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>
@ -880,10 +835,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>
@ -902,12 +857,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>
@ -926,12 +879,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>
@ -951,12 +902,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>
@ -976,12 +925,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>
@ -1002,12 +949,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>
@ -1024,10 +969,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>
@ -1059,10 +1004,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>
@ -1094,10 +1038,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>
@ -1115,10 +1058,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>
@ -1137,12 +1080,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>

View file

@ -18,10 +18,10 @@ namespace std
{
// Type trait
using __pstl::execution::is_execution_policy;
#if _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
# if __INTEL_COMPILER
template <class T>
constexpr bool is_execution_policy_v = is_execution_policy<T>::value;
#if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT)
# if defined(__INTEL_COMPILER)
template <class _Tp>
constexpr bool is_execution_policy_v = is_execution_policy<_Tp>::value;
# else
using __pstl::execution::is_execution_policy_v;
# endif

View file

@ -13,6 +13,8 @@
#include "utils.h"
#include "algorithm_fwd.h"
#include "execution_impl.h"
namespace std
{
@ -27,28 +29,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); });
});
}
@ -61,27 +60,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); });
});
}
@ -96,28 +93,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)); });
});
}
@ -130,28 +124,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)); });
});
}
@ -164,26 +155,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); });
});
}
@ -194,26 +183,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); });
});
}
@ -226,16 +213,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>
@ -245,17 +231,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(); });
});
}
@ -268,16 +252,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>
@ -287,17 +270,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; });
});
}
@ -310,25 +291,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(); });
});
}
@ -339,25 +319,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(); });
});
}

View file

@ -54,14 +54,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,
@ -70,12 +68,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>
@ -83,10 +79,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]
@ -96,12 +91,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>
@ -109,12 +104,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]
@ -156,13 +151,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]
@ -174,13 +167,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,
@ -213,12 +204,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>

View file

@ -36,13 +36,13 @@ __brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _O
return __result;
}
template <typename _ForwardIterator, typename _OutputIterator>
template <typename _RandomAccessIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
__brick_uninitialized_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
/*vector=*/std::true_type) noexcept
{
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
return __unseq_backend::__simd_walk_2(
@ -60,12 +60,12 @@ __brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type)
__first->~_ValueType();
}
template <typename _Iterator>
template <typename _RandomAccessIterator>
void
__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::true_type) noexcept
__brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept
{
using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
using _ReferenceType = typename std::iterator_traits<_Iterator>::reference;
using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type;
using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference;
__unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); });
}
@ -87,13 +87,13 @@ __brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _O
return __result;
}
template <typename _ForwardIterator, typename _OutputIterator>
template <typename _RandomAccessIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
__brick_uninitialized_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
/*vector=*/std::true_type) noexcept
{
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference;
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
return __unseq_backend::__simd_walk_2(

View file

@ -22,9 +22,10 @@ namespace __internal
// transform_reduce (version with two binary functions, according to draft N4659)
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
_Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, _BinaryOperation1,
_BinaryOperation2,
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp, class _BinaryOperation1,
class _BinaryOperation2>
_Tp __brick_transform_reduce(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Tp,
_BinaryOperation1, _BinaryOperation2,
/*__is_vector=*/std::true_type) noexcept;
template <class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
@ -32,45 +33,41 @@ _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)
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation,
template <class _RandomAccessIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
_Tp __brick_transform_reduce(_RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation, _UnaryOperation,
/*is_vector=*/std::true_type) noexcept;
template <class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
_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 _ForwardIterator, 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&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation,
_UnaryOperation, _IsVector,
/*is_parallel=*/std::true_type);
__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator,
_Tp, _BinaryOperation, _UnaryOperation);
//------------------------------------------------------------------------
// transform_exclusive_scan
@ -83,29 +80,28 @@ std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _Forwar
_UnaryOperation, _Tp, _BinaryOperation,
/*Inclusive*/ std::false_type) noexcept;
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _ForwardIterator, _OutputIterator,
template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
_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
@ -115,20 +111,20 @@ template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
/*is_vector*/ std::false_type) noexcept;
template <class _ForwardIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
template <class _RandomAccessIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
_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 _ForwardIterator, class _OutputIterator, class _BinaryOperation,
class _IsVector>
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator,
class _BinaryOperation>
_OutputIterator
__pattern_adjacent_difference(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation,
__pattern_adjacent_difference(_ExecutionPolicy&&, _OutputIterator, _OutputIterator, _OutputIterator, _BinaryOperation,
_IsVector, /*is_parallel*/ std::true_type);
} // namespace __internal

View file

@ -38,50 +38,56 @@ __brick_transform_reduce(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
return std::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2);
}
template <class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2>
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _Tp, class _BinaryOperation1,
class _BinaryOperation2>
_Tp
__brick_transform_reduce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Tp __init,
_BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2,
__brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2,
/*is_vector=*/std::true_type) noexcept
{
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType;
return __unseq_backend::__simd_transform_reduce(
__last1 - __first1, __init, __binary_op1,
[=, &__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{});
});
});
}
//------------------------------------------------------------------------
@ -96,42 +102,47 @@ __brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp
return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op);
}
template <class _ForwardIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
template <class _RandomAccessIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
_Tp
__brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op,
_UnaryOperation __unary_op, /*is_vector=*/std::true_type) noexcept
__brick_transform_reduce(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp __init,
_BinaryOperation __binary_op, _UnaryOperation __unary_op,
/*is_vector=*/std::true_type) noexcept
{
typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType;
typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
return __unseq_backend::__simd_transform_reduce(
__last - __first, __init, __binary_op,
[=, &__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 _ForwardIterator, 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, _ForwardIterator __first, _ForwardIterator __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](_ForwardIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op,
[__unary_op, __binary_op, __is_vector](_ForwardIterator __i, _ForwardIterator __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{});
});
});
}
//------------------------------------------------------------------------
@ -157,9 +168,9 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu
}
// Inclusive form
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation>
std::pair<_OutputIterator, _Tp>
__brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
_UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op,
/*Inclusive*/ std::true_type, /*is_vector=*/std::false_type) noexcept
{
@ -179,14 +190,14 @@ using is_arithmetic_udop = std::integral_constant<bool, std::is_arithmetic<_Tp>:
// [restriction] - T shall be DefaultConstructible.
// [violation] - default ctor of T shall set the identity value for binary_op.
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation,
template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation,
class _Inclusive>
typename std::enable_if<!is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
__brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
_UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive,
/*is_vector=*/std::true_type) noexcept
{
#if (_PSTL_UDS_PRESENT)
#if defined(_PSTL_UDS_PRESENT)
return __unseq_backend::__simd_scan(__first, __last - __first, __result, __unary_op, __init, __binary_op,
_Inclusive());
#else
@ -196,10 +207,10 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu
#endif
}
template <class _ForwardIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation,
template <class _RandomAccessIterator, class _OutputIterator, class _UnaryOperation, class _Tp, class _BinaryOperation,
class _Inclusive>
typename std::enable_if<is_arithmetic_udop<_Tp, _BinaryOperation>::value, std::pair<_OutputIterator, _Tp>>::type
__brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
_UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive,
/*is_vector=*/std::true_type) noexcept
{
@ -207,55 +218,62 @@ __brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _Outpu
/*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;
@ -263,26 +281,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);
});
}
//------------------------------------------------------------------------
@ -297,15 +320,16 @@ __brick_adjacent_difference(_ForwardIterator __first, _ForwardIterator __last, _
return std::adjacent_difference(__first, __last, __d_first, __op);
}
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation>
_ForwardIterator2
__brick_adjacent_difference(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first,
_BinaryOperation __op, /*is_vector=*/std::true_type) noexcept
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryOperation>
_RandomAccessIterator2
__brick_adjacent_difference(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last,
_RandomAccessIterator2 __d_first, _BinaryOperation __op,
/*is_vector=*/std::true_type) noexcept
{
_PSTL_ASSERT(__first != __last);
typedef typename std::iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
typedef typename std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1;
typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2;
auto __n = __last - __first;
*__d_first = *__first;
@ -314,37 +338,38 @@ __brick_adjacent_difference(_ForwardIterator1 __first, _ForwardIterator1 __last,
[&__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 _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation,
class _IsVector>
_ForwardIterator2
__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __d_first, _BinaryOperation __op, _IsVector __is_vector,
/*is_parallel=*/std::true_type)
template <class _IsVector, class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
class _BinaryOperation>
_RandomAccessIterator2
__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<_ForwardIterator1>::reference _ReferenceType1;
typedef typename std::iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
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](_ForwardIterator1 __b, _ForwardIterator1 __e) {
_ForwardIterator2 __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);
}

View file

@ -22,6 +22,12 @@ namespace __pstl
{
namespace __par_backend = __tbb_backend;
}
#elif defined(_PSTL_PAR_BACKEND_OPENMP)
# include "parallel_backend_omp.h"
namespace __pstl
{
namespace __par_backend = __omp_backend;
}
#else
_PSTL_PRAGMA_MESSAGE("Parallel backend was not specified");
#endif

View file

@ -50,15 +50,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)
{
@ -72,16 +72,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)
@ -93,15 +93,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);
}
@ -109,16 +110,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)();

View file

@ -99,7 +99,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));
@ -110,8 +110,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(
@ -191,8 +191,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
@ -354,8 +354,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)
@ -394,8 +394,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);
@ -1154,8 +1154,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
@ -1248,9 +1248,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;
@ -1279,7 +1279,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)); });

View file

@ -24,17 +24,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))
@ -59,13 +61,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);

View file

@ -11,12 +11,12 @@
#define _PSTL_CONFIG_H
// The version is XYYZ, where X is major, YY is minor, and Z is patch (i.e. X.YY.Z)
#define _PSTL_VERSION 12000
#define _PSTL_VERSION 17000
#define _PSTL_VERSION_MAJOR (_PSTL_VERSION / 1000)
#define _PSTL_VERSION_MINOR ((_PSTL_VERSION % 1000) / 10)
#define _PSTL_VERSION_PATCH (_PSTL_VERSION % 10)
#if !defined(_PSTL_PAR_BACKEND_SERIAL) && !defined(_PSTL_PAR_BACKEND_TBB)
#if !defined(_PSTL_PAR_BACKEND_SERIAL) && !defined(_PSTL_PAR_BACKEND_TBB) && !defined(_PSTL_PAR_BACKEND_OPENMP)
# error "A parallel backend must be specified"
#endif
@ -53,13 +53,15 @@
// the actual GCC version on the system.
#define _PSTL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#if __clang__
#if defined(__clang__)
// according to clang documentation, version can be vendor specific
# define _PSTL_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
// Enable SIMD for compilers that support OpenMP 4.0
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \
#if (defined(_OPENMP) && _OPENMP >= 201307) || \
(defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1600) || \
(!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \
defined(__clang__)
# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd)
# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd)
@ -74,13 +76,13 @@
# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM)
#endif //Enable SIMD
#if (__INTEL_COMPILER)
#if defined(__INTEL_COMPILER)
# define _PSTL_PRAGMA_FORCEINLINE _PSTL_PRAGMA(forceinline)
#else
# define _PSTL_PRAGMA_FORCEINLINE
#endif
#if (__INTEL_COMPILER >= 1900)
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900
# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM))
# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM))
# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM))
@ -91,34 +93,50 @@
#endif
// Should be defined to 1 for environments with a vendor implementation of C++17 execution policies
#define _PSTL_CPP17_EXECUTION_POLICIES_PRESENT (_MSC_VER >= 1912)
#define _PSTL_CPP17_EXECUTION_POLICIES_PRESENT (_MSC_VER >= 1912 && _MSVC_LANG >= 201703L) || \
(_GLIBCXX_RELEASE >= 9 && __GLIBCXX__ >= 20190503 && __cplusplus >= 201703L)
#define _PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT \
(_MSC_VER >= 1900 || __cplusplus >= 201300L || __cpp_lib_robust_nonmodifying_seq_ops == 201304)
#define _PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT \
(_MSC_VER >= 1900 || __cplusplus >= 201402L || __cpp_lib_make_reverse_iterator == 201402)
#define _PSTL_CPP14_INTEGER_SEQUENCE_PRESENT (_MSC_VER >= 1900 || __cplusplus >= 201402L)
#define _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT \
(!__INTEL_COMPILER || __INTEL_COMPILER >= 1700) && (_MSC_FULL_VER >= 190023918 || __cplusplus >= 201402L)
#define _PSTL_EARLYEXIT_PRESENT (__INTEL_COMPILER >= 1800)
#define _PSTL_MONOTONIC_PRESENT (__INTEL_COMPILER >= 1800)
#if (__INTEL_COMPILER >= 1900 || !defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900 || _OPENMP >= 201307)
# define _PSTL_UDR_PRESENT 1
#else
# define _PSTL_UDR_PRESENT 0
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
__cplusplus >= 201300L || \
__cpp_lib_robust_nonmodifying_seq_ops == 201304
# define _PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT
#endif
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
__cplusplus >= 201402L || \
__cpp_lib_make_reverse_iterator == 201402
# define _PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT
#endif
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || __cplusplus >= 201402L
# define _PSTL_CPP14_INTEGER_SEQUENCE_PRESENT
#endif
#if (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1700) || \
(defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918) || \
__cplusplus >= 201402L
# define _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT
#endif
#define _PSTL_UDS_PRESENT (__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626)
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1800
# define _PSTL_EARLYEXIT_PRESENT
# define _PSTL_MONOTONIC_PRESENT
#endif
#if _PSTL_EARLYEXIT_PRESENT
#if (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900) || \
(!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \
(defined(_OPENMP) && _OPENMP >= 201307)
# define _PSTL_UDR_PRESENT
#endif
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626
# define _PSTL_UDS_PRESENT
#endif
#if defined(_PSTL_EARLYEXIT_PRESENT)
# define _PSTL_PRAGMA_SIMD_EARLYEXIT _PSTL_PRAGMA(omp simd early_exit)
#else
# define _PSTL_PRAGMA_SIMD_EARLYEXIT
#endif
#if _PSTL_MONOTONIC_PRESENT
#if defined(_PSTL_MONOTONIC_PRESENT)
# define _PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC(PRM) _PSTL_PRAGMA(omp ordered simd monotonic(PRM))
# define _PSTL_PRAGMA_SIMD_ORDERED_MONOTONIC_2ARGS(PRM1, PRM2) _PSTL_PRAGMA(omp ordered simd monotonic(PRM1, PRM2))
#else
@ -136,7 +154,7 @@
#define _PSTL_PRAGMA_DECLARE_REDUCTION(NAME, OP) \
_PSTL_PRAGMA(omp declare reduction(NAME:OP : omp_out(omp_in)) initializer(omp_priv = omp_orig))
#if (__INTEL_COMPILER >= 1600)
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1600
# define _PSTL_PRAGMA_VECTOR_UNALIGNED _PSTL_PRAGMA(vector unaligned)
#else
# define _PSTL_PRAGMA_VECTOR_UNALIGNED
@ -149,7 +167,7 @@
# define _PSTL_USE_NONTEMPORAL_STORES_IF_ALLOWED
#endif
#if _MSC_VER || __INTEL_COMPILER //the preprocessors don't type a message location
#if defined(_MSC_VER) || defined(__INTEL_COMPILER) // the preprocessors don't type a message location
# define _PSTL_PRAGMA_LOCATION __FILE__ ":" _PSTL_STRING(__LINE__) ": [Parallel STL message]: "
#else
# define _PSTL_PRAGMA_LOCATION " [Parallel STL message]: "
@ -157,7 +175,7 @@
#define _PSTL_PRAGMA_MESSAGE_IMPL(x) _PSTL_PRAGMA(message(_PSTL_STRING_CONCAT(_PSTL_PRAGMA_LOCATION, x)))
#if _PSTL_USAGE_WARNINGS
#if defined(_PSTL_USAGE_WARNINGS)
# define _PSTL_PRAGMA_MESSAGE(x) _PSTL_PRAGMA_MESSAGE_IMPL(x)
# define _PSTL_PRAGMA_MESSAGE_POLICIES(x) _PSTL_PRAGMA_MESSAGE_IMPL(x)
#else
@ -166,8 +184,13 @@
#endif
// broken macros
#define _PSTL_CPP11_STD_ROTATE_BROKEN ((__GLIBCXX__ && __GLIBCXX__ < 20150716) || (_MSC_VER && _MSC_VER < 1800))
#if (defined(__GLIBCXX__) && __GLIBCXX__ < 20150716) || \
(defined(_MSC_VER) && _MSC_VER < 1800)
# define _PSTL_CPP11_STD_ROTATE_BROKEN
#endif
#define _PSTL_ICC_18_OMP_SIMD_BROKEN (__INTEL_COMPILER == 1800)
#if defined(__INTEL_COMPILER) && __INTEL_COMPILER == 1800
# define _PSTL_ICC_18_OMP_SIMD_BROKEN
#endif
#endif /* _PSTL_CONFIG_H */

View file

@ -61,7 +61,7 @@ template <class _Index, class _DifferenceType, class _Pred>
bool
__simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept
{
#if _PSTL_EARLYEXIT_PRESENT
#if defined(_PSTL_EARLYEXIT_PRESENT)
_DifferenceType __i;
_PSTL_PRAGMA_VECTOR_UNALIGNED
_PSTL_PRAGMA_SIMD_EARLYEXIT
@ -74,7 +74,7 @@ __simd_or(_Index __first, _DifferenceType __n, _Pred __pred) noexcept
const _Index __last = __first + __n;
while (__last != __first)
{
__INT32_TYPE__ __flag = 1;
int32_t __flag = 1;
_PSTL_PRAGMA_SIMD_REDUCTION(& : __flag)
for (_DifferenceType __i = 0; __i < __block_size; ++__i)
if (__pred(*(__first + __i)))
@ -101,7 +101,7 @@ template <class _Index, class _DifferenceType, class _Compare>
_Index
__simd_first(_Index __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp) noexcept
{
#if _PSTL_EARLYEXIT_PRESENT
#if defined(_PSTL_EARLYEXIT_PRESENT)
_DifferenceType __i = __begin;
_PSTL_PRAGMA_VECTOR_UNALIGNED // Do not generate peel loop part
_PSTL_PRAGMA_SIMD_EARLYEXIT for (; __i < __end; ++__i)
@ -161,7 +161,7 @@ template <class _Index1, class _DifferenceType, class _Index2, class _Pred>
std::pair<_Index1, _Index2>
__simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pred) noexcept
{
#if _PSTL_EARLYEXIT_PRESENT
#if defined(_PSTL_EARLYEXIT_PRESENT)
_DifferenceType __i = 0;
_PSTL_PRAGMA_VECTOR_UNALIGNED
_PSTL_PRAGMA_SIMD_EARLYEXIT
@ -383,7 +383,7 @@ __simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, boo
typedef typename std::iterator_traits<_Index>::difference_type _DifferenceType;
_DifferenceType __i = 0;
#if _PSTL_EARLYEXIT_PRESENT
#if defined(_PSTL_EARLYEXIT_PRESENT)
//Some compiler versions fail to compile the following loop when iterators are used. Indices are used instead
const _DifferenceType __n = __last - __first - 1;
_PSTL_PRAGMA_VECTOR_UNALIGNED
@ -532,7 +532,7 @@ struct _Combiner
_BinaryOp* __bin_op; // Here is a pointer to function because of default ctor
_Combiner() : __value{}, __bin_op(nullptr) {}
_Combiner(const _Tp& value, const _BinaryOp* __bin_op) : __value(value), __bin_op(const_cast<_BinaryOp*>(__bin_op)) {}
_Combiner(const _Tp& __v, const _BinaryOp* __b) : __value(__v), __bin_op(const_cast<_BinaryOp*>(__b)) {}
_Combiner(const _Combiner& __obj) : __value{}, __bin_op(__obj.__bin_op) {}
void
@ -624,8 +624,8 @@ __simd_min_element(_ForwardIterator __first, _Size __n, _Compare __comp) noexcep
_Compare* __min_comp;
_ComplexType() : __min_val{}, __min_ind{}, __min_comp(nullptr) {}
_ComplexType(const _ValueType& __val, const _Compare* comp)
: __min_val(__val), __min_ind(0), __min_comp(const_cast<_Compare*>(comp))
_ComplexType(const _ValueType& val, const _Compare* comp)
: __min_val(val), __min_ind(0), __min_comp(const_cast<_Compare*>(comp))
{
}
_ComplexType(const _ComplexType& __obj)
@ -685,9 +685,9 @@ __simd_minmax_element(_ForwardIterator __first, _Size __n, _Compare __comp) noex
_Compare* __minmax_comp;
_ComplexType() : __min_val{}, __max_val{}, __min_ind{}, __max_ind{}, __minmax_comp(nullptr) {}
_ComplexType(const _ValueType& __min_val, const _ValueType& __max_val, const _Compare* comp)
: __min_val(__min_val), __max_val(__max_val), __min_ind(0), __max_ind(0),
__minmax_comp(const_cast<_Compare*>(comp))
_ComplexType(const _ValueType& __min, const _ValueType& __max, const _Compare* __comp)
: __min_val(__min), __max_val(__max), __min_ind(0), __max_ind(0),
__minmax_comp(const_cast<_Compare*>(__comp))
{
}
_ComplexType(const _ComplexType& __obj)

View file

@ -19,8 +19,8 @@ namespace __internal
{
template <typename _Fp>
typename std::result_of<_Fp()>::type
__except_handler(_Fp __f)
auto
__except_handler(_Fp __f) -> decltype(__f())
{
try
{
@ -44,8 +44,7 @@ __invoke_if(std::true_type, _Fp __f)
}
template <typename _Fp>
void
__invoke_if(std::false_type, _Fp __f)
void __invoke_if(std::false_type, _Fp)
{
}
@ -57,21 +56,20 @@ __invoke_if_not(std::false_type, _Fp __f)
}
template <typename _Fp>
void
__invoke_if_not(std::true_type, _Fp __f)
void __invoke_if_not(std::true_type, _Fp)
{
}
template <typename _F1, typename _F2>
typename std::result_of<_F1()>::type
__invoke_if_else(std::true_type, _F1 __f1, _F2 __f2)
auto
__invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1())
{
return __f1();
}
template <typename _F1, typename _F2>
typename std::result_of<_F2()>::type
__invoke_if_else(std::false_type, _F1 __f1, _F2 __f2)
auto
__invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2())
{
return __f2();
}
@ -87,23 +85,6 @@ struct __no_op
}
};
//! Logical negation of a predicate
template <typename _Pred>
class __not_pred
{
_Pred _M_pred;
public:
explicit __not_pred(_Pred __pred) : _M_pred(__pred) {}
template <typename... _Args>
bool
operator()(_Args&&... __args)
{
return !_M_pred(std::forward<_Args>(__args)...);
}
};
template <typename _Pred>
class __reorder_pred
{
@ -120,36 +101,6 @@ class __reorder_pred
}
};
//! "==" comparison.
/** Not called "equal" to avoid (possibly unfounded) concerns about accidental invocation via
argument-dependent name lookup by code expecting to find the usual std::equal. */
class __pstl_equal
{
public:
explicit __pstl_equal() {}
template <typename _Xp, typename _Yp>
bool
operator()(_Xp&& __x, _Yp&& __y) const
{
return std::forward<_Xp>(__x) == std::forward<_Yp>(__y);
}
};
//! "<" comparison.
class __pstl_less
{
public:
explicit __pstl_less() {}
template <typename _Xp, typename _Yp>
bool
operator()(_Xp&& __x, _Yp&& __y) const
{
return std::forward<_Xp>(__x) < std::forward<_Yp>(__y);
}
};
//! Like a polymorphic lambda for pred(...,value)
template <typename _Tp, typename _Predicate>
class __equal_value_by_pred

View file

@ -112,12 +112,12 @@ test_uninit_construct_by_type()
}
}
int32_t
int
main()
{
// for user-defined types
#if !_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN)
test_uninit_construct_by_type<Wrapper<int32_t>>();
test_uninit_construct_by_type<Wrapper<std::vector<std::string>>>();
#endif

View file

@ -81,16 +81,16 @@ struct test_uninitialized_copy_move
std::destroy_n(exec, out_first, n);
}
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN)
template <typename InputIterator, typename OutputIterator>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
size_t n, /*is_trivial<T>=*/std::true_type)
{
}
template <typename InputIterator, typename OutputIterator>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, size_t n, /*is_trivial<T>=*/std::true_type)
{
}
@ -101,8 +101,6 @@ struct test_uninitialized_copy_move
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first, size_t n,
/*is_trivial<T>=*/std::true_type)
{
typedef typename std::iterator_traits<InputIterator>::value_type T;
std::uninitialized_copy(exec, first, last, out_first);
EXPECT_TRUE(IsCheckValueCorrectness(first, out_first, n), "wrong uninitialized_copy");
std::destroy_n(exec, out_first, n);
@ -134,7 +132,7 @@ test_uninitialized_copy_move_by_type()
}
}
int32_t
int
main()
{
@ -143,8 +141,8 @@ main()
test_uninitialized_copy_move_by_type<float64_t>();
// for user-defined types
#if !_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && !_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN && \
!_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) && !defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) && \
!defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN)
test_uninitialized_copy_move_by_type<Wrapper<int8_t>>();
#endif

View file

@ -87,7 +87,7 @@ test_uninitialized_fill_destroy_by_type()
}
}
int32_t
int
main()
{
// for trivial types

View file

@ -30,18 +30,18 @@ using namespace TestUtils;
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename BiDirIt1, typename Size, typename Generator1, typename Generator2, typename Compare>
void
operator()(pstl::execution::unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2,
operator()(__pstl::execution::unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2,
Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
template <typename BiDirIt1, typename Size, typename Generator1, typename Generator2, typename Compare>
void
operator()(pstl::execution::parallel_unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2,
operator()(__pstl::execution::parallel_unsequenced_policy, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2,
BiDirIt1 last2, Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
@ -54,8 +54,6 @@ struct test_one_policy
operator()(Policy&& exec, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2, Size n, Size m,
Generator1 generator1, Generator2 generator2, Compare comp)
{
using T = typename std::iterator_traits<BiDirIt1>::value_type;
const BiDirIt1 mid1 = std::next(first1, m);
fill_data(first1, mid1, generator1);
fill_data(mid1, last1, generator2);
@ -72,8 +70,7 @@ struct test_one_policy
template <typename Policy, typename BiDirIt1, typename Size, typename Generator1, typename Generator2,
typename Compare>
typename std::enable_if<is_same_iterator_category<BiDirIt1, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt1 first1, BiDirIt1 last1, BiDirIt1 first2, BiDirIt1 last2, Size n, Size m,
Generator1 generator1, Generator2 generator2, Compare comp)
operator()(Policy&&, BiDirIt1, BiDirIt1, BiDirIt1, BiDirIt1, Size, Size, Generator1, Generator2, Compare)
{
}
};
@ -146,7 +143,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test_by_type<float64_t>([](int32_t i) { return -2 * i; }, [](int32_t i) { return -(2 * i + 1); },
@ -160,6 +157,13 @@ main()
test_algo_basic_single<int32_t>(run_for_rnd_bi<test_non_const<int32_t>>());
test_by_type<MemoryChecker>(
[](std::size_t idx){ return MemoryChecker{std::int32_t(idx * 2)}; },
[](std::size_t idx){ return MemoryChecker{std::int32_t(idx * 2 + 1)}; },
[](const MemoryChecker& val1, const MemoryChecker& val2){ return val1.value() == val2.value(); });
EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from inplace_merge: number of ctors calls < num of dtors calls");
EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from inplace_merge: number of ctors calls > num of dtors calls");
std::cout << done() << std::endl;
return 0;
}

View file

@ -23,6 +23,7 @@
#else
#include <execution>
#include <algorithm>
#include <functional>
#endif // PSTL_STANDALONE_TESTS
#include "pstl/test_utils.h"
@ -58,8 +59,7 @@ struct test_merge
void
operator()(Policy&& exec, std::reverse_iterator<InputIterator1> first1, std::reverse_iterator<InputIterator1> last1,
std::reverse_iterator<InputIterator2> first2, std::reverse_iterator<InputIterator2> last2,
std::reverse_iterator<OutputIterator> out_first, std::reverse_iterator<OutputIterator> out_last,
Compare comp)
std::reverse_iterator<OutputIterator> out_first, std::reverse_iterator<OutputIterator> out_last, Compare)
{
using namespace std;
typedef typename std::iterator_traits<std::reverse_iterator<InputIterator1>>::value_type T;
@ -106,13 +106,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test_merge_by_type<int32_t>([](size_t v) { return (v % 2 == 0 ? v : -v) * 3; }, [](size_t v) { return v * 2; });
test_merge_by_type<float64_t>([](size_t v) { return float64_t(v); }, [](size_t v) { return float64_t(v - 100); });
#if !_PSTL_ICC_16_17_TEST_64_TIMEOUT
#if !defined(_PSTL_ICC_16_17_TEST_64_TIMEOUT)
test_merge_by_type<Wrapper<int16_t>>([](size_t v) { return Wrapper<int16_t>(v % 100); },
[](size_t v) { return Wrapper<int16_t>(v % 10); });
#endif

View file

@ -29,7 +29,7 @@ using namespace TestUtils;
struct run_copy_if
{
#if _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
#if defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN) // dummy specializations to skip testing in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
@ -131,7 +131,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<float64_t>(-666.0, [](const float64_t& x) { return x * x <= 1024; },
@ -140,12 +140,12 @@ main()
test<int32_t>(-666, [](const int32_t& x) { return x != 42; },
[](size_t j) { return ((j + 1) % 5 & 2) != 0 ? int32_t(j + 1) : 42; });
#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN)
test<Number>(Number(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
#endif
#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<int32_t>(-666, [](const int32_t& x) { return true; }, [](size_t j) { return j; }, false);
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
test<int32_t>(-666, [](const int32_t&) { return true; }, [](size_t j) { return j; }, false);
#endif
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const>());

View file

@ -31,11 +31,11 @@ using namespace TestUtils;
struct run_copy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
@ -43,7 +43,7 @@ struct run_copy
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size, typename T>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, T trash)
{
@ -54,8 +54,7 @@ struct run_copy
typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2, Size size, Size n, T trash)
{
// Cleaning
std::fill_n(expected_first, size, trash);
@ -84,11 +83,11 @@ template <typename T>
struct run_move
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
{
@ -96,7 +95,7 @@ struct run_move
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, T trash)
{
@ -106,8 +105,7 @@ struct run_move
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, T trash)
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2, Size size, Size, T trash)
{
// Cleaning
std::fill_n(expected_first, size, trash);
@ -127,11 +125,11 @@ template <typename T>
struct run_move<Wrapper<T>>
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, Wrapper<T> trash)
{
@ -139,7 +137,7 @@ struct run_move<Wrapper<T>>
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, Size size, Size n, Wrapper<T> trash)
{
@ -149,8 +147,7 @@ struct run_move<Wrapper<T>>
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size size,
Size n, Wrapper<T> trash)
OutputIterator out_last, OutputIterator2, OutputIterator2, Size size, Size, Wrapper<T> trash)
{
// Cleaning
std::fill_n(out_first, size, trash);
@ -194,13 +191,13 @@ test(T trash, Convert convert)
}
}
int32_t
int
main()
{
test<int32_t>(-666, [](size_t j) { return int32_t(j); });
test<Wrapper<float64_t>>(Wrapper<float64_t>(-666.0), [](int32_t j) { return Wrapper<float64_t>(j); });
#if !_PSTL_ICC_16_17_TEST_64_TIMEOUT
#if !defined(_PSTL_ICC_16_17_TEST_64_TIMEOUT)
test<float64_t>(-666.0, [](size_t j) { return float64_t(j); });
test<Number>(Number(42, OddTag()), [](int32_t j) { return Number(j, OddTag()); });
#endif

View file

@ -84,14 +84,14 @@ template <typename T>
void
test_fill_by_type(std::size_t n)
{
Sequence<T> in(n, [](std::size_t v) -> T { return T(0); }); //fill with zeros
Sequence<T> in(n, [](std::size_t) -> T { return T(0); }); //fill with zeros
T value = -1;
invoke_on_all_policies(test_fill(), in.begin(), in.end(), value);
invoke_on_all_policies(test_fill_n(), in.begin(), n, value);
}
int32_t
int
main()
{

View file

@ -57,17 +57,18 @@ struct test_generate
{
Generator_count<T> g;
generate(exec, first, last, g);
EXPECT_TRUE(std::count(first, last, g.default_value()) == n, "generate wrong result for generate");
Size count = std::count(first, last, g.default_value());
EXPECT_TRUE(count == n, "generate wrong result for generate");
std::fill(first, last, T(0));
}
{
Generator_count<T> g;
const auto m = n / 2;
auto last = generate_n(exec, first, m, g);
EXPECT_TRUE(std::count(first, last, g.default_value()) == m && last == std::next(first, m),
"generate_n wrong result for generate_n");
std::fill(first, last, T(0));
auto actual_last = generate_n(exec, first, m, g);
Size count = std::count(first, actual_last, g.default_value());
EXPECT_TRUE(count == m && actual_last == std::next(first, m), "generate_n wrong result for generate_n");
std::fill(first, actual_last, T(0));
}
}
};
@ -78,7 +79,7 @@ test_generate_by_type()
{
for (size_t n = 0; n <= 100000; n = n < 16 ? n + 1 : size_t(3.1415 * n))
{
Sequence<T> in(n, [](size_t v) -> T { return T(0); }); //fill by zero
Sequence<T> in(n, [](size_t) -> T { return T(0); }); //fill by zero
invoke_on_all_policies(test_generate(), in.begin(), in.end(), in.size());
}
@ -98,7 +99,7 @@ struct test_non_const
}
};
int32_t
int
main()
{

View file

@ -29,16 +29,16 @@ using namespace TestUtils;
struct test_one_policy
{
//dummy specialization by policy type, in case of broken configuration
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN)
template <typename Iterator1, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
operator()(__pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
{
}
template <typename Iterator1, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred)
{
}
#endif
@ -92,14 +92,14 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<float64_t>([](const float64_t x) { return x < 0; });
test<int32_t>([](const int32_t x) { return x > 1000; });
test<uint16_t>([](const uint16_t x) { return x % 5 < 3; });
#if !_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN && !_PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN
test<LocalWrapper<float64_t>>([](const LocalWrapper<float64_t>& x) { return true; });
#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN) && !defined(_PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN)
test<LocalWrapper<float64_t>>([](const LocalWrapper<float64_t>&) { return true; });
#endif
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());

View file

@ -66,15 +66,15 @@ is_equal(Iterator first, Iterator last, Iterator d_first)
template <typename Iterator>
typename std::enable_if<!std::is_trivial<typename std::iterator_traits<Iterator>::value_type>::value, bool>::type
is_equal(Iterator first, Iterator last, Iterator d_first)
is_equal(Iterator, Iterator, Iterator)
{
return true;
}
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specializations to skip testing in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specializations to skip testing in case of broken configuration
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::unsequenced_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
@ -88,7 +88,7 @@ struct test_one_policy
BiDirIt exp_last, Size n, UnaryOp unary_op, Generator generator)
{
}
#elif _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN //dummy specializations to skip testing in case of broken configuration
#elif defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN) //dummy specializations to skip testing in case of broken configuration
template <typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
void
operator()(__pstl::execution::parallel_policy, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last,
@ -106,8 +106,8 @@ struct test_one_policy
template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
typename std::enable_if<!is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
UnaryOp unary_op, Generator generator)
operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size, UnaryOp unary_op,
Generator generator)
{
// partition
{
@ -130,8 +130,7 @@ struct test_one_policy
}
template <typename Policy, typename BiDirIt, typename Size, typename UnaryOp, typename Generator>
typename std::enable_if<is_same_iterator_category<BiDirIt, std::forward_iterator_tag>::value, void>::type
operator()(Policy&& exec, BiDirIt first, BiDirIt last, BiDirIt exp_first, BiDirIt exp_last, Size n,
UnaryOp unary_op, Generator generator)
operator()(Policy&&, BiDirIt, BiDirIt, BiDirIt, BiDirIt, Size, UnaryOp, Generator)
{
}
};
@ -170,10 +169,10 @@ struct test_non_const
}
};
int32_t
int
main()
{
#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
test_by_type<int32_t>([](int32_t i) { return i; }, [](int32_t) { return true; });
#endif
test_by_type<float64_t>([](int32_t i) { return -i; }, [](const float64_t x) { return x < 0; });

View file

@ -35,24 +35,23 @@ struct test_partition_copy
template <typename Policy, typename InputIterator, typename OutputIterator, typename OutputIterator2,
typename UnaryOp>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator true_first,
OutputIterator true_last, OutputIterator2 false_first, OutputIterator2 false_last, UnaryOp unary_op)
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator true_first, OutputIterator,
OutputIterator2 false_first, OutputIterator2, UnaryOp unary_op)
{
auto actual_ret = std::partition_copy(exec, first, last, true_first, false_first, unary_op);
EXPECT_TRUE(std::distance(true_first, actual_ret.first) == std::count_if(first, last, unary_op),
"partition_copy has wrong effect from true sequence");
EXPECT_TRUE(std::distance(false_first, actual_ret.second) ==
std::count_if(first, last, __pstl::__internal::__not_pred<UnaryOp>(unary_op)),
EXPECT_TRUE(std::distance(false_first, actual_ret.second) == std::count_if(first, last, std::not_fn(unary_op)),
"partition_copy has wrong effect from false sequence");
}
//dummy specialization by iterator type and policy type, in case of broken configuration
#if _PSTL_ICC_1800_TEST_MONOTONIC_RELEASE_64_BROKEN
#if defined(_PSTL_ICC_1800_TEST_MONOTONIC_RELEASE_64_BROKEN)
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
void
operator()(pstl::execution::unsequenced_policy, std::reverse_iterator<InputIterator> first,
operator()(__pstl::execution::unsequenced_policy, std::reverse_iterator<InputIterator> first,
std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
OutputIterator2 false_last, UnaryOp unary_op)
@ -60,7 +59,7 @@ struct test_partition_copy
}
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename UnaryOp>
void
operator()(pstl::execution::parallel_unsequenced_policy, std::reverse_iterator<InputIterator> first,
operator()(__pstl::execution::parallel_unsequenced_policy, std::reverse_iterator<InputIterator> first,
std::reverse_iterator<InputIterator> last, std::reverse_iterator<OutputIterator> true_first,
std::reverse_iterator<OutputIterator> true_last, std::reverse_iterator<OutputIterator2> false_first,
OutputIterator2 false_last, UnaryOp unary_op)
@ -106,13 +105,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>([](const int32_t value) { return value % 2; });
#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<int32_t>([](const int32_t value) { return true; });
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
test<int32_t>([](const int32_t) { return true; });
#endif
test<float64_t>([](const float64_t value) { return value > 2 << 6; });

View file

@ -29,18 +29,18 @@ using namespace TestUtils;
struct run_remove
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename Size, typename T>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
const T& value)
{
}
template <typename InputIterator, typename OutputIterator, typename Size, typename T>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
OutputIterator expected_last, Size n, const T& value)
{
@ -67,18 +67,18 @@ struct run_remove
struct run_remove_if
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
Predicate pred)
{
}
template <typename InputIterator, typename OutputIterator, typename Size, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last,
OutputIterator out_first, OutputIterator out_last, OutputIterator expected_first,
OutputIterator expected_last, Size n, Predicate pred)
{
@ -138,11 +138,11 @@ struct test_non_const
}
};
int32_t
int
main()
{
#if !_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN
test<int32_t>(666, 42, [](int32_t val) { return true; }, [](size_t j) { return j; });
#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN)
test<int32_t>(666, 42, [](int32_t) { return true; }, [](size_t j) { return j; });
#endif
test<int32_t>(666, 2001, [](const int32_t& val) { return val != 2001; },
@ -150,13 +150,20 @@ main()
test<float64_t>(-666.0, 8.5, [](const float64_t& val) { return val != 8.5; },
[](size_t j) { return ((j + 1) % 7 & 2) != 0 ? 8.5 : float64_t(j % 32 + j); });
#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN)
test<Number>(Number(-666, OddTag()), Number(42, OddTag()), IsMultiple(3, OddTag()),
[](int32_t j) { return Number(j, OddTag()); });
#endif
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const>());
test<MemoryChecker>(MemoryChecker{0}, MemoryChecker{1},
[](const MemoryChecker& val){ return val.value() == 1; },
[](std::size_t idx){ return MemoryChecker{std::int32_t(idx % 3 == 0)}; }
);
EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from remove,remove_if: number of ctors calls < num of dtors calls");
EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from remove,remove_if: number of ctors calls > num of dtors calls");
std::cout << done() << std::endl;
return 0;
}

View file

@ -33,16 +33,17 @@ struct run_remove_copy
typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
const T& value, T trash)
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2, Size n, const T& value,
T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
std::fill_n(out_first, n, trash);
// Run copy_if
auto i = remove_copy(first, last, expected_first, value);
auto k = remove_copy(exec, first, last, out_first, value);
auto i = std::remove_copy(first, last, expected_first, value);
(void)i;
auto k = std::remove_copy(exec, first, last, out_first, value);
EXPECT_EQ_N(expected_first, out_first, n, "wrong remove_copy effect");
for (size_t j = 0; j < GuardSize; ++j)
{
@ -84,7 +85,7 @@ test(T trash, const T& value, Convert convert, bool check_weakness = true)
}
}
int32_t
int
main()
{

View file

@ -31,9 +31,10 @@ struct copy_int
{
int32_t value;
int32_t copied_times = 0;
explicit copy_int(int32_t val = 0) { value = val; }
constexpr explicit copy_int(int32_t val = 0) : value(val) {}
constexpr copy_int(copy_int const& other) : value(other.value), copied_times(other.copied_times) { }
copy_int&
constexpr copy_int&
operator=(const copy_int& other)
{
if (&other == this)
@ -46,7 +47,7 @@ struct copy_int
return *this;
}
bool
constexpr bool
operator==(const copy_int& other) const
{
return (value == other.value);
@ -112,13 +113,13 @@ test(Pred pred)
const std::size_t max_len = 100000;
const T1 value = T1(0);
const T1 new_value = T1(666);
static constexpr T1 value = T1(0);
static constexpr T1 new_value = T1(666);
Sequence<T2> expected(max_len);
Sequence<T2> actual(max_len);
Sequence<T2> data(max_len, [&value](std::size_t i) {
Sequence<T2> data(max_len, [](std::size_t i) {
if (i % 3 == 2)
{
return T1(i);
@ -153,7 +154,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t, float32_t>(__pstl::__internal::__equal_value<int32_t>(666));

View file

@ -34,8 +34,8 @@ struct test_replace_copy
typename Predicate, typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
Predicate pred, const T& old_value, const T& new_value, T trash)
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2, Size n, Predicate pred,
const T& old_value, const T& new_value, T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
@ -91,7 +91,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
@ -101,7 +101,7 @@ main()
test<int32_t>(-666, 42, 99, [](const int32_t& x) { return x != 42; },
[](size_t j) { return ((j + 1) % 5 & 2) != 0 ? 42 : -1 - int32_t(j); });
#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN)
test<Number>(Number(42, OddTag()), Number(2001, OddTag()), Number(2017, OddTag()), IsMultiple(3, OddTag()),
[](int32_t j) { return ((j + 1) % 3 & 2) != 0 ? Number(2001, OddTag()) : Number(j, OddTag()); });
#endif

View file

@ -83,8 +83,8 @@ struct compare<wrapper<T>>
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specializations to skip testing in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specializations to skip testing in case of broken configuration
template <typename Iterator, typename Size>
void
operator()(__pstl::execution::unsequenced_policy, Iterator data_b, Iterator data_e, Iterator actual_b,
@ -123,10 +123,10 @@ struct test_one_policy
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
!std::is_same<ExecutionPolicy, std::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value,
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
check_move(ExecutionPolicy&&, Iterator b, Iterator e, Size shift)
{
bool result = all_of(b, e, [](wrapper<float32_t>& a) {
bool temp = a.move_count > 0;
@ -139,10 +139,10 @@ struct test_one_policy
template <typename ExecutionPolicy, typename Iterator, typename Size>
typename std::enable_if<
!(is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value &&
!std::is_same<ExecutionPolicy, __pstl::execution::sequenced_policy>::value &&
!std::is_same<ExecutionPolicy, std::execution::sequenced_policy>::value &&
std::is_same<typename std::iterator_traits<Iterator>::value_type, wrapper<float32_t>>::value),
bool>::type
check_move(ExecutionPolicy&& exec, Iterator b, Iterator e, Size shift)
check_move(ExecutionPolicy&&, Iterator, Iterator, Size)
{
return true;
}
@ -171,7 +171,7 @@ test()
}
}
int32_t
int
main()
{
test<int32_t>();

View file

@ -78,17 +78,17 @@ struct comparator
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, std::size_t shift)
{
}
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, std::size_t shift)
{
}
@ -142,7 +142,7 @@ test()
}
}
int32_t
int
main()
{
test<int32_t, int8_t>();

View file

@ -61,7 +61,7 @@ template <typename T>
struct check_swap
{
bool
operator()(T& a)
operator()(T&)
{
return true;
}
@ -129,7 +129,7 @@ test()
}
}
int32_t
int
main()
{
test<wrapper<uint16_t>>();

View file

@ -70,10 +70,11 @@ struct test_one_policy
template <typename Policy, typename InputIterator1, typename InputIterator2, typename OutputIterator,
typename BinaryOp>
void
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
OutputIterator out_first, OutputIterator out_last, BinaryOp op)
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2,
OutputIterator out_first, OutputIterator, BinaryOp op)
{
auto orrr = std::transform(exec, first1, last1, first2, out_first, op);
auto result = std::transform(exec, first1, last1, first2, out_first, op);
(void)result;
check_and_reset(first1, last1, first2, out_first);
}
};
@ -87,7 +88,7 @@ test(Predicate pred)
Sequence<In1> in1(n, [](size_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; });
Sequence<In2> in2(n, [](size_t k) { return k % 7 != 2 ? 5 * k - 5 : 0; });
Sequence<Out> out(n, [](size_t k) { return -1; });
Sequence<Out> out(n, [](size_t) { return -1; });
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.end(), in2.begin(), in2.end(), out.begin(),
out.end(), pred);
@ -110,7 +111,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
//const operator()

View file

@ -83,7 +83,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t, int32_t>();

View file

@ -29,32 +29,32 @@ using namespace TestUtils;
struct run_unique
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename ForwardIt, typename Generator>
void
operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
operator()(__pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, Generator generator)
{
}
template <typename ForwardIt, typename Generator>
void
operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
operator()(__pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, Generator generator)
{
}
template <typename ForwardIt, typename BinaryPred, typename Generator>
void
operator()(pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
operator()(__pstl::execution::unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, BinaryPred pred, Generator generator)
{
}
template <typename ForwardIt, typename BinaryPred, typename Generator>
void
operator()(pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
operator()(__pstl::execution::parallel_unsequenced_policy, ForwardIt first1, ForwardIt last1, ForwardIt first2,
ForwardIt last2, BinaryPred pred, Generator generator)
{
}
@ -144,10 +144,10 @@ struct test_non_const
}
};
int32_t
int
main()
{
#if !_PSTL_ICC_16_17_18_TEST_UNIQUE_MASK_RELEASE_BROKEN
#if !defined(_PSTL_ICC_16_17_18_TEST_UNIQUE_MASK_RELEASE_BROKEN)
test<int32_t>([](size_t j) { return j / 3; },
[](const int32_t& val1, const int32_t& val2) { return val1 * val1 == val2 * val2; });
test<float64_t>([](size_t) { return float64_t(1); },
@ -160,6 +160,12 @@ main()
test_algo_basic_single<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
test<MemoryChecker>(
[](std::size_t idx){ return MemoryChecker{std::int32_t(idx / 3)}; },
[](const MemoryChecker& val1, const MemoryChecker& val2){ return val1.value() == val2.value(); });
EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from unique: number of ctors calls < num of dtors calls");
EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from unique: number of ctors calls > num of dtors calls");
std::cout << done() << std::endl;
return 0;
}

View file

@ -29,7 +29,7 @@ using namespace TestUtils;
struct run_unique_copy
{
#if _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN // dummy specializations to skip testing in case of broken configuration
#if defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN) // dummy specializations to skip testing in case of broken configuration
template <typename InputIterator, typename OutputIterator, typename OutputIterator2, typename Size,
typename Predicate, typename T>
void
@ -53,8 +53,8 @@ struct run_unique_copy
typename Predicate, typename T>
void
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2 expected_last, Size n,
Predicate pred, T trash)
OutputIterator out_last, OutputIterator2 expected_first, OutputIterator2, Size n, Predicate pred,
T trash)
{
// Cleaning
std::fill_n(expected_first, n, trash);
@ -123,17 +123,17 @@ struct test_non_const
}
};
int32_t
main(int32_t argc, char* argv[])
int
main()
{
test<Number>(Number(42, OddTag()), std::equal_to<Number>(),
[](int32_t j) { return Number(3 * j / 13 ^ (j & 8), OddTag()); });
test<float32_t>(float32_t(42), std::equal_to<float32_t>(),
[](int32_t j) { return float32_t(5 * j / 23 ^ (j / 7)); });
#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<float32_t>(float32_t(42), [](float32_t x, float32_t y) { return false; },
[](int32_t j) { return float32_t(j); }, false);
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
test<float32_t>(float32_t(42), [](float32_t, float32_t) { return false; }, [](int32_t j) { return float32_t(j); },
false);
#endif
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());

View file

@ -50,13 +50,13 @@ test_adjacent_find_by_type()
{
size_t counts[] = {2, 3, 500};
for (int32_t c = 0; c < const_size(counts); ++c)
for (size_t c = 0; c < const_size(counts); ++c)
{
for (int32_t e = 0; e < (counts[c] >= 64 ? 64 : (counts[c] == 2 ? 1 : 2)); ++e)
for (size_t e = 0; e < (counts[c] >= 64 ? 64 : (counts[c] == 2 ? 1 : 2)); ++e)
{
Sequence<T> in(counts[c], [](int32_t v) -> T { return T(v); }); //fill 0...n
in[e] = in[e + 1] = -1; //make an adjacent pair
Sequence<T> in(counts[c], [](size_t v) -> T { return T(v); }); //fill 0...n
in[e] = in[e + 1] = -1; //make an adjacent pair
auto i = std::adjacent_find(in.cbegin(), in.cend(), std::equal_to<T>());
EXPECT_TRUE(i == in.cbegin() + e, "std::adjacent_find returned wrong result");
@ -67,9 +67,9 @@ test_adjacent_find_by_type()
}
//special cases: size=0, size=1;
for (int32_t expect = 0; expect < 1; ++expect)
for (size_t expect = 0; expect < 1; ++expect)
{
Sequence<T> in(expect, [](int32_t v) -> T { return T(v); }); //fill 0...n
Sequence<T> in(expect, [](size_t v) -> T { return T(v); }); //fill 0...n
auto i = std::adjacent_find(in.cbegin(), in.cend(), std::equal_to<T>());
EXPECT_TRUE(i == in.cbegin() + expect, "std::adjacent_find returned wrong result");
@ -109,7 +109,7 @@ struct test_non_const
}
};
int32_t
int
main()
{

View file

@ -69,7 +69,7 @@ test(size_t bits)
{
// Sequence of odd values
Sequence<T> in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); });
Sequence<T> in(n, [n, bits](size_t) { return T(2 * HashBits(n, bits - 1) ^ 1); });
// Even value, or false when T is bool.
T spike(2 * HashBits(n, bits - 1));
@ -108,13 +108,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(8 * sizeof(int32_t));
test<uint16_t>(8 * sizeof(uint16_t));
test<float64_t>(53);
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN)
test<bool>(1);
#endif

View file

@ -55,7 +55,7 @@ test(size_t bits)
{
// Sequence of odd values
Sequence<T> in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); });
Sequence<T> in(n, [n, bits](size_t) { return T(2 * HashBits(n, bits - 1) ^ 1); });
// Even value, or false when T is bool.
T spike(2 * HashBits(n, bits - 1));
@ -94,13 +94,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(8 * sizeof(int32_t));
test<uint16_t>(8 * sizeof(uint16_t));
test<float64_t>(53);
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN)
test<bool>(1);
#endif

View file

@ -98,12 +98,12 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(42, IsEqual<int32_t>(50, OddTag()), [](int32_t j) { return j; });
#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN
test<int32_t>(42, [](const int32_t& x) { return true; }, [](int32_t j) { return j; });
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN)
test<int32_t>(42, [](const int32_t&) { return true; }, [](int32_t j) { return j; });
#endif
test<float64_t>(42, IsEqual<float64_t>(50, OddTag()), [](int32_t j) { return float64_t(j); });
test<Number>(Number(42, OddTag()), IsEqual<Number>(Number(50, OddTag()), OddTag()),

View file

@ -30,10 +30,10 @@ using namespace TestUtils;
struct UserType
{
size_t key;
float32_t f;
float64_t d;
int32_t i;
size_t key;
bool
operator()(UserType a, UserType b)
@ -157,14 +157,14 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(8 * sizeof(int32_t));
test<uint16_t>(8 * sizeof(uint16_t));
test<float64_t>(53);
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN)
test<bool>(1);
#endif
test<UserType>(256);

View file

@ -29,16 +29,16 @@ using namespace TestUtils;
struct test_find
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator, typename Value>
void
operator()(pstl::execution::unsequenced_policy, Iterator first, Iterator last, Value value)
operator()(__pstl::execution::unsequenced_policy, Iterator first, Iterator last, Value value)
{
}
template <typename Iterator, typename Value>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Value value)
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Value value)
{
}
#endif
@ -88,12 +88,12 @@ class Weird
Weird(int32_t val, OddTag) : value(val, OddTag()) {}
};
int32_t
int
main()
{
// Note that the "hit" and "miss" functions here avoid overflow issues.
test<Number>(Weird(42, OddTag()), [](int32_t j) { return Number(42, OddTag()); }, // hit
[](int32_t j) { return Number(j == 42 ? 0 : j, OddTag()); }); // miss
test<Number>(Weird(42, OddTag()), [](int32_t) { return Number(42, OddTag()); }, // hit
[](int32_t j) { return Number(j == 42 ? 0 : j, OddTag()); }); // miss
// Test with value that is equal to two different bit patterns (-0.0 and 0.0)
test<float32_t>(-0.0, [](int32_t j) { return j & 1 ? 0.0 : -0.0; }, // hit

View file

@ -26,105 +26,77 @@
using namespace TestUtils;
struct test_one_policy
struct test_find
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2, typename Predicate>
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator, typename Value>
void
operator()(pstl::execution::unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
Predicate pred)
operator()(__pstl::execution::unsequenced_policy, Iterator first, Iterator last, Value value)
{
}
template <typename Iterator1, typename Iterator2, typename Predicate>
template <typename Iterator, typename Value>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
Predicate pred)
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Value value)
{
}
#endif
template <typename ExecutionPolicy, typename Iterator1, typename Iterator2, typename Predicate>
template <typename Policy, typename Iterator, typename Value>
void
operator()(ExecutionPolicy&& exec, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub, Predicate pred)
operator()(Policy&& exec, Iterator first, Iterator last, Value value)
{
using namespace std;
// For find_end
{
auto expected = find_end(b, e, bsub, esub, pred);
auto actual = find_end(exec, b, e, bsub, esub);
EXPECT_TRUE(actual == expected, "wrong return result from find_end");
actual = find_end(exec, b, e, bsub, esub, pred);
EXPECT_TRUE(actual == expected, "wrong return result from find_end with a predicate");
}
// For search
{
auto expected = search(b, e, bsub, esub, pred);
auto actual = search(exec, b, e, bsub, esub);
EXPECT_TRUE(actual == expected, "wrong return result from search");
actual = search(exec, b, e, bsub, esub, pred);
EXPECT_TRUE(actual == expected, "wrong return result from search with a predicate");
}
auto i = std::find(first, last, value);
auto j = find(exec, first, last, value);
EXPECT_TRUE(i == j, "wrong return value from find");
}
};
template <typename T>
template <typename T, typename Value, typename Hit, typename Miss>
void
test(const std::size_t bits)
test(Value value, Hit hit, Miss miss)
{
const std::size_t max_n1 = 1000;
const std::size_t max_n2 = (max_n1 * 10) / 8;
Sequence<T> in(max_n1, [max_n1, bits](std::size_t) { return T(2 * HashBits(max_n1, bits - 1) ^ 1); });
Sequence<T> sub(max_n2, [max_n1, bits](std::size_t) { return T(2 * HashBits(max_n1, bits - 1)); });
for (std::size_t n1 = 0; n1 <= max_n1; n1 = n1 <= 16 ? n1 + 1 : size_t(3.1415 * n1))
// Try sequences of various lengths.
for (size_t n = 0; n <= 100000; n = n <= 16 ? n + 1 : size_t(3.1415 * n))
{
std::size_t sub_n[] = {0, 1, 3, n1, (n1 * 10) / 8};
std::size_t res[] = {0, 1, n1 / 2, n1};
for (auto n2 : sub_n)
Sequence<T> in(n, [&](size_t k) -> T { return miss(n ^ k); });
// Try different find positions, including not found.
// By going backwards, we can add extra matches that are *not* supposed to be found.
// The decreasing exponential gives us O(n) total work for the loop since each find takes O(m) time.
for (size_t m = n; m > 0; m *= 0.6)
{
for (auto r : res)
{
std::size_t i = r, isub = 0;
for (; i < n1 && isub < n2; ++i, ++isub)
in[i] = sub[isub];
invoke_on_all_policies(test_one_policy(), in.begin(), in.begin() + n1, sub.begin(), sub.begin() + n2,
std::equal_to<T>());
invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, sub.cbegin(),
sub.cbegin() + n2, std::equal_to<T>());
}
if (m < n)
in[m] = hit(n ^ m);
invoke_on_all_policies(test_find(), in.begin(), in.end(), value);
invoke_on_all_policies(test_find(), in.cbegin(), in.cend(), value);
}
}
}
template <typename T>
struct test_non_const
// Type defined for sake of checking that std::find works with asymmetric ==.
class Weird
{
template <typename Policy, typename FirstIterator, typename SecondInterator>
void
operator()(Policy&& exec, FirstIterator first_iter, SecondInterator second_iter)
Number value;
public:
friend bool
operator==(Number x, Weird y)
{
invoke_if(exec, [&]() {
find_end(exec, first_iter, first_iter, second_iter, second_iter, non_const(std::equal_to<T>()));
search(exec, first_iter, first_iter, second_iter, second_iter, non_const(std::equal_to<T>()));
});
return x == y.value;
}
Weird(int32_t val, OddTag) : value(val, OddTag()) {}
};
int32_t
int
main()
{
test<int32_t>(8 * sizeof(int32_t));
test<uint16_t>(8 * sizeof(uint16_t));
test<float64_t>(53);
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
test<bool>(1);
#endif
// Note that the "hit" and "miss" functions here avoid overflow issues.
test<Number>(Weird(42, OddTag()), [](int32_t) { return Number(42, OddTag()); }, // hit
[](int32_t j) { return Number(j == 42 ? 0 : j, OddTag()); }); // miss
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
// Test with value that is equal to two different bit patterns (-0.0 and 0.0)
test<float32_t>(-0.0, [](int32_t j) { return j & 1 ? 0.0 : -0.0; }, // hit
[](int32_t j) { return j == 0 ? ~j : j; }); // miss
std::cout << done() << std::endl;
return 0;

View file

@ -28,17 +28,17 @@ using namespace TestUtils;
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
operator()(__pstl::execution::unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
Predicate pred)
{
}
template <typename Iterator1, typename Iterator2, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 b, Iterator1 e, Iterator2 bsub, Iterator2 esub,
Predicate pred)
{
}
@ -66,8 +66,8 @@ test(Predicate pred)
const std::size_t max_n1 = 1000;
const std::size_t max_n2 = (max_n1 * 10) / 8;
Sequence<T> in1(max_n1, [](std::size_t k) { return T(1); });
Sequence<T> in2(max_n2, [](std::size_t k) { return T(0); });
Sequence<T> in1(max_n1, [](std::size_t) { return T(1); });
Sequence<T> in2(max_n2, [](std::size_t) { return T(0); });
for (std::size_t n1 = 0; n1 <= max_n1; n1 = n1 <= 16 ? n1 + 1 : size_t(3.1415 * n1))
{
std::size_t sub_n[] = {0, 1, n1 / 3, n1, (n1 * 10) / 8};
@ -106,7 +106,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(std::equal_to<int32_t>());

View file

@ -29,17 +29,17 @@ using namespace TestUtils;
struct test_find_if
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator, typename Predicate, typename NotPredicate>
void
operator()(pstl::execution::unsequenced_policy, Iterator first, Iterator last, Predicate pred,
operator()(__pstl::execution::unsequenced_policy, Iterator first, Iterator last, Predicate pred,
NotPredicate not_pred)
{
}
template <typename Iterator, typename Predicate, typename NotPredicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Predicate pred,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Predicate pred,
NotPredicate not_pred)
{
}
@ -97,10 +97,10 @@ struct test_non_const
}
};
int32_t
int
main()
{
#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN)
// Note that the "hit" and "miss" functions here avoid overflow issues.
test<Number>(IsMultiple(5, OddTag()), [](int32_t j) { return Number(j - j % 5, OddTag()); }, // hit
[](int32_t j) { return Number(j % 5 == 0 ? j ^ 1 : j, OddTag()); }); // miss

View file

@ -62,7 +62,7 @@ struct test_one_policy
EXPECT_EQ_N(expected_first, first, n, "wrong effect from for_each");
// Try for_each_n
std::for_each_n(__pstl::execution::seq, expected_first, n, Flip<T>(1));
std::for_each_n(std::execution::seq, expected_first, n, Flip<T>(1));
for_each_n(exec, first, n, Flip<T>(1));
EXPECT_EQ_N(expected_first, first, n, "wrong effect from for_each_n");
}
@ -96,7 +96,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>();

View file

@ -53,7 +53,7 @@ struct test_mismatch
using namespace std;
typedef typename iterator_traits<Iterator1>::value_type T;
{
const auto expected = mismatch(__pstl::execution::seq, first1, last1, first2, last2, std::equal_to<T>());
const auto expected = mismatch(std::execution::seq, first1, last1, first2, last2, std::equal_to<T>());
const auto res1 = mismatch(exec, first1, last1, first2, last2, std::equal_to<T>());
EXPECT_TRUE(expected == res1, "wrong return result from mismatch");
const auto res2 = mismatch(exec, first1, last1, first2, last2);
@ -129,7 +129,7 @@ struct test_non_const
}
};
int32_t
int
main()
{

View file

@ -55,7 +55,7 @@ test(size_t bits)
{
// Sequence of odd values
Sequence<T> in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); });
Sequence<T> in(n, [n, bits](size_t) { return T(2 * HashBits(n, bits - 1) ^ 1); });
// Even value, or false when T is bool.
T spike(2 * HashBits(n, bits - 1));
@ -92,13 +92,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>(8 * sizeof(int32_t));
test<uint16_t>(8 * sizeof(uint16_t));
test<float64_t>(53);
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN)
test<bool>(1);
#endif

View file

@ -78,17 +78,17 @@ is_equal(const T& x, const T& y)
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Size, typename Generator1, typename Generator2, typename Compare>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 first1, Iterator1 last1, Iterator1 first2,
operator()(__pstl::execution::unsequenced_policy, Iterator1 first1, Iterator1 last1, Iterator1 first2,
Iterator1 last2, Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
template <typename Iterator1, typename Size, typename Generator1, typename Generator2, typename Compare>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 first1, Iterator1 last1, Iterator1 first2,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 first1, Iterator1 last1, Iterator1 first2,
Iterator1 last2, Size n, Size m, Generator1 generator1, Generator2 generator2, Compare comp)
{
}
@ -123,8 +123,7 @@ struct test_one_policy
template <typename Policy, typename Iterator1, typename Size, typename Generator1, typename Generator2,
typename Compare>
typename std::enable_if<!is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(Policy&& exec, Iterator1 first1, Iterator1 last1, Iterator1 first2, Iterator1 last2, Size n, Size m,
Generator1 generator1, Generator2 generator2, Compare comp)
operator()(Policy&&, Iterator1, Iterator1, Iterator1, Iterator1, Size, Size, Generator1, Generator2, Compare)
{
}
};
@ -166,7 +165,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test_by_type<int32_t>([](int32_t i) { return 10 * i; }, [](int32_t i) { return i + 1; }, std::less<int32_t>());

View file

@ -30,17 +30,17 @@ using namespace TestUtils;
struct test_one_policy
{
#if _PSTL_ICC_18_VC141_TEST_SIMD_LAMBDA_RELEASE_BROKEN || _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_18_VC141_TEST_SIMD_LAMBDA_RELEASE_BROKEN) || defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e)
{
}
template <typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e)
{
}
@ -63,7 +63,7 @@ struct test_one_policy
template <typename ExecutionPolicy, typename Iterator1, typename Iterator2>
typename std::enable_if<is_same_iterator_category<Iterator1, std::forward_iterator_tag>::value>::type
operator()(ExecutionPolicy&& exec, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b, Iterator2 actual_e)
operator()(ExecutionPolicy&&, Iterator1, Iterator1, Iterator2, Iterator2)
{
}
};
@ -98,13 +98,13 @@ struct wrapper
}
};
int32_t
int
main()
{
test<int32_t>();
test<uint16_t>();
test<float64_t>();
#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN
#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN)
test<wrapper<float64_t>>();
#endif

View file

@ -70,16 +70,16 @@ struct test_one_policy
Iterator data_e;
test_one_policy(Iterator b, Iterator e) : data_b(b), data_e(e) {}
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
operator()(__pstl::execution::unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
{
}
template <typename Iterator1>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 actual_b, Iterator1 actual_e)
{
}
#endif
@ -90,7 +90,6 @@ struct test_one_policy
{
using namespace std;
using T = typename iterator_traits<Iterator1>::value_type;
using DifferenceType = typename iterator_traits<Iterator1>::difference_type;
fill(actual_b, actual_e, T(-123));
Iterator1 actual_return = reverse_copy(exec, data_b, data_e, actual_b);
@ -127,11 +126,9 @@ test()
}
}
int32_t
int
main()
{
// clang-3.8 fails to correctly auto vectorize the loop in some cases of different types of container's elements,
// for example: int32_t and int8_t. This issue isn't detected for clang-3.9 and newer versions.
test<int16_t, int8_t>();
test<uint16_t, float32_t>();
test<float64_t, int64_t>();

View file

@ -28,16 +28,16 @@ using namespace TestUtils;
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator, typename Size, typename T, typename Predicate>
void
operator()(pstl::execution::unsequenced_policy, Iterator b, Iterator e, Size count, const T& value, Predicate pred)
operator()(__pstl::execution::unsequenced_policy, Iterator b, Iterator e, Size count, const T& value, Predicate pred)
{
}
template <typename Iterator, typename Size, typename T, typename Predicate>
void
operator()(pstl::execution::parallel_unsequenced_policy, Iterator b, Iterator e, Size count, const T& value,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator b, Iterator e, Size count, const T& value,
Predicate pred)
{
}
@ -77,7 +77,7 @@ test()
}
for (auto r : res)
{
Sequence<T> in(n1, [n1](std::size_t k) { return T(0); });
Sequence<T> in(n1, [](std::size_t) { return T(0); });
std::size_t i = r, isub = 0;
for (; i < n1 && isub < n2; ++i, ++isub)
in[i] = value;
@ -100,13 +100,13 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<int32_t>();
test<uint16_t>();
test<float64_t>();
#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN
#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN)
test<bool>();
#endif

View file

@ -67,8 +67,7 @@ struct test_one_policy
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
Compare comp)
operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
{
}
};
@ -104,11 +103,11 @@ test_includes(Compare compare)
}
}
int32_t
int
main()
{
test_includes<float64_t, float64_t>(__pstl::__internal::__pstl_less());
test_includes<float64_t, float64_t>(std::less<>());
test_includes<Num<int64_t>, Num<int32_t>>([](const Num<int64_t>& x, const Num<int32_t>& y) { return x < y; });
std::cout << done() << std::endl;

View file

@ -43,16 +43,16 @@ struct WithCmpOp
struct test_is_heap
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator, typename Predicate>
typename std::enable_if<is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator first, Iterator last, Predicate pred)
operator()(__pstl::execution::unsequenced_policy, Iterator first, Iterator last, Predicate pred)
{
}
template <typename Iterator, typename Predicate>
typename std::enable_if<is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Predicate pred)
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator first, Iterator last, Predicate pred)
{
}
#endif
@ -87,13 +87,14 @@ struct test_is_heap
const Iterator actual = is_heap_until(exec, first, last, pred);
const auto x = std::distance(first, actual);
EXPECT_TRUE(expected == actual, "wrong return value from is_heap_until with predicate");
EXPECT_EQ(x, y, "both iterators should be the same distance away from 'first'");
}
}
// is_heap, is_heap_until works only with random access iterators
template <typename Policy, typename Iterator, typename Predicate>
typename std::enable_if<!is_same_iterator_category<Iterator, std::random_access_iterator_tag>::value, void>::type
operator()(Policy&& exec, Iterator first, Iterator last, Predicate pred)
operator()(Policy&&, Iterator, Iterator, Predicate)
{
}
};
@ -121,7 +122,7 @@ test_is_heap_by_type(Comp comp)
invoke_on_all_policies(test_is_heap(), in.cbegin(), in.cend(), comp);
}
Sequence<T> in(max_size / 10, [](size_t v) -> T { return T(1); });
Sequence<T> in(max_size / 10, [](size_t) -> T { return T(1); });
invoke_on_all_policies(test_is_heap(), in.begin(), in.end(), comp);
}
@ -139,7 +140,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test_is_heap_by_type<float32_t>(std::greater<float32_t>());

View file

@ -76,7 +76,7 @@ test_is_sorted_by_type()
invoke_on_all_policies(test_is_sorted(), in0.cbegin(), in0.cend(), std::is_sorted(in0.begin(), in0.end()));
//non-descending order
Sequence<T> in1(9, [](size_t v) -> T { return T(0); });
Sequence<T> in1(9, [](size_t) -> T { return T(0); });
invoke_on_all_policies(test_is_sorted(), in1.begin(), in1.end(), std::is_sorted(in1.begin(), in1.end()));
invoke_on_all_policies(test_is_sorted(), in1.cbegin(), in1.cend(), std::is_sorted(in1.begin(), in1.end()));
}
@ -93,7 +93,7 @@ struct test_non_const
}
};
int32_t
int
main()
{

View file

@ -165,12 +165,12 @@ struct test_non_const
}
};
int32_t
int
main()
{
test<uint16_t, float64_t>(std::less<float64_t>());
test<float32_t, int32_t>(std::greater<float32_t>());
#if !_PSTL_ICC_18_TEST_EARLY_EXIT_AVX_RELEASE_BROKEN
#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_AVX_RELEASE_BROKEN)
test<float64_t, int32_t>([](const float64_t x, const int32_t y) { return x * x < y * y; });
#endif
test<LocalWrapper<int32_t>, LocalWrapper<int32_t>>(

View file

@ -184,7 +184,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
using TestUtils::float64_t;

View file

@ -90,19 +90,18 @@ struct test_brick_partial_sort
//checking upper bound number of comparisons; O(p*(last-first)log(middle-first)); where p - number of threads;
if (m1 - first > 1)
{
auto complex = std::ceil(n * std::log(float32_t(m1 - first)));
#if _PSTL_USE_PAR_POLICIES
auto p = tbb::this_task_arena::max_concurrency();
#else
auto p = 1;
#endif
#ifdef _DEBUG
# if defined(_PSTL_PAR_BACKEND_TBB)
auto p = tbb::this_task_arena::max_concurrency();
# else
auto p = 1;
# endif
auto complex = std::ceil(n * std::log(float32_t(m1 - first)));
if (count_comp > complex * p)
{
std::cout << "complexity exceeded" << std::endl;
}
#endif
#endif // _DEBUG
}
}
}
@ -110,8 +109,7 @@ struct test_brick_partial_sort
template <typename Policy, typename InputIterator, typename Compare>
typename std::enable_if<!is_same_iterator_category<InputIterator, std::random_access_iterator_tag>::value,
void>::type
operator()(Policy&& exec, InputIterator first, InputIterator last, InputIterator exp_first, InputIterator exp_last,
Compare compare)
operator()(Policy&&, InputIterator, InputIterator, InputIterator, InputIterator, Compare)
{
}
};
@ -142,7 +140,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
count_val = 0;

View file

@ -64,32 +64,32 @@ struct test_one_policy
: d_first(b1), d_last(e1), exp_first(b2), exp_last(e2)
{
}
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename InputIterator, typename Size, typename T, typename Compare>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
const T& trash, Compare compare)
{
}
template <typename InputIterator, typename Size, typename T, typename Compare>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
const T& trash, Compare compare)
{
}
template <typename InputIterator, typename Size, typename T>
void
operator()(pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
operator()(__pstl::execution::unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
const T& trash)
{
}
template <typename InputIterator, typename Size, typename T>
void
operator()(pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
operator()(__pstl::execution::parallel_unsequenced_policy, InputIterator first, InputIterator last, Size n1, Size n2,
const T& trash)
{
}
@ -187,7 +187,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
test_partial_sort_copy<Num<float32_t>>([](Num<float32_t> x, Num<float32_t> y) { return x < y; });
@ -195,6 +195,11 @@ main()
test_algo_basic_double<int32_t>(run_for_rnd<test_non_const<int32_t>>());
test_partial_sort_copy<MemoryChecker>(
[](const MemoryChecker& val1, const MemoryChecker& val2){ return val1.value() < val2.value(); });
EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from partial_sort_copy: number of ctors calls < num of dtors calls");
EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from partial_sort_copy: number of ctors calls > num of dtors calls");
std::cout << done() << std::endl;
return 0;
}

View file

@ -60,7 +60,8 @@ struct Num
}
};
struct test_one_policy
template <typename Type>
struct test_set_union
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<!TestUtils::isReverse<InputIterator1>::value, void>::type
@ -75,30 +76,98 @@ struct test_one_policy
Sequence<T1> expect(n);
Sequence<T1> out(n);
//1. set_union
auto expect_res = std::set_union(first1, last1, first2, last2, expect.begin(), comp);
auto res = std::set_union(exec, first1, last1, first2, last2, out.begin(), comp);
EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_union");
EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_union effect");
}
//2. set_intersection
expect_res = std::set_intersection(first1, last1, first2, last2, expect.begin(), comp);
res = std::set_intersection(exec, first1, last1, first2, last2, out.begin(), comp);
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
{
}
};
template <typename Type>
struct test_set_intersection
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<!TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
Compare comp)
{
using T1 = typename std::iterator_traits<InputIterator1>::value_type;
auto n1 = std::distance(first1, last1);
auto n2 = std::distance(first2, last2);
auto n = n1 + n2;
Sequence<T1> expect(n);
Sequence<T1> out(n);
auto expect_res = std::set_intersection(first1, last1, first2, last2, expect.begin(), comp);
auto res = std::set_intersection(exec, first1, last1, first2, last2, out.begin(), comp);
EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_intersection");
EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_intersection effect");
}
//3. set_difference
expect_res = std::set_difference(first1, last1, first2, last2, expect.begin(), comp);
res = std::set_difference(exec, first1, last1, first2, last2, out.begin(), comp);
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
{
}
};
template <typename Type>
struct test_set_difference
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<!TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
Compare comp)
{
using T1 = typename std::iterator_traits<InputIterator1>::value_type;
auto n1 = std::distance(first1, last1);
auto n2 = std::distance(first2, last2);
auto n = n1 + n2;
Sequence<T1> expect(n);
Sequence<T1> out(n);
auto expect_res = std::set_difference(first1, last1, first2, last2, expect.begin(), comp);
auto res = std::set_difference(exec, first1, last1, first2, last2, out.begin(), comp);
EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_difference");
EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res), "wrong set_difference effect");
}
//4. set_symmetric_difference
expect_res = std::set_symmetric_difference(first1, last1, first2, last2, expect.begin(), comp);
res = std::set_symmetric_difference(exec, first1, last1, first2, last2, out.begin(), comp);
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
{
}
};
template <typename Type>
struct test_set_symmetric_difference
{
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<!TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
Compare comp)
{
using T1 = typename std::iterator_traits<InputIterator1>::value_type;
auto n1 = std::distance(first1, last1);
auto n2 = std::distance(first2, last2);
auto n = n1 + n2;
Sequence<T1> expect(n);
Sequence<T1> out(n);
auto expect_res = std::set_symmetric_difference(first1, last1, first2, last2, expect.begin(), comp);
auto res = std::set_symmetric_difference(exec, first1, last1, first2, last2, out.begin(), comp);
EXPECT_TRUE(expect_res - expect.begin() == res - out.begin(), "wrong result for set_symmetric_difference");
EXPECT_EQ_N(expect.begin(), out.begin(), std::distance(out.begin(), res),
@ -107,8 +176,7 @@ struct test_one_policy
template <typename Policy, typename InputIterator1, typename InputIterator2, typename Compare>
typename std::enable_if<TestUtils::isReverse<InputIterator1>::value, void>::type
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
Compare comp)
operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare)
{
}
};
@ -128,43 +196,92 @@ test_set(Compare compare)
for (std::size_t m = 0; m < n_max; m = m <= 16 ? m + 1 : size_t(2.71828 * m))
{
//prepare the input ranges
Sequence<T1> in1(n, [n](std::size_t k) { return rand() % (2 * k + 1); });
Sequence<T1> in1(n, [](std::size_t k) { return rand() % (2 * k + 1); });
Sequence<T2> in2(m, [m](std::size_t k) { return (m % 2) * rand() + rand() % (k + 1); });
std::sort(in1.begin(), in1.end(), compare);
std::sort(in2.begin(), in2.end(), compare);
invoke_on_all_policies(test_one_policy(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(), compare);
invoke_on_all_policies(test_set_union<T1>(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(),
compare);
invoke_on_all_policies(test_set_intersection<T1>(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(),
compare);
invoke_on_all_policies(test_set_difference<T1>(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(),
compare);
invoke_on_all_policies(test_set_symmetric_difference<T1>(), in1.begin(), in1.end(), in2.cbegin(),
in2.cend(), compare);
}
}
}
template <typename T>
struct test_non_const
struct test_non_const_set_difference
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
set_difference(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less<T>()));
}
};
template <typename T>
struct test_non_const_set_intersection
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
set_intersection(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less<T>()));
}
};
template <typename T>
struct test_non_const_set_symmetric_difference
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
set_symmetric_difference(exec, input_iter, input_iter, input_iter, input_iter, out_iter,
non_const(std::less<T>()));
}
};
template <typename T>
struct test_non_const_set_union
{
template <typename Policy, typename InputIterator, typename OutputInterator>
void
operator()(Policy&& exec, InputIterator input_iter, OutputInterator out_iter)
{
set_union(exec, input_iter, input_iter, input_iter, input_iter, out_iter, non_const(std::less<T>()));
}
};
int32_t
int
main()
{
test_set<float64_t, float64_t>(__pstl::__internal::__pstl_less());
test_set<float64_t, float64_t>(std::less<>());
test_set<Num<int64_t>, Num<int32_t>>([](const Num<int64_t>& x, const Num<int32_t>& y) { return x < y; });
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const<int32_t>>());
test_set<MemoryChecker, MemoryChecker>([](const MemoryChecker& val1, const MemoryChecker& val2) -> bool {
return val1.value() < val2.value();
});
EXPECT_FALSE(MemoryChecker::alive_objects() < 0, "wrong effect from set algorithms: number of ctors calls < num of dtors calls");
EXPECT_FALSE(MemoryChecker::alive_objects() > 0, "wrong effect from set algorithms: number of ctors calls > num of dtors calls");
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const_set_difference<int32_t>>());
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const_set_intersection<int32_t>>());
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const_set_symmetric_difference<int32_t>>());
test_algo_basic_double<int32_t>(run_for_rnd_fw<test_non_const_set_union<int32_t>>());
std::cout << done() << std::endl;

View file

@ -94,7 +94,7 @@ class ParanoidKey
index = k.index;
return *this;
}
ParanoidKey(int32_t index, int32_t value, OddTag) : index(index), value(value) {}
ParanoidKey(int32_t index, int32_t value, OddTag) : value(value), index(index) {}
ParanoidKey(ParanoidKey&& k) : value(k.value), index(k.index)
{
EXPECT_TRUE(k.isConstructed(), "source for move-construction is dead");
@ -171,7 +171,7 @@ struct test_sort_with_compare
typename std::enable_if<is_same_iterator_category<InputIterator, std::random_access_iterator_tag>::value,
void>::type
operator()(Policy&& exec, OutputIterator tmp_first, OutputIterator tmp_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, InputIterator first, InputIterator last, Size n, Compare compare)
OutputIterator2 expected_last, InputIterator first, InputIterator, Size n, Compare compare)
{
using namespace std;
copy_n(first, n, expected_first);
@ -198,8 +198,8 @@ struct test_sort_with_compare
typename Compare>
typename std::enable_if<!is_same_iterator_category<InputIterator, std::random_access_iterator_tag>::value,
void>::type
operator()(Policy&& exec, OutputIterator tmp_first, OutputIterator tmp_last, OutputIterator2 expected_first,
OutputIterator2 expected_last, InputIterator first, InputIterator last, Size n, Compare compare)
operator()(Policy&&, OutputIterator, OutputIterator, OutputIterator2, OutputIterator2, InputIterator, InputIterator,
Size, Compare)
{
}
};
@ -233,7 +233,7 @@ struct test_non_const
}
};
int32_t
int
main()
{
std::srand(42);

View file

@ -33,19 +33,19 @@ template <typename T>
struct wrapper
{
T t;
explicit wrapper(T t_) : t(t_) {}
constexpr explicit wrapper(T t_) : t(t_) {}
template <typename T2>
wrapper(const wrapper<T2>& a)
constexpr wrapper(const wrapper<T2>& a)
{
t = a.t;
}
template <typename T2>
void
constexpr void
operator=(const wrapper<T2>& a)
{
t = a.t;
}
wrapper<T>
constexpr wrapper<T>
operator-(const wrapper<T>& a) const
{
return wrapper<T>(t - a.t);
@ -75,9 +75,11 @@ compute_and_check(Iterator1 first, Iterator1 last, Iterator2 d_first, T, Functio
if (first == last)
return true;
T2 temp(*first);
if (!compare(temp, *d_first))
return false;
{
T2 temp(*first);
if (!compare(temp, *d_first))
return false;
}
Iterator1 second = std::next(first);
++d_first;
@ -94,25 +96,25 @@ compute_and_check(Iterator1 first, Iterator1 last, Iterator2 d_first, T, Functio
// we don't want to check equality here
// because we can't be sure it will be strictly equal for floating point types
template <typename Iterator1, typename Iterator2, typename T, typename Function>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
compute_and_check(Iterator1 first, Iterator1 last, Iterator2 d_first, T, Function)
typename std::enable_if<std::is_floating_point<T>::value, bool>::type compute_and_check(Iterator1, Iterator1, Iterator2,
T, Function)
{
return true;
}
struct test_one_policy
{
#if _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || \
_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN // dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || \
defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) // dummy specialization by policy type, in case of broken configuration
template <typename Iterator1, typename Iterator2, typename T, typename Function>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, T trash, Function f)
{
}
template <typename Iterator1, typename Iterator2, typename T, typename Function>
typename std::enable_if<is_same_iterator_category<Iterator1, std::random_access_iterator_tag>::value, void>::type
operator()(pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
operator()(__pstl::execution::parallel_unsequenced_policy, Iterator1 data_b, Iterator1 data_e, Iterator2 actual_b,
Iterator2 actual_e, T trash, Function f)
{
}
@ -146,16 +148,14 @@ template <typename T1, typename T2, typename Pred>
void
test(Pred pred)
{
typedef typename Sequence<T2>::iterator iterator_type;
const std::size_t max_len = 100000;
const T2 value = T2(77);
const T1 trash = T1(31);
static constexpr T2 value = T2(77);
static constexpr T1 trash = T1(31);
Sequence<T1> actual(max_len, [](std::size_t i) { return T1(i); });
Sequence<T2> data(max_len, [&value](std::size_t i) { return i % 3 == 2 ? T2(i * i) : value; });
Sequence<T2> data(max_len, [](std::size_t i) { return i % 3 == 2 ? T2(i * i) : value; });
for (std::size_t len = 0; len < max_len; len = len <= 16 ? len + 1 : std::size_t(3.1415 * len))
{
@ -166,7 +166,7 @@ test(Pred pred)
}
}
int32_t
int
main()
{
test<uint8_t, uint32_t>([](uint32_t a, uint32_t b) { return a - b; });

View file

@ -62,7 +62,7 @@ test_long_form(T init, BinaryOp binary_op, F f)
struct test_two_short_forms
{
#if _PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN //dummy specialization by policy type, in case of broken configuration
#if defined(_PSTL_ICC_16_VC14_TEST_PAR_TBB_RT_RELEASE_64_BROKEN) //dummy specialization by policy type, in case of broken configuration
template <typename Iterator>
void
operator()(__pstl::execution::parallel_policy, Iterator first, Iterator last, Sum init, Sum expected)
@ -105,7 +105,7 @@ test_short_forms()
}
}
int32_t
int
main()
{
// Test for popular types

View file

@ -108,12 +108,13 @@ struct test_scan_with_plus
template <typename Policy, typename Iterator1, typename Iterator2, typename Iterator3, typename Size, typename T>
void
operator()(Policy&& exec, Iterator1 in_first, Iterator1 in_last, Iterator2 out_first, Iterator2 out_last,
Iterator3 expected_first, Iterator3 expected_last, Size n, T init, T trash)
Iterator3 expected_first, Iterator3, Size n, T init, T trash)
{
using namespace std;
auto orr1 = inclusive ? inclusive_scan_serial(in_first, in_last, expected_first)
: exclusive_scan_serial(in_first, in_last, expected_first, init);
(void)orr1;
auto orr = inclusive ? inclusive_scan(exec, in_first, in_last, out_first)
: exclusive_scan(exec, in_first, in_last, out_first, init);
EXPECT_TRUE(out_last == orr,
@ -146,12 +147,13 @@ struct test_scan_with_binary_op
typename BinaryOp>
typename std::enable_if<!TestUtils::isReverse<Iterator1>::value, void>::type
operator()(Policy&& exec, Iterator1 in_first, Iterator1 in_last, Iterator2 out_first, Iterator2 out_last,
Iterator3 expected_first, Iterator3 expected_last, Size n, T init, BinaryOp binary_op, T trash)
Iterator3 expected_first, Iterator3, Size n, T init, BinaryOp binary_op, T trash)
{
using namespace std;
auto orr1 = inclusive ? inclusive_scan_serial(in_first, in_last, expected_first, binary_op, init)
: exclusive_scan_serial(in_first, in_last, expected_first, init, binary_op);
(void)orr1;
auto orr = inclusive ? inclusive_scan(exec, in_first, in_last, out_first, binary_op, init)
: exclusive_scan(exec, in_first, in_last, out_first, init, binary_op);
@ -162,8 +164,7 @@ struct test_scan_with_binary_op
template <typename Policy, typename Iterator1, typename Iterator2, typename Iterator3, typename Size, typename T,
typename BinaryOp>
typename std::enable_if<TestUtils::isReverse<Iterator1>::value, void>::type
operator()(Policy&& exec, Iterator1 in_first, Iterator1 in_last, Iterator2 out_first, Iterator2 out_last,
Iterator3 expected_first, Iterator3 expected_last, Size n, T init, BinaryOp binary_op, T trash)
operator()(Policy&&, Iterator1, Iterator1, Iterator2, Iterator2, Iterator3, Iterator3, Size, T, BinaryOp, T)
{
}
};
@ -186,13 +187,13 @@ test_matrix(Out init, BinaryOp binary_op, Out trash)
}
}
int32_t
int
main()
{
for (int32_t mode = 0; mode < 2; ++mode)
{
inclusive = mode != 0;
#if !_PSTL_ICC_19_TEST_SIMD_UDS_WINDOWS_RELEASE_BROKEN
#if !defined(_PSTL_ICC_19_TEST_SIMD_UDS_WINDOWS_RELEASE_BROKEN)
// Test with highly restricted type and associative but not commutative operation
test_matrix<Matrix2x2<int32_t>, Matrix2x2<int32_t>>(Matrix2x2<int32_t>(), multiply_matrix<int32_t>,
Matrix2x2<int32_t>(-666, 666));

View file

@ -54,7 +54,7 @@ class MyClass
int32_t my_field;
MyClass() { my_field = 0; }
MyClass(int32_t in) { my_field = in; }
MyClass(const MyClass& in) { my_field = in.my_field; }
MyClass(const MyClass& in) = default;
friend MyClass
operator+(const MyClass& x, const MyClass& y)
@ -66,11 +66,13 @@ class MyClass
{
return MyClass(-x.my_field);
}
friend MyClass operator*(const MyClass& x, const MyClass& y) { return MyClass(x.my_field * y.my_field); }
bool
operator==(const MyClass& in) const
friend MyClass operator*(const MyClass& x, const MyClass& y)
{
return my_field == in.my_field;
return MyClass(x.my_field * y.my_field);
}
friend bool operator==(const MyClass& x, const MyClass& y)
{
return x.my_field == y.my_field;
}
};
@ -78,13 +80,13 @@ template <typename T>
void
CheckResults(const T& expected, const T& in)
{
EXPECT_TRUE(Equal(expected, in), "wrong result of transform_reduce");
EXPECT_TRUE(expected == in, "wrong result of transform_reduce");
}
// We need to check correctness only for "int" (for example) except cases
// if we have "floating-point type"-specialization
void
CheckResults(const float32_t& expected, const float32_t& in)
CheckResults(const float32_t&, const float32_t&)
{
}
@ -94,7 +96,7 @@ struct test_transform_reduce
template <typename Policy, typename InputIterator1, typename InputIterator2, typename T, typename BinaryOperation1,
typename BinaryOperation2, typename UnaryOp>
void
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,
operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2,
T init, BinaryOperation1 opB1, BinaryOperation2 opB2, UnaryOp opU)
{
@ -125,20 +127,19 @@ test_by_type(T init, BinaryOperation1 opB1, BinaryOperation2 opB2, UnaryOp opU,
}
}
int32_t
int
main()
{
test_by_type<int32_t>(42, std::plus<int32_t>(), std::multiplies<int32_t>(), std::negate<int32_t>(),
[](std::size_t a) -> int32_t { return int32_t(rand() % 1000); });
[](std::size_t) -> int32_t { return int32_t(rand() % 1000); });
test_by_type<int64_t>(0, [](const int64_t& a, const int64_t& b) -> int64_t { return a | b; }, XOR(),
[](const int64_t& x) -> int64_t { return x * 2; },
[](std::size_t a) -> int64_t { return int64_t(rand() % 1000); });
test_by_type<float32_t>(1.0f, std::multiplies<float32_t>(),
[](const float32_t& a, const float32_t& b) -> float32_t { return a + b; },
[](const float32_t& x) -> float32_t { return x + 2; },
[](std::size_t a) -> float32_t { return rand() % 1000; });
[](std::size_t) -> int64_t { return int64_t(rand() % 1000); });
test_by_type<float32_t>(
1.0f, std::multiplies<float32_t>(), [](const float32_t& a, const float32_t& b) -> float32_t { return a + b; },
[](const float32_t& x) -> float32_t { return x + 2; }, [](std::size_t) -> float32_t { return rand() % 1000; });
test_by_type<MyClass>(MyClass(), std::plus<MyClass>(), std::multiplies<MyClass>(), std::negate<MyClass>(),
[](std::size_t a) -> MyClass { return MyClass(rand() % 1000); });
[](std::size_t) -> MyClass { return MyClass(rand() % 1000); });
std::cout << done() << std::endl;
return 0;

View file

@ -47,15 +47,15 @@ struct test_transform_scan
typename T, typename BinaryOp>
typename std::enable_if<!TestUtils::isReverse<InputIterator>::value, void>::type
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
UnaryOp unary_op, T init, BinaryOp binary_op, T trash)
OutputIterator out_last, OutputIterator expected_first, OutputIterator, Size n, UnaryOp unary_op, T init,
BinaryOp binary_op, T trash)
{
using namespace std;
auto orr1 = inclusive ? transform_inclusive_scan(__pstl::execution::seq, first, last, expected_first, binary_op,
unary_op, init)
: transform_exclusive_scan(__pstl::execution::seq, first, last, expected_first, init,
binary_op, unary_op);
auto orr1 =
inclusive
? transform_inclusive_scan(std::execution::seq, first, last, expected_first, binary_op, unary_op, init)
: transform_exclusive_scan(std::execution::seq, first, last, expected_first, init, binary_op, unary_op);
auto orr2 = inclusive ? transform_inclusive_scan(exec, first, last, out_first, binary_op, unary_op, init)
: transform_exclusive_scan(exec, first, last, out_first, init, binary_op, unary_op);
EXPECT_TRUE(out_last == orr2, "transform...scan returned wrong iterator");
@ -64,7 +64,7 @@ struct test_transform_scan
// Checks inclusive scan if init is not provided
if (inclusive && n > 0)
{
orr1 = transform_inclusive_scan(__pstl::execution::seq, first, last, expected_first, binary_op, unary_op);
orr1 = transform_inclusive_scan(std::execution::seq, first, last, expected_first, binary_op, unary_op);
orr2 = transform_inclusive_scan(exec, first, last, out_first, binary_op, unary_op);
EXPECT_TRUE(out_last == orr2, "transform...scan returned wrong iterator");
check_and_reset(expected_first, out_first, n, trash);
@ -74,9 +74,8 @@ struct test_transform_scan
template <typename Policy, typename InputIterator, typename OutputIterator, typename Size, typename UnaryOp,
typename T, typename BinaryOp>
typename std::enable_if<TestUtils::isReverse<InputIterator>::value, void>::type
operator()(Policy&& exec, InputIterator first, InputIterator last, OutputIterator out_first,
OutputIterator out_last, OutputIterator expected_first, OutputIterator expected_last, Size n,
UnaryOp unary_op, T init, BinaryOp binary_op, T trash)
operator()(Policy&&, InputIterator, InputIterator, OutputIterator, OutputIterator, OutputIterator, OutputIterator,
Size, UnaryOp, T, BinaryOp, T)
{
}
};
@ -140,6 +139,7 @@ test(UnaryOp unary_op, Out init, BinaryOp binary_op, Out trash)
inclusive
? transform_inclusive_scan_serial(in.cbegin(), in.cend(), out.fbegin(), unary_op, init, binary_op)
: transform_exclusive_scan_serial(in.cbegin(), in.cend(), out.fbegin(), unary_op, init, binary_op);
(void)result;
check_and_reset(expected.begin(), out.begin(), out.size(), trash);
invoke_on_all_policies(test_transform_scan(), in.begin(), in.end(), out.begin(), out.end(), expected.begin(),
@ -167,13 +167,13 @@ test_matrix(UnaryOp unary_op, Out init, BinaryOp binary_op, Out trash)
}
}
int32_t
int
main()
{
for (int32_t mode = 0; mode < 2; ++mode)
{
inclusive = mode != 0;
#if !_PSTL_ICC_19_TEST_SIMD_UDS_WINDOWS_RELEASE_BROKEN
#if !defined(_PSTL_ICC_19_TEST_SIMD_UDS_WINDOWS_RELEASE_BROKEN)
test_matrix<Matrix2x2<int32_t>, Matrix2x2<int32_t>>([](const Matrix2x2<int32_t> x) { return x; },
Matrix2x2<int32_t>(), multiply_matrix<int32_t>,
Matrix2x2<int32_t>(-666, 666));

View file

@ -30,7 +30,7 @@ typedef float float32_t;
template <class T, std::size_t N>
constexpr size_t
const_size(const T (&array)[N]) noexcept
const_size(const T (&)[N]) noexcept
{
return N;
}
@ -119,7 +119,7 @@ expect_equal(Iterator1 expected_first, Iterator2 actual_first, Size n, const cha
const char* message)
{
size_t error_count = 0;
for (size_t k = 0; k < n && error_count < 10; ++k, ++expected_first, ++actual_first)
for (Size k = 0; k < n && error_count < 10; ++k, ++expected_first, ++actual_first)
{
if (!(*expected_first == *actual_first))
{
@ -231,6 +231,82 @@ fill_data(Iterator first, Iterator last, F f)
}
}
struct MemoryChecker {
// static counters and state tags
static std::atomic<std::int64_t> alive_object_counter; // initialized outside
static constexpr std::int64_t alive_state = 0xAAAAAAAAAAAAAAAA;
static constexpr std::int32_t dead_state = 0; // only used as a set value to cancel alive_state
std::int32_t _value; // object value used for algorithms
std::int64_t _state; // state tag used for checks
// ctors, dtors, assign ops
explicit MemoryChecker(std::int32_t value = 0) : _value(value) {
// check for EXPECT_TRUE(state() != alive_state, ...) has not been done since we cannot guarantee that
// raw memory for object being constructed does not have a bit sequence being equal to alive_state
// set constructed state and increment counter for living object
inc_alive_objects();
_state = alive_state;
}
MemoryChecker(MemoryChecker&& other) : _value(other.value()) {
// check for EXPECT_TRUE(state() != alive_state, ...) has not been done since
// compiler can optimize out the move ctor call that results in false positive failure
EXPECT_TRUE(other.state() == alive_state, "wrong effect from MemoryChecker(MemoryChecker&&): attemp to construct an object from non-existing object");
// set constructed state and increment counter for living object
inc_alive_objects();
_state = alive_state;
}
MemoryChecker(const MemoryChecker& other) : _value(other.value()) {
// check for EXPECT_TRUE(state() != alive_state, ...) has not been done since
// compiler can optimize out the copy ctor call that results in false positive failure
EXPECT_TRUE(other.state() == alive_state, "wrong effect from MemoryChecker(const MemoryChecker&): attemp to construct an object from non-existing object");
// set constructed state and increment counter for living object
inc_alive_objects();
_state = alive_state;
}
MemoryChecker& operator=(MemoryChecker&& other) {
// check if we do not assign over uninitialized memory
EXPECT_TRUE(state() == alive_state, "wrong effect from MemoryChecker::operator=(MemoryChecker&& other): attemp to assign to non-existing object");
EXPECT_TRUE(other.state() == alive_state, "wrong effect from MemoryChecker::operator=(MemoryChecker&& other): attemp to assign from non-existing object");
// just assign new value, counter is the same, state is the same
_value = other.value();
return *this;
}
MemoryChecker& operator=(const MemoryChecker& other) {
// check if we do not assign over uninitialized memory
EXPECT_TRUE(state() == alive_state, "wrong effect from MemoryChecker::operator=(const MemoryChecker& other): attemp to assign to non-existing object");
EXPECT_TRUE(other.state() == alive_state, "wrong effect from MemoryChecker::operator=(const MemoryChecker& other): attemp to assign from non-existing object");
// just assign new value, counter is the same, state is the same
_value = other.value();
return *this;
}
~MemoryChecker() {
// check if we do not double destruct the object
EXPECT_TRUE(state() == alive_state, "wrong effect from ~MemoryChecker(): attemp to destroy non-existing object");
// set destructed state and decrement counter for living object
static_cast<volatile std::int64_t&>(_state) = dead_state;
dec_alive_objects();
}
// getters
std::int32_t value() const { return _value; }
std::int64_t state() const { return _state; }
static std::int32_t alive_objects() { return alive_object_counter.load(); }
private:
// setters
void inc_alive_objects() { alive_object_counter.fetch_add(1); }
void dec_alive_objects() { alive_object_counter.fetch_sub(1); }
};
std::atomic<std::int64_t> MemoryChecker::alive_object_counter{0};
std::ostream& operator<<(std::ostream& os, const MemoryChecker& val) { return (os << val.value()); }
bool operator==(const MemoryChecker& v1, const MemoryChecker& v2) { return v1.value() == v2.value(); }
bool operator<(const MemoryChecker& v1, const MemoryChecker& v2) { return v1.value() < v2.value(); }
// Sequence<T> is a container of a sequence of T with lots of kinds of iterators.
// Prefixes on begin/end mean:
// c = "const"
@ -572,7 +648,7 @@ struct Matrix2x2
T a[2][2];
Matrix2x2() : a{{1, 0}, {0, 1}} {}
Matrix2x2(T x, T y) : a{{0, x}, {x, y}} {}
#if !_PSTL_ICL_19_VC14_VC141_TEST_SCAN_RELEASE_BROKEN
#if !defined(_PSTL_ICL_19_VC14_VC141_TEST_SCAN_RELEASE_BROKEN)
Matrix2x2(const Matrix2x2& m) : a{{m.a[0][0], m.a[0][1]}, {m.a[1][0], m.a[1][1]}} {}
Matrix2x2&
operator=(const Matrix2x2& m)
@ -651,7 +727,7 @@ struct ReverseAdapter
iterator_type
operator()(Iterator it)
{
#if _PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT
#if defined(_PSTL_CPP14_MAKE_REVERSE_ITERATOR_PRESENT)
return std::make_reverse_iterator(it);
#else
return iterator_type(it);
@ -1191,7 +1267,7 @@ transform_reduce_serial(InputIterator first, InputIterator last, T init, BinaryO
static const char*
done()
{
#if _PSTL_TEST_SUCCESSFUL_KEYWORD
#if defined(_PSTL_TEST_SUCCESSFUL_KEYWORD)
return "done";
#else
return "passed";
@ -1228,8 +1304,12 @@ template <typename Policy, typename F>
static void
invoke_if(Policy&&, F f)
{
#if _PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN || _PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN
__pstl::__internal::invoke_if_not(__pstl::__internal::allow_unsequenced<Policy>(), f);
#if defined(_PSTL_ICC_16_VC14_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN) || defined(_PSTL_ICC_17_VC141_TEST_SIMD_LAMBDA_DEBUG_32_BROKEN)
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