libstdc++: Rebase include/pstl to current upstream

From llvm-project/pstl @ 0b2e0e80d96

libstdc++-v3/ChangeLog:

	* include/pstl/algorithm_impl.h: Update file.
	* include/pstl/execution_impl.h: Likewise.
	* include/pstl/glue_algorithm_impl.h: Likewise.
	* include/pstl/glue_memory_impl.h: Likewise.
	* include/pstl/glue_numeric_impl.h: Likewise.
	* include/pstl/memory_impl.h: Likewise.
	* include/pstl/numeric_impl.h: Likewise.
	* include/pstl/parallel_backend.h: Likewise.
	* include/pstl/parallel_backend_serial.h: Likewise.
	* include/pstl/parallel_backend_tbb.h: Likewise.
	* include/pstl/parallel_backend_utils.h: Likewise.
	* include/pstl/pstl_config.h: Likewise.
	* include/pstl/unseq_backend_simd.h: Likewise.
This commit is contained in:
Thomas Rodgers 2020-10-21 06:11:28 -07:00
parent 310fe80bab
commit e957b86ca2
13 changed files with 1585 additions and 778 deletions

View File

@ -402,9 +402,7 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _
if (__last1 - __first1 != __last2 - __first2)
return false;
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2,
__internal::__not_pred<_BinaryPredicate>(__p))
.first == __last1;
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
@ -454,8 +452,7 @@ bool
__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
_BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept
{
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, __not_pred<_BinaryPredicate>(__p))
.first == __last1;
return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
@ -599,21 +596,19 @@ _RandomAccessIterator
__find_subrange(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __global_last,
_Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector) noexcept
{
if (__global_last - __first < __count || __count < 1)
if (static_cast<_Size>(__global_last - __first) < __count || __count < 1)
{
return __last; // According to the standard last shall be returned when count < 1
}
auto __n = __global_last - __first;
auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred);
while (__first != __last && (__global_last - __first >= __count))
while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count))
{
__first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector);
// check that all of elements in [first+1, first+count) equal to value
if (__first != __last && (__global_last - __first >= __count) &&
!__internal::__brick_any_of(__first + 1, __first + __count,
__not_pred<decltype(__unary_pred)>(__unary_pred), __is_vector))
if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) &&
!__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector))
{
return __first;
}
@ -821,7 +816,7 @@ __pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Ra
_Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector,
/*is_parallel=*/std::true_type) noexcept
{
if (__last - __first == __count)
if (static_cast<_Size>(__last - __first) == __count)
{
const bool __result = !__internal::__pattern_any_of(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
@ -903,6 +898,36 @@ __brick_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _Outpu
[](_RandomAccessIterator __first, _OutputIterator __result) { *__result = std::move(*__first); });
}
struct __brick_move_destroy
{
template <typename _Iterator, typename _OutputIterator>
_OutputIterator
operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::true_type) const
{
using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;
return __unseq_backend::__simd_assign(__first, __last - __first, __result,
[](_Iterator __first, _OutputIterator __result) {
*__result = std::move(*__first);
(*__first).~_IteratorValueType();
});
}
template <typename _Iterator, typename _OutputIterator>
_OutputIterator
operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::false_type) const
{
using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;
for (; __first != __last; ++__first, ++__result)
{
*__result = std::move(*__first);
(*__first).~_IteratorValueType();
}
return __result;
}
};
//------------------------------------------------------------------------
// swap_ranges
//------------------------------------------------------------------------
@ -1224,10 +1249,16 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI
[&__m](_DifferenceType __total) { __m = __total; });
// 3. Elements from result are moved to [first, last)
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
[__result, __first, __is_vector](_Tp* __i, _Tp* __j) {
__internal::__brick_move(__i, __j, __first + (__i - __result), __is_vector);
});
__par_backend::__parallel_for(
std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
[__result, __first, __is_vector](_Tp* __i, _Tp* __j) {
__invoke_if_else(
std::is_trivial<_Tp>(),
[&]() { __brick_move(__i, __j, __first + (__i - __result), __is_vector); },
[&]() {
__brick_move_destroy()(__i, __j, __first + (__i - __result), __is_vector);
});
});
return __first + __m;
});
}
@ -1576,8 +1607,8 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m),
[__first, __result, __is_vector](_Tp* __b, _Tp* __e) {
__internal::__brick_move(__b, __e, __first + (__b - __result),
__is_vector);
__brick_move_destroy()(
__b, __e, __first + (__b - __result), __is_vector);
});
return __first + (__last - __middle);
@ -1602,7 +1633,7 @@ __pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
[__n, __m, __first, __result, __is_vector](_Tp* __b, _Tp* __e) {
__internal::__brick_move(
__brick_move_destroy()(
__b, __e, __first + ((__n - __m) + (__b - __result)), __is_vector);
});
@ -1764,7 +1795,7 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F
{
// find first element that don't satisfy pred
_ForwardIterator __x =
__internal::__brick_find_if(__i + 1, __j, __not_pred<_UnaryPredicate>(__pred), __is_vector);
__internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), __is_vector);
if (__x != __j)
{
// find first element after "x" that satisfy pred
@ -2087,8 +2118,7 @@ __pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Random
__internal::__except_handler([&]() {
__par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
[](_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp) { std::sort(__first, __last, __comp); },
__last - __first);
_Compare __comp) { std::sort(__first, __last, __comp); });
});
}
@ -2135,6 +2165,9 @@ __pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp, _IsVector, /*is_parallel=*/std::true_type)
{
const auto __n = __middle - __first;
if (__n == 0)
return;
__internal::__except_handler([&]() {
__par_backend::__parallel_stable_sort(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
@ -2223,8 +2256,13 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first,
// 3. Move elements from temporary __buffer to output
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2,
[__r, __d_first, __is_vector](_T1* __i, _T1* __j) {
__internal::__brick_move(__i, __j, __d_first + (__i - __r), __is_vector);
__brick_move_destroy()(
__i, __j, __d_first + (__i - __r), __is_vector);
});
__par_backend::__parallel_for(
std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1,
[__is_vector](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, __is_vector); });
return __d_first + __n2;
}
});
@ -2244,7 +2282,7 @@ __brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _Binary
template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
/* IsVector = */ std::false_type, bool __or_semantic) noexcept
/* IsVector = */ std::false_type, bool) noexcept
{
return std::adjacent_find(__first, __last, __pred);
}
@ -2670,16 +2708,14 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __firs
[__n, __move_values, __move_sequences](_BidirectionalIterator __f1, _BidirectionalIterator __l1,
_BidirectionalIterator __f2, _BidirectionalIterator __l2, _Tp* __f3,
_Compare __comp) {
auto __func = __par_backend::__serial_move_merge<decltype(__move_values), decltype(__move_sequences)>(
__n, __move_values, __move_sequences);
__func(__f1, __l1, __f2, __l2, __f3, __comp);
(__utils::__serial_move_merge(__n))(__f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values,
__move_sequences, __move_sequences);
return __f3 + (__l1 - __f1) + (__l2 - __f2);
});
__par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n,
[__r, __first, __is_vector](_Tp* __i, _Tp* __j) {
__internal::__brick_move(__i, __j, __first + (__i - __r), __is_vector);
});
__par_backend::__parallel_for(
std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first, __is_vector](_Tp* __i, _Tp* __j) {
__brick_move_destroy()(__i, __j, __first + (__i - __r), __is_vector);
});
});
}
@ -2689,7 +2725,7 @@ __pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __firs
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
/*is_parallel=*/std::false_type) noexcept
{
@ -2699,7 +2735,7 @@ __pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwa
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector __is_vector,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
/*is_parallel=*/std::true_type)
{
if (__first2 >= __last2)
@ -2761,7 +2797,7 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
_SizeFunction __size_func, _SetOP __set_op, _IsVector __is_vector)
{
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
struct _SetRange
{
@ -2776,7 +2812,7 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
const _DifferenceType __n1 = __last1 - __first1;
const _DifferenceType __n2 = __last2 - __first2;
__par_backend::__buffer<_T> __buf(__size_func(__n1, __n2));
__par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2));
return __internal::__except_handler([&__exec, __n1, __first1, __last1, __first2, __last2, __result, __is_vector,
__comp, __size_func, __set_op, &__buf]() {
@ -2784,8 +2820,9 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar
_DifferenceType __m{};
auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan
if (!__s.empty())
__internal::__brick_move(__buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len),
__result + __s.__pos, __is_vector);
__brick_move_destroy()(__buffer + __s.__buf_pos,
__buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos,
__is_vector);
};
__par_backend::__parallel_strict_scan(
std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0},
@ -2971,6 +3008,17 @@ __brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forwar
return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
}
template <typename _IsVector>
struct __BrickCopyConstruct
{
template <typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result)
{
return __brick_uninitialized_copy(__first, __last, __result, _IsVector());
}
};
template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
@ -3007,12 +3055,14 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forw
if (__n1 + __n2 <= __set_algo_cut_off)
return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
return __internal::__parallel_set_union_op(
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
return __parallel_set_union_op(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
_T* __result,
_Compare __comp) { return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); },
_Tp* __result, _Compare __comp) {
return __pstl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp,
__BrickCopyConstruct<_IsVector>());
},
__is_vector);
}
@ -3056,7 +3106,7 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
_Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
const auto __n1 = __last1 - __first1;
@ -3086,8 +3136,9 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, __comp,
[](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _T* __result, _Compare __comp) {
return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result,
__comp);
},
__is_vector);
}
@ -3100,8 +3151,9 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, __comp,
[](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _T* __result, _Compare __comp) {
return std::set_intersection(__first2, __last2, __first1, __last1, __result, __comp);
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result,
__comp);
},
__is_vector);
return __result;
@ -3151,7 +3203,7 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
_Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
const auto __n1 = __last1 - __first1;
@ -3193,13 +3245,15 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1,
std::true_type());
if (__n1 + __n2 > __set_algo_cut_off)
return __internal::__parallel_set_op(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
[](_DifferenceType __n, _DifferenceType __m) { return __n; },
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _T* __result,
_Compare __comp) { return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); },
__is_vector);
return __parallel_set_op(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
__comp, [](_DifferenceType __n, _DifferenceType) { return __n; },
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
return __pstl::__utils::__set_difference_construct(
__first1, __last1, __first2, __last2, __result, __comp,
__BrickCopyConstruct<_IsVector>());
},
__is_vector);
// use serial algorithm
return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
@ -3254,12 +3308,13 @@ __pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1
if (__n1 + __n2 <= __set_algo_cut_off)
return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
typedef typename std::iterator_traits<_OutputIterator>::value_type _T;
typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
return __internal::__parallel_set_union_op(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
[](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
_T* __result, _Compare __comp) {
return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
_Tp* __result, _Compare __comp) {
return __pstl::__utils::__set_symmetric_difference_construct(__first1, __last1, __first2, __last2, __result,
__comp, __BrickCopyConstruct<_IsVector>());
},
__is_vector);
}
@ -3443,14 +3498,14 @@ __pattern_minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F
std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, std::make_pair(__first, __first),
[=](_ForwardIterator __begin, _ForwardIterator __end, _Result __init) -> _Result {
const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, __is_vector);
return std::make_pair(__internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
__internal::__cmp_iterators_by_values(__init.second, __subresult.second,
__not_pred<_Compare>(__comp)));
return std::make_pair(
__internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
__internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp)));
},
[=](_Result __p1, _Result __p2) -> _Result {
return std::make_pair(
__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp),
__internal::__cmp_iterators_by_values(__p2.second, __p1.second, __not_pred<_Compare>(__comp)));
__internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp)));
});
});
}
@ -3487,7 +3542,7 @@ __brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forward
_ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::true_type) noexcept
{
auto __n = std::min(__last1 - __first1, __last2 - __first2);
return __unseq_backend::__simd_first(__first1, __n, __first2, __not_pred<_Predicate>(__pred));
return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate, class _IsVector>

View File

@ -28,7 +28,7 @@ template <typename _Tp>
std::false_type __lazy_and(_Tp, std::false_type)
{
return std::false_type{};
};
}
template <typename _Tp>
inline _Tp
@ -41,7 +41,7 @@ template <typename _Tp>
std::true_type __lazy_or(_Tp, std::true_type)
{
return std::true_type{};
};
}
template <typename _Tp>
inline _Tp

File diff suppressed because it is too large Load Diff

View File

@ -26,29 +26,29 @@ uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
using namespace __pstl;
const auto __is_parallel =
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector =
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() {
return __internal::__pattern_walk2_brick(
return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
return __internal::__brick_copy(__begin, __end, __res, __is_vector);
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(__val1);
},
__is_vector, __is_parallel);
return __pstl::__internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last,
__result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(__val1);
},
__is_vector, __is_parallel);
});
}
@ -60,29 +60,28 @@ uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
using namespace __pstl;
const auto __is_parallel =
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector =
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() {
return __internal::__pattern_walk2_brick_n(
return __pstl::__internal::__pattern_walk2_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(__val1);
},
__is_vector, __is_parallel);
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(__val1);
},
__is_vector, __is_parallel);
});
}
@ -96,29 +95,29 @@ uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIter
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
using namespace __pstl;
const auto __is_parallel =
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector =
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() {
return __internal::__pattern_walk2_brick(
return __pstl::__internal::__pattern_walk2_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[__is_vector](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) {
return __internal::__brick_copy(__begin, __end, __res, __is_vector);
return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
},
__is_vector, __is_parallel);
return __pstl::__internal::__pattern_walk2(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
},
__is_vector, __is_parallel);
});
}
@ -130,29 +129,29 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2;
typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2;
using namespace __pstl;
const auto __is_parallel =
__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
const auto __is_vector =
__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _InputIterator, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (),
[&]() {
return __internal::__pattern_walk2_brick_n(
return __pstl::__internal::__pattern_walk2_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[__is_vector](_InputIterator __begin, _Size __sz, _ForwardIterator __res) {
return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2)) _ValueType2(std::move(__val1));
},
__is_vector, __is_parallel);
return __pstl::__internal::__pattern_walk2_n(std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
[](_ReferenceType1 __val1, _ReferenceType2 __val2) {
::new (std::addressof(__val2))
_ValueType2(std::move(__val1));
},
__is_vector, __is_parallel);
});
}
@ -164,28 +163,28 @@ uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forward
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__internal::__invoke_if_else(std::is_arithmetic<_ValueType>(),
[&]() {
__internal::__pattern_walk_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector);
},
__is_parallel);
},
[&]() {
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first,
__last,
[&__value](_ReferenceType __val) {
::new (std::addressof(__val)) _ValueType(__value);
},
__is_vector, __is_parallel);
});
__pstl::__internal::__invoke_if_else(
std::is_arithmetic<_ValueType>(),
[&]() {
__pstl::__internal::__pattern_walk_brick(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__value, &__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector);
},
__is_parallel);
},
[&]() {
__pstl::__internal::__pattern_walk1(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
__is_parallel);
});
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
@ -194,23 +193,24 @@ uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::is_arithmetic<_ValueType>(),
[&]() {
return __internal::__pattern_walk_brick_n(
return __pstl::__internal::__pattern_walk_brick_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n,
[&__value, &__is_vector](_ForwardIterator __begin, _Size __count) {
return __internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector);
return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk1_n(
return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n,
[&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }, __is_vector,
__is_parallel);
@ -225,14 +225,16 @@ destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector, __is_parallel);
__pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() {
__pstl::__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
__is_parallel);
});
}
@ -242,17 +244,18 @@ destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n)
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); },
[&]() {
return __internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
__is_parallel);
return __pstl::__internal::__pattern_walk1_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { __val.~_ValueType(); }, __is_vector,
__is_parallel);
});
}
@ -264,15 +267,16 @@ uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __fi
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector,
__is_parallel);
__pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() {
__pstl::__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; },
__is_vector, __is_parallel);
});
}
@ -282,18 +286,19 @@ uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
[&]() {
return __internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; },
__is_vector, __is_parallel);
});
return __pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); },
[&]() {
return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }, __is_vector, __is_parallel);
});
}
// [uninitialized.construct.value]
@ -304,24 +309,26 @@ uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __firs
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
__internal::__invoke_if_else(
__pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(),
[&]() {
__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector);
},
__is_parallel);
__pstl::__internal::__pattern_walk_brick(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[__is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
__pstl::__internal::__brick_fill(__begin, __end, _ValueType(),
__is_vector);
},
__is_parallel);
},
[&]() {
__internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); },
__is_vector, __is_parallel);
__pstl::__internal::__pattern_walk1(
std::forward<_ExecutionPolicy>(__exec), __first, __last,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel);
});
}
@ -331,23 +338,24 @@ uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __fi
{
typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType;
using namespace __pstl;
const auto __is_parallel = __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector = __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_parallel =
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
const auto __is_vector =
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec);
return __internal::__invoke_if_else(
return __pstl::__internal::__invoke_if_else(
std::is_trivial<_ValueType>(),
[&]() {
return __internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
[__is_vector](_ForwardIterator __begin, _Size __count) {
return __internal::__brick_fill_n(__begin, __count,
_ValueType(), __is_vector);
},
__is_parallel);
return __pstl::__internal::__pattern_walk_brick_n(std::forward<_ExecutionPolicy>(__exec), __first, __n,
[__is_vector](_ForwardIterator __begin, _Size __count) {
return __pstl::__internal::__brick_fill_n(
__begin, __count, _ValueType(), __is_vector);
},
__is_parallel);
},
[&]() {
return __internal::__pattern_walk1_n(
return __pstl::__internal::__pattern_walk1_n(
std::forward<_ExecutionPolicy>(__exec), __first, __n,
[](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }, __is_vector, __is_parallel);
});

View File

@ -55,12 +55,13 @@ transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forward
_ForwardIterator2 __first2, _Tp __init)
{
typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType;
using namespace __pstl;
return __internal::__pattern_transform_reduce(
return __pstl::__internal::__pattern_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, std::plus<_InputType>(),
std::multiplies<_InputType>(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1,
@ -69,11 +70,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2)
{
using namespace __pstl;
return __internal::__pattern_transform_reduce(
return __pstl::__internal::__pattern_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2,
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation>
@ -81,11 +83,10 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp>
transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
_BinaryOperation __binary_op, _UnaryOperation __unary_op)
{
using namespace __pstl;
return __internal::__pattern_transform_reduce(
return __pstl::__internal::__pattern_transform_reduce(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op,
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
}
// [exclusive.scan]
@ -95,8 +96,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init)
{
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
std::plus<_Tp>(), __pstl::__internal::__no_op());
using namespace __pstl;
return __internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
std::plus<_Tp>(), /*inclusive=*/std::false_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation>
@ -104,8 +109,12 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardItera
exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op)
{
return transform_exclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __init,
__binary_op, __pstl::__internal::__no_op());
using namespace __pstl;
return __internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init,
__binary_op, /*inclusive=*/std::false_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
}
// [inclusive.scan]
@ -147,12 +156,13 @@ transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
_ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op,
_UnaryOperation __unary_op)
{
using namespace __pstl;
return __internal::__pattern_transform_scan(
return __pstl::__internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
/*inclusive=*/std::false_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
}
// [transform.inclusive.scan]
@ -164,12 +174,13 @@ transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _
_ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op,
_Tp __init)
{
using namespace __pstl;
return __internal::__pattern_transform_scan(
return __pstl::__internal::__pattern_transform_scan(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op,
/*inclusive=*/std::true_type(),
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation,
@ -202,11 +213,12 @@ adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Forwa
if (__first == __last)
return __d_first;
using namespace __pstl;
return __internal::__pattern_adjacent_difference(
return __pstl::__internal::__pattern_adjacent_difference(
std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op,
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec),
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec));
__pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec),
__pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
__exec));
}
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>

View File

@ -23,31 +23,82 @@ namespace __internal
// uninitialized_move
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
template <typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::false_type) noexcept
{
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType2;
using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
for (; __first != __last; ++__first, ++__result)
{
::new (std::addressof(*__result)) _ValueType2(std::move(*__first));
::new (std::addressof(*__result)) _ValueType(std::move(*__first));
}
return __result;
}
template <class _ForwardIterator, class _OutputIterator>
template <typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::true_type) noexcept
{
typedef typename std::iterator_traits<_OutputIterator>::value_type __ValueType2;
typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType1;
typedef typename std::iterator_traits<_OutputIterator>::reference _ReferenceType2;
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
return __unseq_backend::__simd_walk_2(
__first, __last - __first, __result,
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType2(std::move(__x)); });
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(std::move(__x)); });
}
template <typename _Iterator>
void
__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept
{
using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
for (; __first != __last; ++__first)
__first->~_ValueType();
}
template <typename _Iterator>
void
__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::true_type) noexcept
{
using _ValueType = typename std::iterator_traits<_Iterator>::value_type;
using _ReferenceType = typename std::iterator_traits<_Iterator>::reference;
__unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); });
}
//------------------------------------------------------------------------
// uninitialized copy
//------------------------------------------------------------------------
template <typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::false_type) noexcept
{
using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
for (; __first != __last; ++__first, ++__result)
{
::new (std::addressof(*__result)) _ValueType(*__first);
}
return __result;
}
template <typename _ForwardIterator, typename _OutputIterator>
_OutputIterator
__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
/*vector=*/std::true_type) noexcept
{
using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type;
using _ReferenceType1 = typename std::iterator_traits<_ForwardIterator>::reference;
using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference;
return __unseq_backend::__simd_walk_2(
__first, __last - __first, __result,
[](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(__x); });
}
} // namespace __internal

View File

@ -93,11 +93,7 @@ _Tp
__brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op,
_UnaryOperation __unary_op, /*is_vector=*/std::false_type) noexcept
{
for (; __first != __last; ++__first)
{
__init = __binary_op(__init, __unary_op(*__first));
}
return __init;
return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op);
}
template <class _ForwardIterator, class _Tp, class _UnaryOperation, class _BinaryOperation>
@ -284,7 +280,7 @@ __pattern_transform_scan(_ExecutionPolicy&& __exec, _RandomAccessIterator __firs
}) -
1);
},
[](_Tp __res) {});
[](_Tp) {});
return __result + (__last - __first);
});
}

View File

@ -12,8 +12,16 @@
#if defined(_PSTL_PAR_BACKEND_SERIAL)
# include "parallel_backend_serial.h"
namespace __pstl
{
namespace __par_backend = __serial_backend;
}
#elif defined(_PSTL_PAR_BACKEND_TBB)
# include "parallel_backend_tbb.h"
namespace __pstl
{
namespace __par_backend = __tbb_backend;
}
#else
_PSTL_PRAGMA_MESSAGE("Parallel backend was not specified");
#endif

View File

@ -18,7 +18,7 @@
namespace __pstl
{
namespace __serial
namespace __serial_backend
{
template <typename _Tp>
@ -110,10 +110,10 @@ template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _Ran
typename _RandomAccessIterator3, typename _Compare, typename _LeafMerge>
void
__parallel_merge(_ExecutionPolicy&&, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __out,
_RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _RandomAccessIterator3 __outit,
_Compare __comp, _LeafMerge __leaf_merge)
{
__leaf_merge(__first1, __last1, __first2, __last2, __out, __comp);
__leaf_merge(__first1, __last1, __first2, __last2, __outit, __comp);
}
template <class _ExecutionPolicy, typename _F1, typename _F2>
@ -124,7 +124,7 @@ __parallel_invoke(_ExecutionPolicy&&, _F1&& __f1, _F2&& __f2)
std::forward<_F2>(__f2)();
}
} // namespace __serial
} // namespace __serial_backend
} // namespace __pstl
namespace __pstl

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,8 @@
namespace __pstl
{
namespace __par_backend
namespace __utils
{
//! Destroy sequence [xs,xe)
@ -36,24 +37,28 @@ struct __serial_destroy
};
//! Merge sequences [__xs,__xe) and [__ys,__ye) to output sequence [__zs,(__xe-__xs)+(__ye-__ys)), using std::move
template <class _MoveValues, class _MoveSequences>
struct __serial_move_merge
{
const std::size_t _M_nmerge;
_MoveValues _M_move_values;
_MoveSequences _M_move_sequences;
explicit __serial_move_merge(std::size_t __nmerge, _MoveValues __move_values, _MoveSequences __move_sequences)
: _M_nmerge(__nmerge), _M_move_values(__move_values), _M_move_sequences(__move_sequences)
{
}
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare>
explicit __serial_move_merge(std::size_t __nmerge) : _M_nmerge(__nmerge) {}
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Compare,
class _MoveValueX, class _MoveValueY, class _MoveSequenceX, class _MoveSequenceY>
void
operator()(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
_RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp)
_RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp, _MoveValueX __move_value_x,
_MoveValueY __move_value_y, _MoveSequenceX __move_sequence_x, _MoveSequenceY __move_sequence_y)
{
constexpr bool __same_move_val = std::is_same<_MoveValueX, _MoveValueY>::value;
constexpr bool __same_move_seq = std::is_same<_MoveSequenceX, _MoveSequenceY>::value;
auto __n = _M_nmerge;
_PSTL_ASSERT(__n > 0);
auto __nx = __xe - __xs;
//auto __ny = __ye - __ys;
_RandomAccessIterator3 __zs_beg = __zs;
if (__xs != __xe)
{
if (__ys != __ye)
@ -62,7 +67,11 @@ struct __serial_move_merge
{
if (__comp(*__ys, *__xs))
{
_M_move_values(__ys, __zs);
const auto __i = __zs - __zs_beg;
if (__i < __nx)
__move_value_x(__ys, __zs);
else
__move_value_y(__ys, __zs);
++__zs, --__n;
if (++__ys == __ye)
{
@ -70,126 +79,179 @@ struct __serial_move_merge
}
else if (__n == 0)
{
__zs = _M_move_sequences(__ys, __ye, __zs);
const auto __j = __zs - __zs_beg;
if (__same_move_seq || __j < __nx)
__zs = __move_sequence_x(__ys, __ye, __zs);
else
__zs = __move_sequence_y(__ys, __ye, __zs);
break;
}
else
{
}
}
else
{
_M_move_values(__xs, __zs);
const auto __i = __zs - __zs_beg;
if (__same_move_val || __i < __nx)
__move_value_x(__xs, __zs);
else
__move_value_y(__xs, __zs);
++__zs, --__n;
if (++__xs == __xe)
{
_M_move_sequences(__ys, __ye, __zs);
const auto __j = __zs - __zs_beg;
if (__same_move_seq || __j < __nx)
__move_sequence_x(__ys, __ye, __zs);
else
__move_sequence_y(__ys, __ye, __zs);
return;
}
else if (__n == 0)
{
__zs = _M_move_sequences(__xs, __xe, __zs);
_M_move_sequences(__ys, __ye, __zs);
const auto __j = __zs - __zs_beg;
if (__same_move_seq || __j < __nx)
{
__zs = __move_sequence_x(__xs, __xe, __zs);
__move_sequence_x(__ys, __ye, __zs);
}
else
{
__zs = __move_sequence_y(__xs, __xe, __zs);
__move_sequence_y(__ys, __ye, __zs);
}
return;
}
else
{
}
}
}
}
__ys = __xs;
__ye = __xe;
}
_M_move_sequences(__ys, __ye, __zs);
const auto __i = __zs - __zs_beg;
if (__same_move_seq || __i < __nx)
__move_sequence_x(__ys, __ye, __zs);
else
__move_sequence_y(__ys, __ye, __zs);
}
};
template <typename _RandomAccessIterator1, typename _OutputIterator>
void
__init_buf(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _OutputIterator __zs, bool __bMove)
template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
typename _CopyConstructRange>
_OutputIterator
__set_union_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
_CopyConstructRange __cc_range)
{
const _OutputIterator __ze = __zs + (__xe - __xs);
typedef typename std::iterator_traits<_OutputIterator>::value_type _ValueType;
if (__bMove)
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
for (; __first1 != __last1; ++__result)
{
// Initialize the temporary buffer and move keys to it.
for (; __zs != __ze; ++__xs, ++__zs)
new (&*__zs) _ValueType(std::move(*__xs));
}
else
{
// Initialize the temporary buffer
for (; __zs != __ze; ++__zs)
new (&*__zs) _ValueType;
if (__first2 == __last2)
return __cc_range(__first1, __last1, __result);
if (__comp(*__first2, *__first1))
{
::new (std::addressof(*__result)) _Tp(*__first2);
++__first2;
}
else
{
::new (std::addressof(*__result)) _Tp(*__first1);
if (!__comp(*__first1, *__first2))
++__first2;
++__first1;
}
}
return __cc_range(__first2, __last2, __result);
}
// TODO is this actually used anywhere?
template <typename _Buf>
class __stack
template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare>
_OutputIterator
__set_intersection_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp)
{
typedef typename std::iterator_traits<decltype(_Buf(0).get())>::value_type _ValueType;
typedef typename std::iterator_traits<_ValueType*>::difference_type _DifferenceType;
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
_Buf _M_buf;
_ValueType* _M_ptr;
_DifferenceType _M_maxsize;
for (; __first1 != __last1 && __first2 != __last2;)
{
if (__comp(*__first1, *__first2))
++__first1;
else
{
if (!__comp(*__first2, *__first1))
{
::new (std::addressof(*__result)) _Tp(*__first1);
++__result;
++__first1;
}
++__first2;
}
}
return __result;
}
__stack(const __stack&) = delete;
void
operator=(const __stack&) = delete;
template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
typename _CopyConstructRange>
_OutputIterator
__set_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
_CopyConstructRange __cc_range)
{
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
public:
__stack(_DifferenceType __max_size) : _M_buf(__max_size), _M_maxsize(__max_size) { _M_ptr = _M_buf.get(); }
for (; __first1 != __last1;)
{
if (__first2 == __last2)
return __cc_range(__first1, __last1, __result);
~__stack()
{
_PSTL_ASSERT(size() <= _M_maxsize);
while (!empty())
pop();
if (__comp(*__first1, *__first2))
{
::new (std::addressof(*__result)) _Tp(*__first1);
++__result;
++__first1;
}
else
{
if (!__comp(*__first2, *__first1))
++__first1;
++__first2;
}
}
return __result;
}
template <typename _ForwardIterator1, typename _ForwardIterator2, typename _OutputIterator, typename _Compare,
typename _CopyConstructRange>
_OutputIterator
__set_symmetric_difference_construct(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
_ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
_CopyConstructRange __cc_range)
{
using _Tp = typename std::iterator_traits<_OutputIterator>::value_type;
const _Buf&
buffer() const
for (; __first1 != __last1;)
{
return _M_buf;
}
size_t
size() const
{
_PSTL_ASSERT(_M_ptr - _M_buf.get() <= _M_maxsize);
_PSTL_ASSERT(_M_ptr - _M_buf.get() >= 0);
return _M_ptr - _M_buf.get();
}
bool
empty() const
{
_PSTL_ASSERT(_M_ptr >= _M_buf.get());
return _M_ptr == _M_buf.get();
}
void
push(const _ValueType& __v)
{
_PSTL_ASSERT(size() < _M_maxsize);
new (_M_ptr) _ValueType(__v);
++_M_ptr;
}
const _ValueType&
top() const
{
return *(_M_ptr - 1);
}
void
pop()
{
_PSTL_ASSERT(_M_ptr > _M_buf.get());
--_M_ptr;
(*_M_ptr).~_ValueType();
}
};
if (__first2 == __last2)
return __cc_range(__first1, __last1, __result);
} // namespace __par_backend
if (__comp(*__first1, *__first2))
{
::new (std::addressof(*__result)) _Tp(*__first1);
++__result;
++__first1;
}
else
{
if (__comp(*__first2, *__first1))
{
::new (std::addressof(*__result)) _Tp(*__first2);
++__result;
}
else
++__first1;
++__first2;
}
}
return __cc_range(__first2, __last2, __result);
}
} // namespace __utils
} // namespace __pstl
#endif /* _PSTL_PARALLEL_BACKEND_UTILS_H */

View File

@ -11,13 +11,13 @@
#define _PSTL_CONFIG_H
// The version is XYYZ, where X is major, YY is minor, and Z is patch (i.e. X.YY.Z)
#define _PSTL_VERSION 9000
#define _PSTL_VERSION 12000
#define _PSTL_VERSION_MAJOR (_PSTL_VERSION / 1000)
#define _PSTL_VERSION_MINOR ((_PSTL_VERSION % 1000) / 10)
#define _PSTL_VERSION_PATCH (_PSTL_VERSION % 10)
#if !defined(_PSTL_PAR_BACKEND_SERIAL) && !defined(_PSTL_PAR_BACKEND_TBB)
# error "The parallel backend is neither serial nor TBB"
# error "A parallel backend must be specified"
#endif
// Check the user-defined macro for warnings
@ -40,6 +40,15 @@
#define _PSTL_STRING(x) _PSTL_STRING_AUX(x)
#define _PSTL_STRING_CONCAT(x, y) x #y
#ifdef _PSTL_HIDE_FROM_ABI_PER_TU
# define _PSTL_HIDE_FROM_ABI_PUSH \
_Pragma("clang attribute push(__attribute__((internal_linkage)), apply_to=any(function,record))")
# define _PSTL_HIDE_FROM_ABI_POP _Pragma("clang attribute pop")
#else
# define _PSTL_HIDE_FROM_ABI_PUSH /* nothing */
# define _PSTL_HIDE_FROM_ABI_POP /* nothing */
#endif
// note that when ICC or Clang is in use, _PSTL_GCC_VERSION might not fully match
// the actual GCC version on the system.
#define _PSTL_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
@ -50,7 +59,8 @@
#endif
// Enable SIMD for compilers that support OpenMP 4.0
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900)
#if (_OPENMP >= 201307) || (__INTEL_COMPILER >= 1600) || (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \
defined(__clang__)
# define _PSTL_PRAGMA_SIMD _PSTL_PRAGMA(omp simd)
# define _PSTL_PRAGMA_DECLARE_SIMD _PSTL_PRAGMA(omp declare simd)
# define _PSTL_PRAGMA_SIMD_REDUCTION(PRM) _PSTL_PRAGMA(omp simd reduction(PRM))
@ -70,7 +80,7 @@
# define _PSTL_PRAGMA_FORCEINLINE
#endif
#if (__INTEL_COMPILER >= 1900) || (_PSTL_GCC_VERSION >= 100000)
#if (__INTEL_COMPILER >= 1900)
# define _PSTL_PRAGMA_SIMD_SCAN(PRM) _PSTL_PRAGMA(omp simd reduction(inscan, PRM))
# define _PSTL_PRAGMA_SIMD_INCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan inclusive(PRM))
# define _PSTL_PRAGMA_SIMD_EXCLUSIVE_SCAN(PRM) _PSTL_PRAGMA(omp scan exclusive(PRM))
@ -100,11 +110,7 @@
# define _PSTL_UDR_PRESENT 0
#endif
#if ((__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626) || _PSTL_GCC_VERSION >= 100000)
# define _PSTL_UDS_PRESENT 1
#else
# define _PSTL_UDS_PRESENT 0
#endif
#define _PSTL_UDS_PRESENT (__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626)
#if _PSTL_EARLYEXIT_PRESENT
# define _PSTL_PRAGMA_SIMD_EARLYEXIT _PSTL_PRAGMA(omp simd early_exit)

View File

@ -181,7 +181,7 @@ __simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pr
_DifferenceType __i;
_PSTL_PRAGMA_VECTOR_UNALIGNED // Do not generate peel loop part
_PSTL_PRAGMA_SIMD_REDUCTION(|
: __found) for (__i = 0; __i < __block_size; ++__i)
: __found) for (__i = 0; __i < __block_size; ++__i)
{
const _DifferenceType __t = __pred(__first1[__i], __first2[__i]);
__lane[__i] = __t;
@ -189,14 +189,14 @@ __simd_first(_Index1 __first1, _DifferenceType __n, _Index2 __first2, _Pred __pr
}
if (__found)
{
_DifferenceType __i;
_DifferenceType __i2;
// This will vectorize
for (__i = 0; __i < __block_size; ++__i)
for (__i2 = 0; __i2 < __block_size; ++__i2)
{
if (__lane[__i])
if (__lane[__i2])
break;
}
return std::make_pair(__first1 + __i, __first2 + __i);
return std::make_pair(__first1 + __i2, __first2 + __i2);
}
__first1 += __block_size;
__first2 += __block_size;
@ -403,7 +403,7 @@ __simd_adjacent_find(_Index __first, _Index __last, _BinaryPredicate __pred, boo
_DifferenceType __found = 0;
_PSTL_PRAGMA_VECTOR_UNALIGNED // Do not generate peel loop part
_PSTL_PRAGMA_SIMD_REDUCTION(|
: __found) for (__i = 0; __i < __block_size - 1; ++__i)
: __found) for (__i = 0; __i < __block_size - 1; ++__i)
{
//TODO: to improve SIMD vectorization
const _DifferenceType __t = __pred(*(__first + __i), *(__first + __i + 1));
@ -486,15 +486,15 @@ __simd_transform_reduce(_Size __n, _Tp __init, _BinaryOperation __binary_op, _Un
__lane[__j] = __binary_op(__lane[__j], __f(last_iteration + __j));
}
// combiner
for (_Size __i = 0; __i < __block_size; ++__i)
for (_Size __j = 0; __j < __block_size; ++__j)
{
__init = __binary_op(__init, __lane[__i]);
__init = __binary_op(__init, __lane[__j]);
}
// destroyer
_PSTL_PRAGMA_SIMD
for (_Size __i = 0; __i < __block_size; ++__i)
for (_Size __j = 0; __j < __block_size; ++__j)
{
__lane[__i].~_Tp();
__lane[__j].~_Tp();
}
}
else
@ -796,8 +796,9 @@ __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forwa
{
for (; __first != __last; ++__first)
{
if (__unseq_backend::__simd_or(__s_first, __n2,
__internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
if (__unseq_backend::__simd_or(
__s_first, __n2,
__internal::__equal_value_by_pred<decltype(*__first), _BinaryPredicate>(*__first, __pred)))
{
return __first;
}
@ -807,10 +808,10 @@ __simd_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forwa
{
for (; __s_first != __s_last; ++__s_first)
{
const auto __result = __unseq_backend::__simd_first(__first, _DifferencType(0), __n1,
[__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
return __pred(__it[__i], *__s_first);
});
const auto __result = __unseq_backend::__simd_first(
__first, _DifferencType(0), __n1, [__s_first, &__pred](_ForwardIterator1 __it, _DifferencType __i) {
return __pred(__it[__i], *__s_first);
});
if (__result != __last)
{
return __result;
@ -825,9 +826,9 @@ _RandomAccessIterator
__simd_remove_if(_RandomAccessIterator __first, _DifferenceType __n, _UnaryPredicate __pred) noexcept
{
// find first element we need to remove
auto __current =
__unseq_backend::__simd_first(__first, _DifferenceType(0), __n,
[&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
auto __current = __unseq_backend::__simd_first(
__first, _DifferenceType(0), __n,
[&__pred](_RandomAccessIterator __it, _DifferenceType __i) { return __pred(__it[__i]); });
__n -= __current - __first;
// if we have in sequence only one element that pred(__current[1]) != false we can exit the function