From: Thomas Rodgers Date: Mon, 26 Jun 2023 18:30:21 +0000 (-0700) Subject: libstdc++: Synchronize PSTL with upstream X-Git-Tag: basepoints/gcc-15~8030 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3162ca09dbdc2ea3ff1d4b752edf76955b6d94f9;p=thirdparty%2Fgcc.git 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. --- diff --git a/libstdc++-v3/include/pstl/algorithm_fwd.h b/libstdc++-v3/include/pstl/algorithm_fwd.h index e85125c4dc70..1ba9555e2a01 100644 --- a/libstdc++-v3/include/pstl/algorithm_fwd.h +++ b/libstdc++-v3/include/pstl/algorithm_fwd.h @@ -10,6 +10,7 @@ #ifndef _PSTL_ALGORITHM_FWD_H #define _PSTL_ALGORITHM_FWD_H +#include #include #include @@ -27,20 +28,18 @@ bool __brick_any_of(const _ForwardIterator, const _ForwardIterator, _Pred, /*__is_vector=*/std::false_type) noexcept; -template +template bool -__brick_any_of(const _ForwardIterator, const _ForwardIterator, _Pred, +__brick_any_of(const _RandomAccessIterator, const _RandomAccessIterator, _Pred, /*__is_vector=*/std::true_type) noexcept; -template +template bool -__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred) noexcept; -template +template bool -__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred, _IsVector, - /*parallel=*/std::true_type); +__pattern_any_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred); //------------------------------------------------------------------------ // walk1 (pseudo) @@ -56,25 +55,22 @@ template void __brick_walk1(_RandomAccessIterator, _RandomAccessIterator, _Function, /*vector=*/std::true_type) noexcept; -template +template void -__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept; -template +template void -__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function, _IsVector, - /*parallel=*/std::true_type); +__pattern_walk1(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function); -template +template void -__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick, - /*parallel=*/std::false_type) noexcept; +__pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept; -template +template void -__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick, - /*parallel=*/std::true_type); +__pattern_walk_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Brick); //------------------------------------------------------------------------ // walk1_n @@ -88,25 +84,21 @@ template _RandomAccessIterator __brick_walk1_n(_RandomAccessIterator, _DifferenceType, _Function, /*vectorTag=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Function, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept; -template +template _RandomAccessIterator -__pattern_walk1_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function); -template +template _ForwardIterator -__pattern_walk_brick_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Brick, - /*is_parallel=*/std::false_type) noexcept; +__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept; -template +template _RandomAccessIterator -__pattern_walk_brick_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick, - /*is_parallel=*/std::true_type); +__pattern_walk_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick); //------------------------------------------------------------------------ // walk2 (pseudo) @@ -118,60 +110,60 @@ template _ForwardIterator2 __brick_walk2(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, /*vector=*/std::false_type) noexcept; -template -_ForwardIterator2 __brick_walk2(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, - /*vector=*/std::true_type) noexcept; +template +_RandomAccessIterator2 __brick_walk2(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Function, + /*vector=*/std::true_type) noexcept; template _ForwardIterator2 __brick_walk2_n(_ForwardIterator1, _Size, _ForwardIterator2, _Function, /*vector=*/std::false_type) noexcept; -template -_ForwardIterator2 __brick_walk2_n(_ForwardIterator1, _Size, _ForwardIterator2, _Function, - /*vector=*/std::true_type) noexcept; +template +_RandomAccessIterator2 __brick_walk2_n(_RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function, + /*vector=*/std::true_type) noexcept; -template +template _ForwardIterator2 -__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept; -template -_ForwardIterator2 -__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector, - /*parallel=*/std::true_type); +template +_RandomAccessIterator2 +__pattern_walk2(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _Function); -template +template _ForwardIterator2 -__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept; -template +template _RandomAccessIterator2 -__pattern_walk2_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function, _IsVector, - /*parallel=*/std::true_type); +__pattern_walk2_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, + _Function); -template +template _ForwardIterator2 -__pattern_walk2_brick(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick, - /*parallel=*/std::false_type) noexcept; +__pattern_walk2_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _Brick) noexcept; -template +template _RandomAccessIterator2 -__pattern_walk2_brick(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _Brick, - /*parallel=*/std::true_type); +__pattern_walk2_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _Brick); -template +template _ForwardIterator2 -__pattern_walk2_brick_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick, - /*parallel=*/std::false_type) noexcept; +__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept; -template +template _RandomAccessIterator2 -__pattern_walk2_brick_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick, - /*parallel=*/std::true_type); +__pattern_walk2_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, + _RandomAccessIterator2, _Brick); //------------------------------------------------------------------------ // walk3 (pseudo) @@ -188,18 +180,17 @@ _RandomAccessIterator3 __brick_walk3(_RandomAccessIterator1, _RandomAccessIterat _RandomAccessIterator3, _Function, /*vector=*/std::true_type) noexcept; -template +template _ForwardIterator3 -__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, - _Function, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, + _Function) noexcept; -template +template _RandomAccessIterator3 -__pattern_walk3(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator3, _Function, _IsVector, /*parallel=*/std::true_type); +__pattern_walk3(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator3, _Function); //------------------------------------------------------------------------ // equal @@ -213,17 +204,16 @@ template +template bool -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate, - _IsVector, /* is_parallel = */ std::false_type) noexcept; +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _BinaryPredicate) noexcept; -template +template bool -__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _BinaryPredicate, _IsVector, /* is_parallel = */ std::true_type); +__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _BinaryPredicate); template bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, _BinaryPredicate, @@ -233,17 +223,16 @@ template +template bool -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, /* is_parallel = */ std::false_type) noexcept; +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template +template bool -__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, _IsVector, /* is_parallel = */ std::true_type); +__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); //------------------------------------------------------------------------ // find_if @@ -257,15 +246,14 @@ template _RandomAccessIterator __brick_find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, /*is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; -template -_ForwardIterator -__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, _IsVector, - /*is_parallel=*/std::true_type); +template +_RandomAccessIterator +__pattern_find_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Predicate); //------------------------------------------------------------------------ // find_end @@ -276,24 +264,21 @@ _ForwardIterator1 __brick_find_end(_ForwardIterator1, _ForwardIterator1, _Forwar _BinaryPredicate, /*__is_vector=*/std::false_type) noexcept; -template -_ForwardIterator1 __brick_find_end(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator1 __brick_find_end(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _BinaryPredicate, + /*__is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator1 -__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -_ForwardIterator1 -__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/std::true_type) noexcept; +template +_RandomAccessIterator1 +__pattern_find_end(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // find_first_of @@ -304,22 +289,21 @@ _ForwardIterator1 __brick_find_first_of(_ForwardIterator1, _ForwardIterator1, _F _BinaryPredicate, /*__is_vector=*/std::false_type) noexcept; -template -_ForwardIterator1 __brick_find_first_of(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator1 __brick_find_first_of(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _BinaryPredicate, + /*__is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator1 -__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, /*is_parallel=*/std::false_type) noexcept; +__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _BinaryPredicate) noexcept; -template -_ForwardIterator1 -__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, /*is_parallel=*/std::true_type) noexcept; +template +_RandomAccessIterator1 +__pattern_find_first_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // search @@ -330,24 +314,21 @@ _ForwardIterator1 __brick_search(_ForwardIterator1, _ForwardIterator1, _ForwardI _BinaryPredicate, /*vector=*/std::false_type) noexcept; -template -_ForwardIterator1 __brick_search(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*vector=*/std::true_type) noexcept; +template +_RandomAccessIterator1 __brick_search(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _BinaryPredicate, + /*vector=*/std::true_type) noexcept; -template +template _ForwardIterator1 -__pattern_search(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _BinaryPredicate) noexcept; -template -_ForwardIterator1 -__pattern_search(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, _IsVector, - /*is_parallel=*/std::true_type) noexcept; +template +_RandomAccessIterator1 +__pattern_search(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // search_n @@ -358,24 +339,21 @@ _ForwardIterator __brick_search_n(_ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate, /*vector=*/std::false_type) noexcept; -template -_ForwardIterator -__brick_search_n(_ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate, +template +_RandomAccessIterator +__brick_search_n(_RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&, _BinaryPredicate, /*vector=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate, - _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, + _BinaryPredicate) noexcept; -template +template _RandomAccessIterator -__pattern_search_n(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&, - _BinaryPredicate, _IsVector, - /*is_parallel=*/std::true_type) noexcept; +__pattern_search_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, + const _Tp&, _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // copy_n @@ -385,8 +363,8 @@ template _OutputIterator __brick_copy_n(_ForwardIterator, _Size, _OutputIterator, /*vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_copy_n(_ForwardIterator, _Size, _OutputIterator, +template +_OutputIterator __brick_copy_n(_RandomAccessIterator, _Size, _OutputIterator, /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ @@ -417,14 +395,12 @@ _OutputIterator __brick_move(_RandomAccessIterator, _RandomAccessIterator, _Outp // swap_ranges //------------------------------------------------------------------------ template -_OutputIterator -__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept; +_OutputIterator __brick_swap_ranges(_ForwardIterator, _ForwardIterator, _OutputIterator, + /*vector=*/std::false_type) noexcept; -template -_OutputIterator -__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::true_type) noexcept; +template +_OutputIterator __brick_swap_ranges(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, + /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ // copy_if @@ -434,8 +410,8 @@ template _OutputIterator __brick_copy_if(_ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, /*vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_copy_if(_ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, +template +_OutputIterator __brick_copy_if(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryPredicate, /*vector=*/std::true_type) noexcept; template @@ -452,9 +428,9 @@ void __brick_copy_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator, bool*, /*vector=*/std::false_type) noexcept; -template +template void -__brick_copy_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator, bool* __restrict, +__brick_copy_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, bool* __restrict, /*vector=*/std::true_type) noexcept; template @@ -467,24 +443,24 @@ void __brick_partition_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, _OutputIterator2, bool*, /*vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, _IsVector, - /*parallel=*/std::false_type) noexcept; +__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, + _UnaryPredicate) noexcept; -template +template _OutputIterator -__pattern_copy_if(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryPredicate, - _IsVector, /*parallel=*/std::true_type); +__pattern_copy_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator, _UnaryPredicate); //------------------------------------------------------------------------ // count //------------------------------------------------------------------------ -template -typename std::iterator_traits<_ForwardIterator>::difference_type - __brick_count(_ForwardIterator, _ForwardIterator, _Predicate, +template +typename std::iterator_traits<_RandomAccessIterator>::difference_type + __brick_count(_RandomAccessIterator, _RandomAccessIterator, _Predicate, /* is_vector = */ std::true_type) noexcept; template @@ -492,15 +468,14 @@ typename std::iterator_traits<_ForwardIterator>::difference_type __brick_count(_ForwardIterator, _ForwardIterator, _Predicate, /* is_vector = */ std::false_type) noexcept; -template +template typename std::iterator_traits<_ForwardIterator>::difference_type -__pattern_count(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, - /* is_parallel */ std::false_type, _IsVector) noexcept; +__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; -template -typename std::iterator_traits<_ForwardIterator>::difference_type -__pattern_count(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, - /* is_parallel */ std::true_type, _IsVector); +template +typename std::iterator_traits<_RandomAccessIterator>::difference_type +__pattern_count(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Predicate); //------------------------------------------------------------------------ // unique @@ -510,37 +485,35 @@ template _ForwardIterator __brick_unique(_ForwardIterator, _ForwardIterator, _BinaryPredicate, /*is_vector=*/std::false_type) noexcept; -template -_ForwardIterator __brick_unique(_ForwardIterator, _ForwardIterator, _BinaryPredicate, - /*is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator __brick_unique(_RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, + /*is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_unique(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept; -template -_ForwardIterator -__pattern_unique(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, _IsVector, - /*is_parallel=*/std::true_type) noexcept; +template +_RandomAccessIterator +__pattern_unique(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // unique_copy //------------------------------------------------------------------------ template - _OutputIterator __brick_unique_copy(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate, +_OutputIterator __brick_unique_copy(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate, /*vector=*/std::false_type) noexcept; template _OutputIterator __brick_unique_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _BinaryPredicate, /*vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate, - _IsVector, /*parallel=*/std::false_type) noexcept; +__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, + _BinaryPredicate) noexcept; template _DifferenceType @@ -552,11 +525,11 @@ _DifferenceType __brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate, /*vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_unique_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _BinaryPredicate, _IsVector, /*parallel=*/std::true_type); +__pattern_unique_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator, _BinaryPredicate); //------------------------------------------------------------------------ // reverse @@ -566,27 +539,25 @@ template void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, /*__is_vector=*/std::false_type) noexcept; -template -void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, +template +void __brick_reverse(_RandomAccessIterator, _RandomAccessIterator, /*__is_vector=*/std::true_type) noexcept; template void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, /*is_vector=*/std::false_type) noexcept; -template -void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, +template +void __brick_reverse(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, /*is_vector=*/std::true_type) noexcept; -template +template void -__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept; -template +template void -__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator); //------------------------------------------------------------------------ // reverse_copy @@ -596,19 +567,19 @@ template _OutputIterator __brick_reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator, /*is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator, +template +_OutputIterator __brick_reverse_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, /*is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _OutputIterator) noexcept; -template +template _OutputIterator -__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_reverse_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator); //------------------------------------------------------------------------ // rotate @@ -618,19 +589,18 @@ template _ForwardIterator __brick_rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator, /*is_vector=*/std::false_type) noexcept; -template -_ForwardIterator __brick_rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator, - /*is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator __brick_rotate(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + /*is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept; -template -_ForwardIterator -__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _IsVector, - /*is_parallel=*/std::true_type); +template +_RandomAccessIterator +__pattern_rotate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator); //------------------------------------------------------------------------ // rotate_copy @@ -640,21 +610,20 @@ template _OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, /*__is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, +template +_OutputIterator __brick_rotate_copy(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator, /*__is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, - _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, + _OutputIterator) noexcept; -template +template _OutputIterator -__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, - _IsVector, - /*is_parallel=*/std::true_type); +__pattern_rotate_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _OutputIterator); //------------------------------------------------------------------------ // is_partitioned @@ -664,19 +633,18 @@ template bool __brick_is_partitioned(_ForwardIterator, _ForwardIterator, _UnaryPredicate, /*is_vector=*/std::false_type) noexcept; -template -bool __brick_is_partitioned(_ForwardIterator, _ForwardIterator, _UnaryPredicate, +template +bool __brick_is_partitioned(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /*is_vector=*/std::true_type) noexcept; -template +template bool -__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template +template bool -__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_is_partitioned(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // partition @@ -686,19 +654,18 @@ template _ForwardIterator __brick_partition(_ForwardIterator, _ForwardIterator, _UnaryPredicate, /*is_vector=*/std::false_type) noexcept; -template -_ForwardIterator __brick_partition(_ForwardIterator, _ForwardIterator, _UnaryPredicate, - /*is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator __brick_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, + /*is_vector=*/std::true_type) noexcept; -template +template _ForwardIterator -__pattern_partition(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template -_ForwardIterator -__pattern_partition(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel=*/std::true_type); +template +_RandomAccessIterator +__pattern_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // stable_partition @@ -708,21 +675,19 @@ template _BidirectionalIterator __brick_stable_partition(_BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, /*__is_vector=*/std::false_type) noexcept; -template -_BidirectionalIterator __brick_stable_partition(_BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +template +_RandomAccessIterator __brick_stable_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, + /*__is_vector=*/std::true_type) noexcept; -template +template _BidirectionalIterator -__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, - _IsVector, - /*is_parallelization=*/std::false_type) noexcept; +__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _UnaryPredicate) noexcept; -template -_BidirectionalIterator -__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, - _IsVector, - /*is_parallelization=*/std::true_type) noexcept; +template +_RandomAccessIterator +__pattern_stable_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate) noexcept; //------------------------------------------------------------------------ // partition_copy @@ -733,134 +698,123 @@ std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, _UnaryPredicate, /*is_vector=*/std::false_type) noexcept; -template -std::pair<_OutputIterator1, _OutputIterator2> - __brick_partition_copy(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, _UnaryPredicate, - /*is_vector=*/std::true_type) noexcept; +template +std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(_RandomAccessIterator, _RandomAccessIterator, + _OutputIterator1, _OutputIterator2, + _UnaryPredicate, + /*is_vector=*/std::true_type) noexcept; -template +template std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, - _UnaryPredicate, _IsVector, - /*is_parallelization=*/std::false_type) noexcept; +__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, + _OutputIterator2, _UnaryPredicate) noexcept; -template +template std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, - _OutputIterator2, _UnaryPredicate, _IsVector, - /*is_parallelization=*/std::true_type); +__pattern_partition_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _OutputIterator1, _OutputIterator2, _UnaryPredicate); //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ -template +template void -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/, - /*is_parallel=*/std::false_type, _IsMoveConstructible) noexcept; +__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, + _IsMoveConstructible) noexcept; -template +template void -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/, - /*is_parallel=*/std::true_type, +__pattern_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, /*is_move_constructible=*/std::true_type); //------------------------------------------------------------------------ // stable_sort //------------------------------------------------------------------------ -template +template void -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector /*is_vector*/, - /*is_parallel=*/std::false_type) noexcept; +__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; -template +template void -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector /*is_vector*/, - /*is_parallel=*/std::true_type); +__pattern_stable_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // partial_sort //------------------------------------------------------------------------ -template +template void -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + _Compare) noexcept; -template +template void -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_partial_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // partial_sort_copy //------------------------------------------------------------------------ -template -_RandomAccessIterator -__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator, - _RandomAccessIterator, _Compare, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +template +_RandomAccessIterator2 +__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _Compare) noexcept; -template -_RandomAccessIterator -__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator, - _RandomAccessIterator, _Compare, _IsVector, - /*is_parallel=*/std::true_type); +template +_RandomAccessIterator2 +__pattern_partial_sort_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, _Compare); //------------------------------------------------------------------------ // adjacent_find //------------------------------------------------------------------------ -template -_ForwardIterator -__brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate, - /* _IsVector = */ std::true_type, bool) noexcept; +template +_RandomAccessIterator +__brick_adjacent_find(_RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, + /* IsVector = */ std::true_type, bool) noexcept; template _ForwardIterator __brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate, - /* _IsVector = */ std::false_type, bool) noexcept; + /* IsVector = */ std::false_type, bool) noexcept; -template +template _ForwardIterator -__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, - /* is_parallel */ std::false_type, _IsVector, bool) noexcept; +__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, bool) noexcept; -template +template _RandomAccessIterator -__pattern_adjacent_find(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, - /* is_parallel */ std::true_type, _IsVector, bool); +__pattern_adjacent_find(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _BinaryPredicate, bool); //------------------------------------------------------------------------ // nth_element //------------------------------------------------------------------------ -template +template void -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, + _Compare) noexcept; -template +template void -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsVector, - /*is_parallel=*/std::true_type) noexcept; +__pattern_nth_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare) noexcept; //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ -template +template void -__brick_fill(_ForwardIterator, _ForwardIterator, const _Tp&, +__brick_fill(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, /* __is_vector = */ std::true_type) noexcept; template @@ -868,19 +822,17 @@ void __brick_fill(_ForwardIterator, _ForwardIterator, const _Tp&, /* __is_vector = */ std::false_type) noexcept; -template +template void -__pattern_fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&, - /*is_parallel=*/std::false_type, _IsVector) noexcept; +__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept; -template -_ForwardIterator -__pattern_fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&, - /*is_parallel=*/std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_fill(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, const _Tp&); -template -_OutputIterator -__brick_fill_n(_OutputIterator, _Size, const _Tp&, +template +_RandomAccessIterator +__brick_fill_n(_RandomAccessIterator, _Size, const _Tp&, /* __is_vector = */ std::true_type) noexcept; template @@ -888,15 +840,13 @@ _OutputIterator __brick_fill_n(_OutputIterator, _Size, const _Tp&, /* __is_vector = */ std::false_type) noexcept; -template +template _OutputIterator -__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&, - /*is_parallel=*/std::false_type, _IsVector) noexcept; +__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept; -template -_OutputIterator -__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&, - /*is_parallel=*/std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_fill_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, const _Tp&); //------------------------------------------------------------------------ // generate, generate_n @@ -910,33 +860,30 @@ template void __brick_generate(_ForwardIterator, _ForwardIterator, _Generator, /* is_vector = */ std::false_type) noexcept; -template +template void -__pattern_generate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator, - /*is_parallel=*/std::false_type, _IsVector) noexcept; +__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept; -template -_ForwardIterator -__pattern_generate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator, - /*is_parallel=*/std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_generate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Generator); -template - _OutputIterator __brick_generate_n(_OutputIterator, _Size, _Generator, - /* is_vector = */ std::true_type) noexcept; +template +_RandomAccessIterator __brick_generate_n(_RandomAccessIterator, _Size, _Generator, + /* is_vector = */ std::true_type) noexcept; template - _OutputIterator __brick_generate_n(_OutputIterator, _Size, _Generator, +_OutputIterator __brick_generate_n(_OutputIterator, _Size, _Generator, /* is_vector = */ std::false_type) noexcept; -template - _OutputIterator -__pattern_generate_n(_ExecutionPolicy&&, _OutputIterator, _Size, _Generator, - /*is_parallel=*/std::false_type, _IsVector) noexcept; +template +_OutputIterator +__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, _Generator) noexcept; -template - _OutputIterator -__pattern_generate_n(_ExecutionPolicy&&, _OutputIterator, _Size, _Generator, - /*is_parallel=*/std::true_type, _IsVector); +template +_RandomAccessIterator +__pattern_generate_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Generator); //------------------------------------------------------------------------ // remove @@ -949,15 +896,14 @@ template _RandomAccessIterator __brick_remove_if(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, /* __is_vector = */ std::true_type) noexcept; -template +template _ForwardIterator -__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel*/ std::false_type) noexcept; +__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; -template -_ForwardIterator -__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector, - /*is_parallel*/ std::true_type) noexcept; +template +_RandomAccessIterator +__pattern_remove_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _UnaryPredicate) noexcept; //------------------------------------------------------------------------ // merge @@ -968,23 +914,22 @@ _OutputIterator __brick_merge(_ForwardIterator1, _ForwardIterator1, _ForwardIter _OutputIterator, _Compare, /* __is_vector = */ std::false_type) noexcept; -template -_OutputIterator __brick_merge(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, +template +_OutputIterator __brick_merge(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _OutputIterator, _Compare, /* __is_vector = */ std::true_type) noexcept; -template +template _OutputIterator -__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /* is_parallel = */ std::false_type) noexcept; +__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _OutputIterator, _Compare) noexcept; -template +template _OutputIterator -__pattern_merge(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector, - /* is_parallel = */ std::true_type); +__pattern_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); //------------------------------------------------------------------------ // inplace_merge @@ -994,37 +939,34 @@ template void __brick_inplace_merge(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Compare, /* __is_vector = */ std::false_type) noexcept; -template -void __brick_inplace_merge(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Compare, +template +void __brick_inplace_merge(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ std::true_type) noexcept; -template +template void -__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, - _Compare, _IsVector, - /* is_parallel = */ std::false_type) noexcept; +__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, + _BidirectionalIterator, _Compare) noexcept; -template +template void -__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, - _Compare, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_inplace_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // includes //------------------------------------------------------------------------ -template +template bool -__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _Compare) noexcept; -template +template bool -__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_includes(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _Compare); //------------------------------------------------------------------------ // set_union @@ -1035,22 +977,22 @@ _OutputIterator __brick_set_union(_ForwardIterator1, _ForwardIterator1, _Forward _OutputIterator, _Compare, /*__is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_set_union(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, +template +_OutputIterator __brick_set_union(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::false_type) noexcept; +__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template +template _OutputIterator -__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type); +__pattern_set_union(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); //------------------------------------------------------------------------ // set_intersection @@ -1061,23 +1003,23 @@ _OutputIterator __brick_set_intersection(_ForwardIterator1, _ForwardIterator1, _ _OutputIterator, _Compare, /*__is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_set_intersection(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, +template +_OutputIterator __brick_set_intersection(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template +template _OutputIterator -__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type); +__pattern_set_intersection(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, + _Compare); //------------------------------------------------------------------------ // set_difference @@ -1088,22 +1030,22 @@ _OutputIterator __brick_set_difference(_ForwardIterator1, _ForwardIterator1, _Fo _OutputIterator, _Compare, /*__is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_set_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, +template +_OutputIterator __brick_set_difference(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::false_type) noexcept; +__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template +template _OutputIterator -__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type); +__pattern_set_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); //------------------------------------------------------------------------ // set_symmetric_difference @@ -1114,24 +1056,23 @@ _OutputIterator __brick_set_symmetric_difference(_ForwardIterator1, _ForwardIter _ForwardIterator2, _OutputIterator, _Compare, /*__is_vector=*/std::false_type) noexcept; -template -_OutputIterator __brick_set_symmetric_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, +template +_OutputIterator __brick_set_symmetric_difference(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _OutputIterator, _Compare, /*__is_vector=*/std::true_type) noexcept; -template +template _OutputIterator -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/std::false_type) noexcept; +__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _OutputIterator, _Compare) noexcept; -template +template _OutputIterator -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, _IsVector, - /*is_parallel=*/std::true_type); +__pattern_set_symmetric_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _OutputIterator, _Compare); //------------------------------------------------------------------------ // is_heap_until @@ -1145,15 +1086,14 @@ template _RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare, /* __is_vector = */ std::true_type) noexcept; -template +template _RandomAccessIterator -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ std::false_type) noexcept; +__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; -template +template _RandomAccessIterator -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ std::true_type) noexcept; +__pattern_is_heap_until(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare) noexcept; //------------------------------------------------------------------------ // min_element @@ -1163,19 +1103,18 @@ template _ForwardIterator __brick_min_element(_ForwardIterator, _ForwardIterator, _Compare, /* __is_vector = */ std::false_type) noexcept; -template -_ForwardIterator __brick_min_element(_ForwardIterator, _ForwardIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +template +_RandomAccessIterator __brick_min_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, + /* __is_vector = */ std::true_type) noexcept; -template +template _ForwardIterator -__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector, - /* is_parallel = */ std::false_type) noexcept; +__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; -template +template _RandomAccessIterator -__pattern_min_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector, - /* is_parallel = */ std::true_type); +__pattern_min_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // minmax_element @@ -1185,19 +1124,19 @@ template std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(_ForwardIterator, _ForwardIterator, _Compare, /* __is_vector = */ std::false_type) noexcept; -template -std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(_ForwardIterator, _ForwardIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +template +std::pair<_RandomAccessIterator, _RandomAccessIterator> + __brick_minmax_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, + /* __is_vector = */ std::true_type) noexcept; -template +template std::pair<_ForwardIterator, _ForwardIterator> -__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector, - /* is_parallel = */ std::false_type) noexcept; +__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; -template -std::pair<_ForwardIterator, _ForwardIterator> -__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector, - /* is_parallel = */ std::true_type); +template +std::pair<_RandomAccessIterator, _RandomAccessIterator> +__pattern_minmax_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // mismatch @@ -1208,22 +1147,22 @@ std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(_ForwardIterato _ForwardIterator2, _ForwardIterator2, _Predicate, /* __is_vector = */ std::false_type) noexcept; -template -std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(_ForwardIterator1, _ForwardIterator1, - _ForwardIterator2, _ForwardIterator2, _Predicate, - /* __is_vector = */ std::true_type) noexcept; +template +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> + __brick_mismatch(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _Predicate, + /* __is_vector = */ std::true_type) noexcept; -template +template std::pair<_ForwardIterator1, _ForwardIterator2> -__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Predicate, _IsVector, - /* is_parallel = */ std::false_type) noexcept; +__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, + _Predicate) noexcept; -template +template std::pair<_RandomAccessIterator1, _RandomAccessIterator2> -__pattern_mismatch(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Predicate, _IsVector, /* is_parallel = */ std::true_type) noexcept; +__pattern_mismatch(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, + _RandomAccessIterator2, _RandomAccessIterator2, _Predicate) noexcept; //------------------------------------------------------------------------ // lexicographical_compare @@ -1234,20 +1173,22 @@ bool __brick_lexicographical_compare(_ForwardIterator1, _ForwardIterator1, _Forw _Compare, /* __is_vector = */ std::false_type) noexcept; -template -bool __brick_lexicographical_compare(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare, +template +bool __brick_lexicographical_compare(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, + _RandomAccessIterator2, _Compare, /* __is_vector = */ std::true_type) noexcept; -template +template bool -__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _Compare, _IsVector, /* is_parallel = */ std::false_type) noexcept; +__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, + _ForwardIterator2, _Compare) noexcept; -template +template bool -__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _Compare, _IsVector, /* is_parallel = */ std::true_type) noexcept; +__pattern_lexicographical_compare(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, + _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, + _Compare) noexcept; } // namespace __internal } // namespace __pstl diff --git a/libstdc++-v3/include/pstl/algorithm_impl.h b/libstdc++-v3/include/pstl/algorithm_impl.h index 32c19990ed0f..aec8c7484e72 100644 --- a/libstdc++-v3/include/pstl/algorithm_impl.h +++ b/libstdc++-v3/include/pstl/algorithm_impl.h @@ -41,33 +41,35 @@ __brick_any_of(const _ForwardIterator __first, const _ForwardIterator __last, _P return std::any_of(__first, __last, __pred); }; -template +template bool -__brick_any_of(const _ForwardIterator __first, const _ForwardIterator __last, _Pred __pred, +__brick_any_of(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _Pred __pred, /*__is_vector=*/std::true_type) noexcept { return __unseq_backend::__simd_or(__first, __last - __first, __pred); }; -template +template bool -__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred, - _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) noexcept { - return __internal::__brick_any_of(__first, __last, __pred, __is_vector); + return __internal::__brick_any_of(__first, __last, __pred, typename _Tag::__is_vector{}); } -template +template bool -__pattern_any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred, - _IsVector __is_vector, /*parallel=*/std::true_type) +__pattern_any_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Pred __pred) { - return __internal::__except_handler([&]() { - return __internal::__parallel_or(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred, __is_vector](_ForwardIterator __i, _ForwardIterator __j) { - return __internal::__brick_any_of(__i, __j, __pred, __is_vector); - }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + return __internal::__parallel_or(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) + { return __internal::__brick_any_of(__i, __j, __pred, _IsVector{}); }); + }); } // [alg.foreach] @@ -102,46 +104,51 @@ __brick_walk1(_RandomAccessIterator __first, _RandomAccessIterator __last, _Func __unseq_backend::__simd_walk_1(__first, __last - __first, __f); } -template +template void -__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/std::false_type) noexcept +__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept { - __internal::__brick_walk1(__first, __last, __f, __is_vector); + __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{}); } -template +template void -__pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f, - _IsVector __is_vector, - /*parallel=*/std::true_type) -{ - __internal::__except_handler([&]() { - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__f, __is_vector](_ForwardIterator __i, _ForwardIterator __j) { - __internal::__brick_walk1(__i, __j, __f, __is_vector); - }); - }); +__pattern_walk1(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Function __f) +{ + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) + { __internal::__brick_walk1(__i, __j, __f, _IsVector{}); }); + }); } -template +template void -__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick, - /*parallel=*/std::false_type) noexcept +__pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Brick __brick) noexcept { __brick(__first, __last); } -template +template void -__pattern_walk_brick(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick, - /*parallel=*/std::true_type) +__pattern_walk_brick(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Brick __brick) { - __internal::__except_handler([&]() { - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__brick](_ForwardIterator __i, _ForwardIterator __j) { __brick(__i, __j); }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) + { __brick(__i, __j); }); + }); } //------------------------------------------------------------------------ @@ -163,44 +170,45 @@ __brick_walk1_n(_RandomAccessIterator __first, _DifferenceType __n, _Function __ return __unseq_backend::__simd_walk_1(__first, __n, __f); } -template +template _ForwardIterator -__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f, _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept { - return __internal::__brick_walk1_n(__first, __n, __f, __is_vector); + return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator -__pattern_walk1_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Function __f, - _IsVector __is_vector, - /*is_parallel=*/std::true_type) +__pattern_walk1_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, + _Function __f) { - __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f, __is_vector, - std::true_type()); + __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f); + return __first + __n; } -template +template _ForwardIterator -__pattern_walk_brick_n(_ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick, - /*is_parallel=*/std::false_type) noexcept +__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept { return __brick(__first, __n); } -template +template _RandomAccessIterator -__pattern_walk_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Brick __brick, - /*is_parallel=*/std::true_type) +__pattern_walk_brick_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _Size __n, _Brick __brick) { - return __internal::__except_handler([&]() { - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, - [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); }); - return __first + __n; - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); }); + return __first + __n; + }); } //------------------------------------------------------------------------ @@ -218,9 +226,10 @@ __brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIte return __first2; } -template -_ForwardIterator2 -__brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f, +template +_RandomAccessIterator2 +__brick_walk2(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _Function __f, /*vector=*/std::true_type) noexcept { return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f); @@ -236,102 +245,115 @@ __brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first return __first2; } -template -_ForwardIterator2 -__brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f, +template +_RandomAccessIterator2 +__brick_walk2_n(_RandomAccessIterator1 __first1, _Size __n, _RandomAccessIterator2 __first2, _Function __f, /*vector=*/std::true_type) noexcept { return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f); } -template +template _ForwardIterator2 -__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _Function __f, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _Function __f) noexcept { - return __internal::__brick_walk2(__first1, __last1, __first2, __f, __is_vector); + return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{}); } -template -_ForwardIterator2 -__pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_walk2(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Function __f) { - return __internal::__except_handler([&]() { - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, __is_vector); - }); - return __first2 + (__last1 - __first1); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{}); }); + return __first2 + (__last1 - __first1); + }); } -template +template _ForwardIterator2 -__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f, - _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, + _Function __f) noexcept { - return __internal::__brick_walk2_n(__first1, __n, __first2, __f, __is_vector); + return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator2 -__pattern_walk2_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n, _RandomAccessIterator2 __first2, - _Function __f, _IsVector __is_vector, /*parallel=*/std::true_type) +__pattern_walk2_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _Size __n, _RandomAccessIterator2 __first2, _Function __f) { - return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f, - __is_vector, std::true_type()); + return __internal::__pattern_walk2(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + __first2, __f); } -template +template _ForwardIterator2 -__pattern_walk2_brick(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick, /*parallel=*/std::false_type) noexcept +__pattern_walk2_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _Brick __brick) noexcept { return __brick(__first1, __last1, __first2); } -template +template _RandomAccessIterator2 -__pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/std::true_type) +__pattern_walk2_brick(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Brick __brick) { - return __internal::__except_handler([&]() { - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __brick(__i, __j, __first2 + (__i - __first1)); - }); - return __first2 + (__last1 - __first1); - }); -} + using __backend_tag = typename decltype(__tag)::__backend_tag; -template -_RandomAccessIterator2 -__pattern_walk2_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n, - _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/std::true_type) -{ - return __internal::__except_handler([&]() { - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __brick(__i, __j - __i, __first2 + (__i - __first1)); - }); - return __first2 + __n; - }); + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { __brick(__i, __j, __first2 + (__i - __first1)); }); + return __first2 + (__last1 - __first1); + }); } -template +template _ForwardIterator2 -__pattern_walk2_brick_n(_ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Brick __brick, /*parallel=*/std::false_type) noexcept +__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, + _Brick __brick) noexcept { return __brick(__first1, __n, __first2); } +template +_RandomAccessIterator2 +__pattern_walk2_brick_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _Size __n, _RandomAccessIterator2 __first2, _Brick __brick) +{ + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { __brick(__i, __j - __i, __first2 + (__i - __first1)); }); + return __first2 + __n; + }); +} + //------------------------------------------------------------------------ // walk3 (pseudo) // @@ -355,31 +377,35 @@ __brick_walk3(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f); } -template +template _ForwardIterator3 -__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator3 __first3, _Function __f, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) noexcept { - return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, __is_vector); + return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator3 -__pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, _Function __f, _IsVector __is_vector, - /*parallel=*/std::true_type) +__pattern_walk3(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, + _Function __f) { - return __internal::__except_handler([&]() { - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2, __first3, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __internal::__brick_walk3(__i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, - __is_vector); - }); - return __first3 + (__last1 - __first1); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __internal::__brick_walk3(__i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, + _IsVector{}); + }); + return __first3 + (__last1 - __first1); + }); } //------------------------------------------------------------------------ @@ -405,34 +431,37 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; } -template +template bool -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ - std::false_type) noexcept +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __p) noexcept { - return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, __is_vector); + return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{}); } -template +template bool -__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __p, - _IsVector __is_vector, /*is_parallel=*/std::true_type) +__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _BinaryPredicate __p) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__last1 - __first1 != __last2 - __first2) return false; - return __internal::__except_handler([&]() { - return !__internal::__parallel_or( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - __p, __is_vector); - }); - }); + return __internal::__except_handler( + [&]() + { + return !__internal::__parallel_or( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { + return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), + __first2 + (__j - __first1), __p, _IsVector{}); + }); + }); } //------------------------------------------------------------------------ @@ -455,29 +484,30 @@ __brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _ return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; } -template +template bool -__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept +__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __p) noexcept { - return __internal::__brick_equal(__first1, __last1, __first2, __p, __is_vector); + return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{}); } -template +template bool -__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _BinaryPredicate __p, _IsVector __is_vector, - /*is_parallel=*/std::true_type) +__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _BinaryPredicate __p) { - return __internal::__except_handler([&]() { - return !__internal::__parallel_or( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, __is_vector); - }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + return !__internal::__parallel_or( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{}); }); + }); } //------------------------------------------------------------------------ @@ -502,30 +532,31 @@ __brick_find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _Pr [&__pred](_RandomAccessIterator __it, _SizeType __i) { return __pred(__it[__i]); }); } -template +template _ForwardIterator -__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_find_if(_Tag __tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Predicate __pred) noexcept { - return __internal::__brick_find_if(__first, __last, __pred, __is_vector); + return __internal::__brick_find_if(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - _IsVector __is_vector, - /*is_parallel=*/std::true_type) +template +_RandomAccessIterator +__pattern_find_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Predicate __pred) { - return __internal::__except_handler([&]() { - return __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred, __is_vector](_ForwardIterator __i, _ForwardIterator __j) { - return __internal::__brick_find_if(__i, __j, __pred, __is_vector); - }, - std::less::difference_type>(), - /*is_first=*/true); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + return __internal::__parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) + { return __internal::__brick_find_if(__i, __j, __pred, _IsVector{}); }, + std::less::difference_type>(), + /*is_first=*/true); + }); } //------------------------------------------------------------------------ @@ -632,48 +663,51 @@ __brick_find_end(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIt return std::find_end(__first, __last, __s_first, __s_last, __pred); } -template -_ForwardIterator1 -__brick_find_end(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__brick_find_end(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept { return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type()); } -template +template _ForwardIterator1 -__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, __is_vector); + return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); } -template -_ForwardIterator1 -__pattern_find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__pattern_find_end(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__last - __first == __s_last - __s_first) { - const bool __res = __internal::__pattern_equal(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred, __is_vector, std::true_type()); + const bool __res = __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, + __s_first, __pred); return __res ? __first : __last; } else { - return __internal::__except_handler([&]() { - return __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, - __is_vector); - }, - std::greater::difference_type>(), /*is_first=*/false); - }); + return __internal::__except_handler( + [&]() + { + return __internal::__parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, + _IsVector{}); + }, + std::greater::difference_type>(), + /*is_first=*/false); + }); } } @@ -688,95 +722,99 @@ __brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _Forw return std::find_first_of(__first, __last, __s_first, __s_last, __pred); } -template -_ForwardIterator1 -__brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__brick_find_first_of(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept { return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred); } -template +template _ForwardIterator1 -__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, __is_vector); + return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, + typename _Tag::__is_vector{}); } -template -_ForwardIterator1 -__pattern_find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__pattern_find_first_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__except_handler([&]() { - return __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, __is_vector); - }, - std::less::difference_type>(), /*is_first=*/true); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + return __internal::__parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{}); }, + std::less::difference_type>(), /*is_first=*/true); + }); } //------------------------------------------------------------------------ // search //------------------------------------------------------------------------ -template -_ForwardIterator1 -__brick_search(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept +template +_RandomAccessIterator1 +__brick_search(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept { return std::search(__first, __last, __s_first, __s_last, __pred); } -template -_ForwardIterator1 -__brick_search(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__brick_search(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept { return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type()); } -template +template _ForwardIterator1 -__pattern_search(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept { - return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, __is_vector); + return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); } -template -_ForwardIterator1 -__pattern_search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred, - _IsVector __is_vector, - /*is_parallel=*/std::true_type) noexcept +template +_RandomAccessIterator1 +__pattern_search(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__last - __first == __s_last - __s_first) { - const bool __res = __internal::__pattern_equal(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred, __is_vector, std::true_type()); + const bool __res = __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, + __s_first, __pred); return __res ? __first : __last; } else { - return __internal::__except_handler([&]() { - return __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, - __is_vector); - }, - std::less::difference_type>(), /*is_first=*/true); - }); + return __internal::__except_handler( + [&]() + { + return __internal::__parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, + _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); } } @@ -791,49 +829,49 @@ __brick_search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __coun return std::search_n(__first, __last, __count, __value, __pred); } -template -_ForwardIterator -__brick_search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, +template +_RandomAccessIterator +__brick_search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept { return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type()); } -template +template _ForwardIterator -__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count, + const _Tp& __value, _BinaryPredicate __pred) noexcept { - return __internal::__brick_search_n(__first, __last, __count, __value, __pred, __is_vector); + return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator -__pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector, - /*is_parallel=*/std::true_type) noexcept +__pattern_search_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (static_cast<_Size>(__last - __first) == __count) { - const bool __result = !__internal::__pattern_any_of( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }, __is_vector, - /*is_parallel*/ std::true_type()); + const bool __result = + !__internal::__pattern_any_of(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }); return __result ? __first : __last; } else { - return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred, __is_vector]() { - return __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __count, &__value, __pred, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, __is_vector); - }, - std::less::difference_type>(), /*is_first=*/true); - }); + return __internal::__except_handler( + [&__exec, __first, __last, __count, &__value, __pred]() + { + return __internal::__parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) + { return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{}); }, + std::less::difference_type>(), + /*is_first=*/true); + }); } } @@ -848,12 +886,14 @@ __brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /* return std::copy_n(__first, __n, __result); } -template -_OutputIterator -__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::true_type) noexcept +template +_RandomAccessIterator2 +__brick_copy_n(_RandomAccessIterator1 __first, _Size __n, _RandomAccessIterator2 __result, + /*vector=*/std::true_type) noexcept { return __unseq_backend::__simd_assign( - __first, __n, __result, [](_ForwardIterator __first, _OutputIterator __result) { *__result = *__first; }); + __first, __n, __result, + [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = *__first; }); } //------------------------------------------------------------------------ @@ -867,14 +907,14 @@ __brick_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator return std::copy(__first, __last, __result); } -template -_OutputIterator -__brick_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, +template +_RandomAccessIterator2 +__brick_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, /*vector=*/std::true_type) noexcept { return __unseq_backend::__simd_assign( __first, __last - __first, __result, - [](_RandomAccessIterator __first, _OutputIterator __result) { *__result = *__first; }); + [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = *__first; }); } //------------------------------------------------------------------------ @@ -888,36 +928,38 @@ __brick_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator return std::move(__first, __last, __result); } -template -_OutputIterator -__brick_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, +template +_RandomAccessIterator2 +__brick_move(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, /*vector=*/std::true_type) noexcept { return __unseq_backend::__simd_assign( __first, __last - __first, __result, - [](_RandomAccessIterator __first, _OutputIterator __result) { *__result = std::move(*__first); }); + [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = std::move(*__first); }); } struct __brick_move_destroy { - template - _OutputIterator - operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::true_type) const + template + _RandomAccessIterator2 + operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, + /*vec*/ std::true_type) const { - using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type; + using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; return __unseq_backend::__simd_assign(__first, __last - __first, __result, - [](_Iterator __first, _OutputIterator __result) { + [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = std::move(*__first); (*__first).~_IteratorValueType(); }); } - template - _OutputIterator - operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::false_type) const + template + _RandomAccessIterator2 + operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, + /*vec*/ std::false_type) const { - using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type; + using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; for (; __first != __last; ++__first, ++__result) { @@ -939,14 +981,14 @@ __brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIt return std::swap_ranges(__first, __last, __result); } -template -_OutputIterator -__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, +template +_RandomAccessIterator2 +__brick_swap_ranges(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, /*vector=*/std::true_type) noexcept { using std::iter_swap; return __unseq_backend::__simd_assign(__first, __last - __first, __result, - iter_swap<_ForwardIterator, _OutputIterator>); + iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>); } //------------------------------------------------------------------------ @@ -960,12 +1002,13 @@ __brick_copy_if(_ForwardIterator __first, _ForwardIterator __last, _OutputIterat return std::copy_if(__first, __last, __result, __pred); } -template -_OutputIterator -__brick_copy_if(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _UnaryPredicate __pred, +template +_RandomAccessIterator2 +__brick_copy_if(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, + _UnaryPredicate __pred, /*vector=*/std::true_type) noexcept { -#if (_PSTL_MONOTONIC_PRESENT) +#if defined(_PSTL_MONOTONIC_PRESENT) return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred); #else return std::copy_if(__first, __last, __result, __pred); @@ -981,7 +1024,7 @@ __brick_calc_mask_1(_ForwardIterator __first, _ForwardIterator __last, bool* __r auto __count_true = _DifferenceType(0); auto __size = __last - __first; - static_assert(__is_random_access_iterator<_ForwardIterator>::value, + static_assert(__are_random_access_iterators<_ForwardIterator>::value, "Pattern-brick error. Should be a random access iterator."); for (; __first != __last; ++__first, ++__mask) @@ -1019,12 +1062,12 @@ __brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputI } } -template +template void -__brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, +__brick_copy_by_mask(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, bool* __restrict __mask, _Assigner __assigner, /*vector=*/std::true_type) noexcept { -#if (_PSTL_MONOTONIC_PRESENT) +#if defined(_PSTL_MONOTONIC_PRESENT) __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner); #else __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type()); @@ -1051,67 +1094,72 @@ __brick_partition_by_mask(_ForwardIterator __first, _ForwardIterator __last, _Ou } } -template +template void -__brick_partition_by_mask(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator1 __out_true, - _OutputIterator2 __out_false, bool* __mask, /*vector=*/std::true_type) noexcept +__brick_partition_by_mask(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, + _RandomAccessIterator2 __out_true, _RandomAccessIterator3 __out_false, bool* __mask, + /*vector=*/std::true_type) noexcept { -#if (_PSTL_MONOTONIC_PRESENT) +#if defined(_PSTL_MONOTONIC_PRESENT) __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask); #else __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type()); #endif } -template +template _OutputIterator -__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _UnaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_copy_if(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _OutputIterator __result, _UnaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_copy_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _UnaryPredicate __pred) { - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const _DifferenceType __n = __last - __first; if (_DifferenceType(1) < __n) { __par_backend::__buffer __mask_buf(__n); - return __internal::__except_handler([&__exec, __n, __first, __result, __is_vector, __pred, &__mask_buf]() { - bool* __mask = __mask_buf.get(); - _DifferenceType __m{}; - __par_backend::__parallel_strict_scan( - std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector) - .first; - }, - std::plus<_DifferenceType>(), // Combine - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan - __internal::__brick_copy_by_mask( - __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator __x, _OutputIterator __z) { *__z = *__x; }, __is_vector); - }, - [&__m](_DifferenceType __total) { __m = __total; }); - return __result + __m; - }); + return __internal::__except_handler( + [&__exec, __n, __first, __result, __pred, &__mask_buf]() + { + bool* __mask = __mask_buf.get(); + _DifferenceType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), + __mask + __i, __pred, _IsVector{}) + .first; + }, + std::plus<_DifferenceType>(), // Combine + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan + __internal::__brick_copy_by_mask( + __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, _IsVector{}); + }, + [&__m](_DifferenceType __total) { __m = __total; }); + return __result + __m; + }); } // trivial sequence - use serial algorithm - return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ // count //------------------------------------------------------------------------ -template -typename std::iterator_traits<_ForwardIterator>::difference_type -__brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, +template +typename std::iterator_traits<_RandomAccessIterator>::difference_type +__brick_count(_RandomAccessIterator __first, _RandomAccessIterator __last, _Predicate __pred, /* is_vector = */ std::true_type) noexcept { return __unseq_backend::__simd_count(__first, __last - __first, __pred); @@ -1125,66 +1173,70 @@ __brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pr return std::count_if(__first, __last, __pred); } -template +template typename std::iterator_traits<_ForwardIterator>::difference_type -__pattern_count(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - /* is_parallel */ std::false_type, _IsVector __is_vector) noexcept +__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept { - return __internal::__brick_count(__first, __last, __pred, __is_vector); + return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -typename std::iterator_traits<_ForwardIterator>::difference_type -__pattern_count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - /* is_parallel */ std::true_type, _IsVector __is_vector) +template +typename std::iterator_traits<_RandomAccessIterator>::difference_type +__pattern_count(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Predicate __pred) { - typedef typename std::iterator_traits<_ForwardIterator>::difference_type _SizeType; - return __internal::__except_handler([&]() { - return __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0), - [__pred, __is_vector](_ForwardIterator __begin, _ForwardIterator __end, _SizeType __value) -> _SizeType { - return __value + __internal::__brick_count(__begin, __end, __pred, __is_vector); - }, - std::plus<_SizeType>()); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; + return __internal::__except_handler( + [&]() + { + return __par_backend::__parallel_reduce( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0), + [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType + { return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{}); }, + std::plus<_SizeType>()); + }); } //------------------------------------------------------------------------ // unique //------------------------------------------------------------------------ -template -_ForwardIterator -__brick_unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, +template +_RandomAccessIterator +__brick_unique(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, /*is_vector=*/std::false_type) noexcept { return std::unique(__first, __last, __pred); } -template -_ForwardIterator -__brick_unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, +template +_RandomAccessIterator +__brick_unique(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, /*is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::unique(__first, __last, __pred); } -template +template _ForwardIterator -__pattern_unique(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __pred) noexcept { - return __internal::__brick_unique(__first, __last, __pred, __is_vector); + return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{}); } // That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a mask calculation is different. // So, a caller passes _CalcMask brick into remove_elements. -template +template _ForwardIterator -__remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _CalcMask __calc_mask, - _IsVector __is_vector) +__remove_elements(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, + _ForwardIterator __last, _CalcMask __calc_mask) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType; typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp; _DifferenceType __n = __last - __first; @@ -1193,9 +1245,10 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI return __internal::__except_handler([&]() { bool* __mask = __mask_buf.get(); _DifferenceType __min = __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n, - [__first, __mask, &__calc_mask, __is_vector](_DifferenceType __i, _DifferenceType __j, - _DifferenceType __local_min) -> _DifferenceType { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n, + [__first, __mask, &__calc_mask](_DifferenceType __i, _DifferenceType __j, + _DifferenceType __local_min) -> _DifferenceType + { // Create mask __calc_mask(__mask + __i, __mask + __j, __first + __i); @@ -1205,17 +1258,16 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI return __local_min; } // find first iterator that should be removed - bool* __result = __internal::__brick_find_if(__mask + __i, __mask + __j, - [](bool __val) { return !__val; }, __is_vector); + bool* __result = __internal::__brick_find_if( + __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{}); if (__result - __mask == __j) { return __local_min; } return std::min(__local_min, _DifferenceType(__result - __mask)); }, - [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType { - return std::min(__local_min1, __local_min2); - }); + [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType + { return std::min(__local_min1, __local_min2); }); // No elements to remove - exit if (__min == __n) @@ -1231,44 +1283,46 @@ __remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardI _DifferenceType __m{}; // 2. Elements that doesn't satisfy pred are moved to result __par_backend::__parallel_strict_scan( - std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [__mask, __is_vector](_DifferenceType __i, _DifferenceType __len) { - return __internal::__brick_count(__mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, - __is_vector); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + [__mask](_DifferenceType __i, _DifferenceType __len) + { + return __internal::__brick_count( + __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{}); }, std::plus<_DifferenceType>(), - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) + { __internal::__brick_copy_by_mask( __first + __i, __first + __i + __len, __result + __initial, __mask + __i, - [](_ForwardIterator __x, _Tp* __z) { - __internal::__invoke_if_else(std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, - [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); + [](_ForwardIterator __x, _Tp* __z) + { + __internal::__invoke_if_else( + std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, + [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); }, - __is_vector); + _IsVector{}); }, [&__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) { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, + [__result, __first](_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); - }); + std::is_trivial<_Tp>(), [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); }, + [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); }); }); return __first + __m; }); } -template -_ForwardIterator -__pattern_unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept +template +_RandomAccessIterator +__pattern_unique(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _BinaryPredicate __pred) noexcept { - typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; if (__first == __last) { @@ -1277,16 +1331,16 @@ __pattern_unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt if (__first + 1 == __last || __first + 2 == __last) { // Trivial sequence - use serial algorithm - return __internal::__brick_unique(__first, __last, __pred, __is_vector); + return __internal::__brick_unique(__first, __last, __pred, _IsVector{}); } return __internal::__remove_elements( - std::forward<_ExecutionPolicy>(__exec), ++__first, __last, - [&__pred, __is_vector](bool* __b, bool* __e, _ForwardIterator __it) { + __tag, std::forward<_ExecutionPolicy>(__exec), ++__first, __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) + { __internal::__brick_walk3( __b, __e, __it - 1, __it, - [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, __is_vector); - }, - __is_vector); + [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -1294,32 +1348,31 @@ __pattern_unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIt //------------------------------------------------------------------------ template - _OutputIterator +_OutputIterator __brick_unique_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept { return std::unique_copy(__first, __last, __result, __pred); } -template - _OutputIterator -__brick_unique_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, +template +_RandomAccessIterator2 +__brick_unique_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept { -#if (_PSTL_MONOTONIC_PRESENT) +#if defined(_PSTL_MONOTONIC_PRESENT) return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred); #else return std::unique_copy(__first, __last, __result, __pred); #endif } -template +template _OutputIterator -__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _BinaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept +__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator __result, _BinaryPredicate __pred) noexcept { - return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{}); } template @@ -1344,54 +1397,58 @@ __brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred); } -template -_OutputIterator -__pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _OutputIterator __result, _BinaryPredicate __pred, _IsVector __is_vector, - /*parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_unique_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _BinaryPredicate __pred) { - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const _DifferenceType __n = __last - __first; if (_DifferenceType(2) < __n) { __par_backend::__buffer __mask_buf(__n); if (_DifferenceType(2) < __n) { - return __internal::__except_handler([&__exec, __n, __first, __result, __pred, __is_vector, &__mask_buf]() { - bool* __mask = __mask_buf.get(); - _DifferenceType __m{}; - __par_backend::__parallel_strict_scan( - std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce - _DifferenceType __extra = 0; - if (__i == 0) - { - // Special boundary case - __mask[__i] = true; - if (--__len == 0) - return 1; - ++__i; - ++__extra; - } - return __internal::__brick_calc_mask_2<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector) + - __extra; - }, - std::plus<_DifferenceType>(), // Combine - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan - // Phase 2 is same as for __pattern_copy_if - __internal::__brick_copy_by_mask( - __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator __x, _OutputIterator __z) { *__z = *__x; }, __is_vector); - }, - [&__m](_DifferenceType __total) { __m = __total; }); - return __result + __m; - }); + return __internal::__except_handler( + [&__exec, __n, __first, __result, __pred, &__mask_buf]() + { + bool* __mask = __mask_buf.get(); + _DifferenceType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), + [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce + _DifferenceType __extra = 0; + if (__i == 0) + { + // Special boundary case + __mask[__i] = true; + if (--__len == 0) + return 1; + ++__i; + ++__extra; + } + return __internal::__brick_calc_mask_2<_DifferenceType>( + __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) + + __extra; + }, + std::plus<_DifferenceType>(), // Combine + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan + // Phase 2 is same as for __pattern_copy_if + __internal::__brick_copy_by_mask( + __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, + _IsVector{}); + }, + [&__m](_DifferenceType __total) { __m = __total; }); + return __result + __m; + }); } } // trivial sequence - use serial algorithm - return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector); + return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ @@ -1404,14 +1461,14 @@ __brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, / std::reverse(__first, __last); } -template +template void -__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::true_type) noexcept +__brick_reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept { - typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; const auto __n = (__last - __first) / 2; - __unseq_backend::__simd_walk_2(__first, __n, std::reverse_iterator<_BidirectionalIterator>(__last), + __unseq_backend::__simd_walk_2(__first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), [](_ReferenceType __x, _ReferenceType __y) { using std::swap; swap(__x, __y); @@ -1432,39 +1489,38 @@ __brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _ } // this brick is called in parallel version, so we can use iterator arithmetic -template +template void -__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _BidirectionalIterator __d_last, +__brick_reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __d_last, /*is_vector=*/std::true_type) noexcept { - typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; - __unseq_backend::__simd_walk_2(__first, __last - __first, std::reverse_iterator<_BidirectionalIterator>(__d_last), + __unseq_backend::__simd_walk_2(__first, __last - __first, std::reverse_iterator<_RandomAccessIterator>(__d_last), [](_ReferenceType __x, _ReferenceType __y) { using std::swap; swap(__x, __y); }); } -template +template void -__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept { - __internal::__brick_reverse(__first, __last, __is_vector); + __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{}); } -template +template void -__pattern_reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _IsVector __is_vector, /*is_parallel=*/std::true_type) +__pattern_reverse(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2, - [__is_vector, __first, __last](_BidirectionalIterator __inner_first, _BidirectionalIterator __inner_last) { - __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), __is_vector); - }); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2, + [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) + { __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{}); }); } //------------------------------------------------------------------------ @@ -1479,39 +1535,41 @@ __brick_reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __la return std::reverse_copy(__first, __last, __d_first); } -template -_OutputIterator -__brick_reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __d_first, +template +_RandomAccessIterator2 +__brick_reverse_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, /*is_vector=*/std::true_type) noexcept { - typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType1; - typedef typename std::iterator_traits<_OutputIterator>::reference _ReferenceType2; + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; - return __unseq_backend::__simd_walk_2(std::reverse_iterator<_BidirectionalIterator>(__last), __last - __first, + return __unseq_backend::__simd_walk_2(std::reverse_iterator<_RandomAccessIterator1>(__last), __last - __first, __d_first, [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; }); } -template +template _OutputIterator -__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _OutputIterator __d_first, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, + _OutputIterator __d_first) noexcept { - return __internal::__brick_reverse_copy(__first, __last, __d_first, __is_vector); + return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _OutputIterator __d_first, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_reverse_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + auto __len = __last - __first; - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__is_vector, __first, __len, __d_first](_BidirectionalIterator __inner_first, - _BidirectionalIterator __inner_last) { - __internal::__brick_reverse_copy(__inner_first, __inner_last, - __d_first + (__len - (__inner_last - __first)), - __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) + { + __internal::__brick_reverse_copy(__inner_first, __inner_last, + __d_first + (__len - (__inner_last - __first)), _IsVector{}); + }); return __d_first + __len; } @@ -1523,7 +1581,7 @@ _ForwardIterator __brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, /*is_vector=*/std::false_type) noexcept { -#if _PSTL_CPP11_STD_ROTATE_BROKEN +#if defined(_PSTL_CPP11_STD_ROTATE_BROKEN) std::rotate(__first, __middle, __last); return std::next(__first, std::distance(__middle, __last)); #else @@ -1531,14 +1589,14 @@ __brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIter #endif } -template -_ForwardIterator -__brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, +template +_RandomAccessIterator +__brick_rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, /*is_vector=*/std::true_type) noexcept { auto __n = __last - __first; auto __m = __middle - __first; - const _ForwardIterator __ret = __first + (__last - __middle); + const _RandomAccessIterator __ret = __first + (__last - __middle); bool __is_left = (__m <= __n / 2); if (!__is_left) @@ -1553,7 +1611,7 @@ __brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIter for (; __last - __first >= __m_2; __first += __m) { __unseq_backend::__simd_assign(__first, __m, __first + __m, - iter_swap<_ForwardIterator, _ForwardIterator>); + iter_swap<_RandomAccessIterator, _RandomAccessIterator>); } } else @@ -1561,7 +1619,7 @@ __brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIter for (; __last - __first >= __m_2; __last -= __m) { __unseq_backend::__simd_assign(__last - __m, __m, __last - __m_2, - iter_swap<_ForwardIterator, _ForwardIterator>); + iter_swap<_RandomAccessIterator, _RandomAccessIterator>); } } __is_left = !__is_left; @@ -1572,73 +1630,73 @@ __brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIter return __ret; } -template +template _ForwardIterator -__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last) noexcept { - return __internal::__brick_rotate(__first, __middle, __last, __is_vector); + return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, - _ForwardIterator __last, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator +__pattern_rotate(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last) { - typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp; + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; auto __n = __last - __first; auto __m = __middle - __first; if (__m <= __n / 2) { __par_backend::__buffer<_Tp> __buf(__n - __m); - return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() { - _Tp* __result = __buf.get(); - __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__middle, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) { - __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), __is_vector); - }); + return __internal::__except_handler( + [&__exec, __n, __m, __first, __middle, __last, &__buf]() + { + _Tp* __result = __buf.get(); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __middle, __last, + [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) + { __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{}); }); - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__last, __middle, __is_vector](_ForwardIterator __b, _ForwardIterator __e) { - __internal::__brick_move(__b, __e, __b + (__last - __middle), - __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, + [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) + { __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{}); }); - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m), - [__first, __result, __is_vector](_Tp* __b, _Tp* __e) { - __brick_move_destroy()( - __b, __e, __first + (__b - __result), __is_vector); - }); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m), + [__first, __result](_Tp* __b, _Tp* __e) + { __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{}); }); - return __first + (__last - __middle); - }); + return __first + (__last - __middle); + }); } else { __par_backend::__buffer<_Tp> __buf(__m); - return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() { - _Tp* __result = __buf.get(); - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__first, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) { - __internal::__brick_uninitialized_move( - __b, __e, __result + (__b - __first), __is_vector); - }); - - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__first, __middle, __is_vector](_ForwardIterator __b, _ForwardIterator __e) { - __internal::__brick_move(__b, __e, __first + (__b - __middle), - __is_vector); - }); - - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, - [__n, __m, __first, __result, __is_vector](_Tp* __b, _Tp* __e) { - __brick_move_destroy()( - __b, __e, __first + ((__n - __m) + (__b - __result)), __is_vector); - }); - - return __first + (__last - __middle); - }); + return __internal::__except_handler( + [&__exec, __n, __m, __first, __middle, __last, &__buf]() + { + _Tp* __result = __buf.get(); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, + [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) + { __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{}); }); + + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __middle, __last, + [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) + { __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{}); }); + + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, + [__n, __m, __first, __result](_Tp* __b, _Tp* __e) + { __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{}); }); + + return __first + (__last - __middle); + }); } } @@ -1654,47 +1712,49 @@ __brick_rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _Forwar return std::rotate_copy(__first, __middle, __last, __result); } -template -_OutputIterator -__brick_rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _OutputIterator __result, /*__is_vector=*/std::true_type) noexcept +template +_RandomAccessIterator2 +__brick_rotate_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, /*__is_vector=*/std::true_type) noexcept { - _OutputIterator __res = __internal::__brick_copy(__middle, __last, __result, std::true_type()); + _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type()); return __internal::__brick_copy(__first, __middle, __res, std::true_type()); } -template +template _OutputIterator -__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _OutputIterator __result, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, + _ForwardIterator __last, _OutputIterator __result) noexcept { - return __internal::__brick_rotate_copy(__first, __middle, __last, __result, __is_vector); + return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, - _ForwardIterator __last, _OutputIterator __result, _IsVector __is_vector, - /*is_parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_rotate_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __last, __middle, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) + { if (__b > __middle) { - __internal::__brick_copy(__b, __e, __result + (__b - __middle), __is_vector); + __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{}); } else { - _OutputIterator __new_result = __result + ((__last - __middle) + (__b - __first)); + _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first)); if (__e < __middle) { - __internal::__brick_copy(__b, __e, __new_result, __is_vector); + __internal::__brick_copy(__b, __e, __new_result, _IsVector{}); } else { - __internal::__brick_copy(__b, __middle, __new_result, __is_vector); - __internal::__brick_copy(__middle, __e, __result, __is_vector); + __internal::__brick_copy(__b, __middle, __new_result, _IsVector{}); + __internal::__brick_copy(__middle, __e, __result, _IsVector{}); } } }); @@ -1713,21 +1773,21 @@ __brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _Unary return std::is_partitioned(__first, __last, __pred); } -template +template bool -__brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, +__brick_is_partitioned(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, /*is_vector=*/std::true_type) noexcept { - typedef typename std::iterator_traits<_ForwardIterator>::difference_type _SizeType; + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; if (__first == __last) { return true; } else { - _ForwardIterator __result = __unseq_backend::__simd_first( + _RandomAccessIterator __result = __unseq_backend::__simd_first( __first, _SizeType(0), __last - __first, - [&__pred](_ForwardIterator __it, _SizeType __i) { return !__pred(__it[__i]); }); + [&__pred](_RandomAccessIterator __it, _SizeType __i) { return !__pred(__it[__i]); }); if (__result == __last) { return true; @@ -1740,18 +1800,18 @@ __brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _Unary } } -template +template bool -__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_is_partitioned(__first, __last, __pred, __is_vector); + return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{}); } -template +template bool -__pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/std::true_type) +__pattern_is_partitioned(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { if (__first == __last) { @@ -1759,6 +1819,8 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F } else { + using __backend_tag = typename decltype(__tag)::__backend_tag; + return __internal::__except_handler([&]() { // State of current range: // broken - current range is not partitioned by pred @@ -1782,9 +1844,10 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F __broken, __broken, __true_false, __broken}; __init = __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [&__pred, &__table, __is_vector](_ForwardIterator __i, _ForwardIterator __j, - _ReduceType __value) -> _ReduceType { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [&__pred, &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, + _ReduceType __value) -> _ReduceType + { if (__value == __broken) { return __broken; @@ -1794,12 +1857,12 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F if (__pred(*__i)) { // find first element that don't satisfy pred - _ForwardIterator __x = - __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), __is_vector); + _RandomAccessIterator __x = + __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{}); if (__x != __j) { // find first element after "x" that satisfy pred - _ForwardIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, __is_vector); + _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{}); // if it was found then range isn't partitioned by pred if (__y != __j) { @@ -1819,7 +1882,7 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F { // if first element doesn't satisfy pred // then we should find the first element that satisfy pred. // If we found it then range isn't partitioned by pred - if (__internal::__brick_find_if(__i + 1, __j, __pred, __is_vector) != __j) + if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) { return __broken; } @@ -1832,7 +1895,8 @@ __pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _F return (__value == -1) ? __res : __table[__value * 4 + __res]; }, - [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType { + [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType + { if (__val1 == __broken || __val2 == __broken) { return __broken; @@ -1857,43 +1921,45 @@ __brick_partition(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredi return std::partition(__first, __last, __pred); } -template -_ForwardIterator -__brick_partition(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, +template +_RandomAccessIterator +__brick_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, /*is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::partition(__first, __last, __pred); } -template +template _ForwardIterator -__pattern_partition(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept +__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_partition(__first, __last, __pred, __is_vector); + return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator +__pattern_partition(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; // partitioned range: elements before pivot satisfy pred (true part), // elements after pivot don't satisfy pred (false part) struct _PartitionRange { - _ForwardIterator __begin; - _ForwardIterator __pivot; - _ForwardIterator __end; + _RandomAccessIterator __begin; + _RandomAccessIterator __pivot; + _RandomAccessIterator __end; }; return __internal::__except_handler([&]() { _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [&__exec, __is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange + { auto __size1 = __val1.__end - __val1.__pivot; auto __size2 = __val2.__pivot - __val2.__begin; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); @@ -1908,10 +1974,10 @@ __pattern_partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwar else if (__size2 > __size1) { __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1, - [__val1, __val2, __size1, __is_vector](_ForwardIterator __i, _ForwardIterator __j) { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1, + [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) { __internal::__brick_swap_ranges(__i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), - __is_vector); + _IsVector{}); }); return {__new_begin, __val2.__pivot - __size1, __val2.__end}; } @@ -1919,20 +1985,21 @@ __pattern_partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Forwar else { __par_backend::__parallel_for( - std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2, - [__val1, __val2, __is_vector](_ForwardIterator __i, _ForwardIterator __j) { - __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), __is_vector); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2, + [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{}); }); return {__new_begin, __val1.__pivot + __size2, __val2.__end}; } }; _PartitionRange __result = __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [__pred, __is_vector, __reductor](_ForwardIterator __i, _ForwardIterator __j, - _PartitionRange __value) -> _PartitionRange { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, + _PartitionRange __value) -> _PartitionRange + { //1. serial partition - _ForwardIterator __pivot = __internal::__brick_partition(__i, __j, __pred, __is_vector); + _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{}); // 2. merging of two ranges (left and right respectively) return __reductor(__value, {__i, __pivot, __j}); @@ -1954,44 +2021,45 @@ __brick_stable_partition(_BidirectionalIterator __first, _BidirectionalIterator return std::stable_partition(__first, __last, __pred); } -template -_BidirectionalIterator -__brick_stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred, +template +_RandomAccessIterator +__brick_stable_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::stable_partition(__first, __last, __pred); } -template +template _BidirectionalIterator -__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, - /*is_parallelization=*/std::false_type) noexcept +__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_stable_partition(__first, __last, __pred, __is_vector); + return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -_BidirectionalIterator -__pattern_stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, - /*is_parallelization=*/std::true_type) noexcept +template +_RandomAccessIterator +__pattern_stable_partition(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + // partitioned range: elements before pivot satisfy pred (true part), // elements after pivot don't satisfy pred (false part) struct _PartitionRange { - _BidirectionalIterator __begin; - _BidirectionalIterator __pivot; - _BidirectionalIterator __end; + _RandomAccessIterator __begin; + _RandomAccessIterator __pivot; + _RandomAccessIterator __end; }; return __internal::__except_handler([&]() { _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [__is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange + { auto __size1 = __val1.__end - __val1.__pivot; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); @@ -2004,17 +2072,18 @@ __pattern_stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __f // then we should swap the false part of left range and last part of true part of right range else { - __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, __is_vector); + __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{}); return {__new_begin, __val2.__pivot - __size1, __val2.__end}; } }; _PartitionRange __result = __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [&__pred, __is_vector, __reductor](_BidirectionalIterator __i, _BidirectionalIterator __j, - _PartitionRange __value) -> _PartitionRange { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [&__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, + _PartitionRange __value) -> _PartitionRange + { //1. serial stable_partition - _BidirectionalIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, __is_vector); + _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{}); // 2. merging of two ranges (left and right respectively) return __reductor(__value, {__i, __pivot, __j}); @@ -2036,170 +2105,190 @@ __brick_partition_copy(_ForwardIterator __first, _ForwardIterator __last, _Outpu return std::partition_copy(__first, __last, __out_true, __out_false, __pred); } -template -std::pair<_OutputIterator1, _OutputIterator2> -__brick_partition_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true, - _OutputIterator2 __out_false, _UnaryPredicate __pred, /*is_vector=*/std::true_type) noexcept +template +std::pair<_RandomAccessIterator2, _RandomAccessIterator3> +__brick_partition_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, _UnaryPredicate __pred, + /*is_vector=*/std::true_type) noexcept { -#if (_PSTL_MONOTONIC_PRESENT) +#if defined(_PSTL_MONOTONIC_PRESENT) return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred); #else return std::partition_copy(__first, __last, __out_true, __out_false, __pred); #endif } -template +template std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallelization=*/std::false_type) noexcept +__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept { - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector); + return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, + typename _Tag::__is_vector{}); } -template -std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallelization=*/std::true_type) +template +std::pair<_RandomAccessIterator2, _RandomAccessIterator3> +__pattern_partition_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, _UnaryPredicate __pred) { - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType; const _DifferenceType __n = __last - __first; if (_DifferenceType(1) < __n) { __par_backend::__buffer __mask_buf(__n); - return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __is_vector, __pred, - &__mask_buf]() { - bool* __mask = __mask_buf.get(); - _ReturnType __m{}; - __par_backend::__parallel_strict_scan( - std::forward<_ExecutionPolicy>(__exec), __n, std::make_pair(_DifferenceType(0), _DifferenceType(0)), - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, __is_vector); - }, - [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType { - return std::make_pair(__x.first + __y.first, __x.second + __y.second); - }, // Combine - [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan - __internal::__brick_partition_by_mask(__first + __i, __first + (__i + __len), - __out_true + __initial.first, __out_false + __initial.second, - __mask + __i, __is_vector); - }, - [&__m](_ReturnType __total) { __m = __total; }); - return std::make_pair(__out_true + __m.first, __out_false + __m.second); - }); + return __internal::__except_handler( + [&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() + { + bool* __mask = __mask_buf.get(); + _ReturnType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, + std::make_pair(_DifferenceType(0), _DifferenceType(0)), + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), + __mask + __i, __pred, _IsVector{}); + }, + [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType + { return std::make_pair(__x.first + __y.first, __x.second + __y.second); }, // Combine + [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan + __internal::__brick_partition_by_mask( + __first + __i, __first + (__i + __len), __out_true + __initial.first, + __out_false + __initial.second, __mask + __i, _IsVector{}); + }, + [&__m](_ReturnType __total) { __m = __total; }); + return std::make_pair(__out_true + __m.first, __out_false + __m.second); + }); } // trivial sequence - use serial algorithm - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector); + return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{}); } //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ -template +template void -__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/std::false_type, _IsMoveConstructible) noexcept +__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, + _IsMoveConstructible) noexcept { std::sort(__first, __last, __comp); } -template +template void -__pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/std::true_type, /*is_move_constructible=*/std::true_type) +__pattern_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp, /*is_move_constructible=*/std::true_type) { - __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); }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler( + [&]() + { + __par_backend::__parallel_stable_sort( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) + { std::sort(__first, __last, __comp); }); + }); } //------------------------------------------------------------------------ // stable_sort //------------------------------------------------------------------------ -template +template void -__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsVector /*is_vector*/, /*is_parallel=*/std::false_type) noexcept +__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) noexcept { std::stable_sort(__first, __last, __comp); } -template +template void -__pattern_stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector /*is_vector*/, /*is_parallel=*/std::true_type) +__pattern_stable_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { - __internal::__except_handler([&]() { - __par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [](_RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) { std::stable_sort(__first, __last, __comp); }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler( + [&]() + { + __par_backend::__parallel_stable_sort( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) + { std::stable_sort(__first, __last, __comp); }); + }); } //------------------------------------------------------------------------ // partial_sort //------------------------------------------------------------------------ -template +template void -__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp, _IsVector, - /*is_parallel=*/std::false_type) noexcept +__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle, + _RandomAccessIterator __last, _Compare __comp) noexcept { std::partial_sort(__first, __middle, __last, __comp); } -template +template void -__pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp, _IsVector, /*is_parallel=*/std::true_type) +__pattern_partial_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + const auto __n = __middle - __first; if (__n == 0) return; - __internal::__except_handler([&]() { - __par_backend::__parallel_stable_sort( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) { - if (__n < __end - __begin) - std::partial_sort(__begin, __begin + __n, __end, __comp); - else - std::sort(__begin, __end, __comp); - }, - __n); - }); + __internal::__except_handler( + [&]() + { + __par_backend::__parallel_stable_sort( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, + [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) + { + if (__n < __end - __begin) + std::partial_sort(__begin, __begin + __n, __end, __comp); + else + std::sort(__begin, __end, __comp); + }, + __n); + }); } //------------------------------------------------------------------------ // partial_sort_copy //------------------------------------------------------------------------ -template +template _RandomAccessIterator -__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp, _IsVector, - /*is_parallel=*/std::false_type) noexcept +__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) noexcept { return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp); } -template -_RandomAccessIterator -__pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp, - _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator2 +__pattern_partial_sort_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, + _RandomAccessIterator2 __d_last, _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__last == __first || __d_last == __d_first) { return __d_first; @@ -2210,18 +2299,18 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, if (__n2 >= __n1) { __par_backend::__parallel_stable_sort( - std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp, - [__first, __d_first, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j, - _Compare __comp) { - _ForwardIterator __i1 = __first + (__i - __d_first); - _ForwardIterator __j1 = __first + (__j - __d_first); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp, + [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) + { + _RandomAccessIterator1 __i1 = __first + (__i - __d_first); + _RandomAccessIterator1 __j1 = __first + (__j - __d_first); // 1. Copy elements from input to output -# if !_PSTL_ICC_18_OMP_SIMD_BROKEN - __internal::__brick_copy(__i1, __j1, __i, __is_vector); -# else +#if !defined(_PSTL_ICC_18_OMP_SIMD_BROKEN) + __internal::__brick_copy(__i1, __j1, __i, _IsVector{}); +#else std::copy(__i1, __j1, __i); -# endif +#endif // 2. Sort elements in output sequence std::sort(__i, __j, __comp); }, @@ -2230,38 +2319,38 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, } else { - typedef typename std::iterator_traits<_ForwardIterator>::value_type _T1; - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _T2; + typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2; __par_backend::__buffer<_T1> __buf(__n1); _T1* __r = __buf.get(); - __par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp, - [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) { - _ForwardIterator __it = __first + (__i - __r); + __par_backend::__parallel_stable_sort( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp, + [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) + { + _RandomAccessIterator1 __it = __first + (__i - __r); - // 1. Copy elements from input to raw memory - for (_T1* __k = __i; __k != __j; ++__k, ++__it) - { - ::new (__k) _T2(*__it); - } + // 1. Copy elements from input to raw memory + for (_T1* __k = __i; __k != __j; ++__k, ++__it) + { + ::new (__k) _T2(*__it); + } - // 2. Sort elements in temporary __buffer - if (__n2 < __j - __i) - std::partial_sort(__i, __i + __n2, __j, __comp); - else - std::sort(__i, __j, __comp); - }, - __n2); + // 2. Sort elements in temporary __buffer + if (__n2 < __j - __i) + std::partial_sort(__i, __i + __n2, __j, __comp); + else + std::sort(__i, __j, __comp); + }, + __n2); // 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) { - __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); }); + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2, + [__r, __d_first](_T1* __i, _T1* __j) + { __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{}); }); + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, + __r + __n1, + [](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, _IsVector{}); }); return __d_first + __n2; } @@ -2271,9 +2360,9 @@ __pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, //------------------------------------------------------------------------ // adjacent_find //------------------------------------------------------------------------ -template -_ForwardIterator -__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, +template +_RandomAccessIterator +__brick_adjacent_find(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, /* IsVector = */ std::true_type, bool __or_semantic) noexcept { return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic); @@ -2287,78 +2376,79 @@ __brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _Binary return std::adjacent_find(__first, __last, __pred); } -template +template _ForwardIterator -__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - /* is_parallel */ std::false_type, _IsVector __is_vector, bool __or_semantic) noexcept +__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _BinaryPredicate __pred, bool __or_semantic) noexcept { - return __internal::__brick_adjacent_find(__first, __last, __pred, __is_vector, __or_semantic); + return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic); } -template +template _RandomAccessIterator -__pattern_adjacent_find(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _BinaryPredicate __pred, /* is_parallel */ std::true_type, _IsVector __is_vector, - bool __or_semantic) +__pattern_adjacent_find(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _BinaryPredicate __pred, bool __or_semantic) { if (__last - __first < 2) return __last; - return __internal::__except_handler([&]() { - return __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __last, - [__last, __pred, __is_vector, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end, - _RandomAccessIterator __value) -> _RandomAccessIterator { - // TODO: investigate performance benefits from the use of shared variable for the result, - // checking (compare_and_swap idiom) its __value at __first. - if (__or_semantic && __value < __last) - { //found - __par_backend::__cancel_execution(); - return __value; - } + using __backend_tag = typename decltype(__tag)::__backend_tag; - if (__value > __begin) + return __internal::__except_handler( + [&]() + { + return __par_backend::__parallel_reduce( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __last, + [__last, __pred, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end, + _RandomAccessIterator __value) -> _RandomAccessIterator { - // modify __end to check the predicate on the boundary __values; - // TODO: to use a custom range with boundaries overlapping - // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1) - // then check the pair [__last-1, __last) - if (__end != __last) - ++__end; - - //correct the global result iterator if the "brick" returns a local "__last" - const _RandomAccessIterator __res = - __internal::__brick_adjacent_find(__begin, __end, __pred, __is_vector, __or_semantic); - if (__res < __end) - __value = __res; - } - return __value; - }, - [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator { - return __x < __y ? __x : __y; - } //reduce a __value - ); - }); + // TODO: investigate performance benefits from the use of shared variable for the result, + // checking (compare_and_swap idiom) its __value at __first. + if (__or_semantic && __value < __last) + { //found + __par_backend::__cancel_execution(); + return __value; + } + + if (__value > __begin) + { + // modify __end to check the predicate on the boundary __values; + // TODO: to use a custom range with boundaries overlapping + // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1) + // then check the pair [__last-1, __last) + if (__end != __last) + ++__end; + + //correct the global result iterator if the "brick" returns a local "__last" + const _RandomAccessIterator __res = + __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic); + if (__res < __end) + __value = __res; + } + return __value; + }, + [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator + { return __x < __y ? __x : __y; } //reduce a __value + ); + }); } //------------------------------------------------------------------------ // nth_element //------------------------------------------------------------------------ -template +template void -__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp, _IsVector, - /*is_parallel=*/std::false_type) noexcept +__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth, + _RandomAccessIterator __last, _Compare __comp) noexcept { std::nth_element(__first, __nth, __last, __comp); } -template +template void -__pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/std::true_type) noexcept +__pattern_nth_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) noexcept { if (__first == __last || __nth == __last) { @@ -2370,10 +2460,8 @@ __pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __x; do { - __x = __internal::__pattern_partition(std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, - [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); }, - __is_vector, - /*is_parallel=*/std::true_type()); + __x = __internal::__pattern_partition(__tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, + [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); }); --__x; if (__x != __first) { @@ -2404,9 +2492,9 @@ __pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ -template +template void -__brick_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, +__brick_fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, /* __is_vector = */ std::true_type) noexcept { __unseq_backend::__simd_fill_n(__first, __last - __first, __value); @@ -2420,31 +2508,34 @@ __brick_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val std::fill(__first, __last, __value); } -template +template void -__pattern_fill(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, - /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept +__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept { - __internal::__brick_fill(__first, __last, __value, __is_vector); + __internal::__brick_fill(__first, __last, __value, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, - /*is_parallel=*/std::true_type, _IsVector __is_vector) -{ - return __internal::__except_handler([&__exec, __first, __last, &__value, __is_vector]() { - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value, __is_vector](_ForwardIterator __begin, _ForwardIterator __end) { - __internal::__brick_fill(__begin, __end, __value, __is_vector); - }); - return __last; - }); +template +_RandomAccessIterator +__pattern_fill(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, const _Tp& __value) +{ + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&__exec, __first, __last, &__value]() + { + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__value](_RandomAccessIterator __begin, _RandomAccessIterator __end) + { __internal::__brick_fill(__begin, __end, __value, _IsVector{}); }); + return __last; + }); } -template -_OutputIterator -__brick_fill_n(_OutputIterator __first, _Size __count, const _Tp& __value, /* __is_vector = */ std::true_type) noexcept +template +_RandomAccessIterator +__brick_fill_n(_RandomAccessIterator __first, _Size __count, const _Tp& __value, + /* __is_vector = */ std::true_type) noexcept { return __unseq_backend::__simd_fill_n(__first, __count, __value); } @@ -2456,21 +2547,20 @@ __brick_fill_n(_OutputIterator __first, _Size __count, const _Tp& __value, /* __ return std::fill_n(__first, __count, __value); } -template +template _OutputIterator -__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value, - /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept +__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value) noexcept { - return __internal::__brick_fill_n(__first, __count, __value, __is_vector); + return __internal::__brick_fill_n(__first, __count, __value, typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_fill_n(_ExecutionPolicy&& __exec, _OutputIterator __first, _Size __count, const _Tp& __value, - /*is_parallel=*/std::true_type, _IsVector __is_vector) +template +_RandomAccessIterator +__pattern_fill_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _Size __count, const _Tp& __value) { - return __internal::__pattern_fill(std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __value, - std::true_type(), __is_vector); + return __internal::__pattern_fill(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, + __value); } //------------------------------------------------------------------------ @@ -2492,59 +2582,61 @@ __brick_generate(_ForwardIterator __first, _ForwardIterator __last, _Generator _ std::generate(__first, __last, __g); } -template +template void -__pattern_generate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g, - /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept +__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept { - __internal::__brick_generate(__first, __last, __g, __is_vector); + __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g, - /*is_parallel=*/std::true_type, _IsVector __is_vector) +template +_RandomAccessIterator +__pattern_generate(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Generator __g) { - return __internal::__except_handler([&]() { - __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__g, __is_vector](_ForwardIterator __begin, _ForwardIterator __end) { - __internal::__brick_generate(__begin, __end, __g, __is_vector); - }); - return __last; - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) + { __internal::__brick_generate(__begin, __end, __g, _IsVector{}); }); + return __last; + }); } -template - _OutputIterator -__brick_generate_n(_OutputIterator __first, _Size __count, _Generator __g, /* is_vector = */ std::true_type) noexcept +template +_RandomAccessIterator +__brick_generate_n(_RandomAccessIterator __first, _Size __count, _Generator __g, + /* is_vector = */ std::true_type) noexcept { return __unseq_backend::__simd_generate_n(__first, __count, __g); } template - _OutputIterator +_OutputIterator __brick_generate_n(_OutputIterator __first, _Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept { return std::generate_n(__first, __count, __g); } -template +template _OutputIterator -__pattern_generate_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g, - /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept +__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept { - return __internal::__brick_generate_n(__first, __count, __g, __is_vector); + return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_generate_n(_ExecutionPolicy&& __exec, _OutputIterator __first, _Size __count, _Generator __g, - /*is_parallel=*/std::true_type, _IsVector __is_vector) +template +_RandomAccessIterator +__pattern_generate_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _Size __count, _Generator __g) { - static_assert(__is_random_access_iterator<_OutputIterator>::value, + static_assert(__are_random_access_iterators<_RandomAccessIterator>::value, "Pattern-brick error. Should be a random access iterator."); - return __internal::__pattern_generate(std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g, - std::true_type(), __is_vector); + return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, + __g); } //------------------------------------------------------------------------ @@ -2564,41 +2656,41 @@ _RandomAccessIterator __brick_remove_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, /* __is_vector = */ std::true_type) noexcept { -#if _PSTL_MONOTONIC_PRESENT +#if defined(_PSTL_MONOTONIC_PRESENT) return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred); #else return std::remove_if(__first, __last, __pred); #endif } -template +template _ForwardIterator -__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - _IsVector __is_vector, /*is_parallel*/ std::false_type) noexcept +__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _UnaryPredicate __pred) noexcept { - return __internal::__brick_remove_if(__first, __last, __pred, __is_vector); + return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{}); } -template -_ForwardIterator -__pattern_remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel*/ std::true_type) noexcept +template +_RandomAccessIterator +__pattern_remove_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _UnaryPredicate __pred) noexcept { - typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; if (__first == __last || __first + 1 == __last) { // Trivial sequence - use serial algorithm - return __internal::__brick_remove_if(__first, __last, __pred, __is_vector); + return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{}); } return __internal::__remove_elements( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__pred, __is_vector](bool* __b, bool* __e, _ForwardIterator __it) { - __internal::__brick_walk2(__b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, - __is_vector); - }, - __is_vector); + __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) + { + __internal::__brick_walk2( + __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -2614,39 +2706,42 @@ __brick_merge(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIte return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); } -template -_OutputIterator -__brick_merge(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp, +template +_RandomAccessIterator3 +__brick_merge(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __d_first, _Compare __comp, /* __is_vector = */ std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); } -template +template _OutputIterator -__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp, _IsVector __is_vector, - /* is_parallel = */ std::false_type) noexcept +__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __d_first, + _Compare __comp) noexcept { - return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, __is_vector); + return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, + typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _OutputIterator __d_first, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type) +template +_RandomAccessIterator3 +__pattern_merge(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __d_first, _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + __par_backend::__parallel_merge( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp, - [__is_vector](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2, - _RandomAccessIterator2 __l2, _OutputIterator __f3, _Compare __comp) { - return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, __is_vector); - }); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, + __comp, + [](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2, + _RandomAccessIterator2 __l2, _RandomAccessIterator3 __f3, _Compare __comp) + { return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, _IsVector{}); }); return __d_first + (__last1 - __first1) + (__last2 - __first2); } @@ -2661,83 +2756,89 @@ __brick_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __m std::inplace_merge(__first, __middle, __last, __comp); } -template +template void -__brick_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, +__brick_inplace_merge(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp, /* __is_vector = */ std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial") std::inplace_merge(__first, __middle, __last, __comp); } -template +template void -__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp, _IsVector __is_vector, - /* is_parallel = */ std::false_type) noexcept +__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle, + _BidirectionalIterator __last, _Compare __comp) noexcept { - __internal::__brick_inplace_merge(__first, __middle, __last, __comp, __is_vector); + __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{}); } -template +template void -__pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp, _IsVector __is_vector, - /*is_parallel=*/std::true_type) +__pattern_inplace_merge(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__first == __last || __first == __middle || __middle == __last) { return; } - typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; auto __n = __last - __first; __par_backend::__buffer<_Tp> __buf(__n); _Tp* __r = __buf.get(); - __internal::__except_handler([&]() { - auto __move_values = [](_BidirectionalIterator __x, _Tp* __z) { - __internal::__invoke_if_else(std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, - [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); - }; + __internal::__except_handler( + [&]() + { + auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) + { + __internal::__invoke_if_else( + std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, + [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); + }; - auto __move_sequences = [](_BidirectionalIterator __first1, _BidirectionalIterator __last1, _Tp* __first2) { - return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); - }; + auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) + { return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); }; - __par_backend::__parallel_merge( - std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, __comp, - [__n, __move_values, __move_sequences](_BidirectionalIterator __f1, _BidirectionalIterator __l1, - _BidirectionalIterator __f2, _BidirectionalIterator __l2, _Tp* __f3, - _Compare __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) { - __brick_move_destroy()(__i, __j, __first + (__i - __r), __is_vector); - }); - }); + __par_backend::__parallel_merge( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, + __comp, + [__n, __move_values, __move_sequences](_RandomAccessIterator __f1, _RandomAccessIterator __l1, + _RandomAccessIterator __f2, _RandomAccessIterator __l2, + _Tp* __f3, _Compare __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(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, + [__r, __first](_Tp* __i, _Tp* __j) + { __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{}); }); + }); } //------------------------------------------------------------------------ // includes //------------------------------------------------------------------------ -template +template bool -__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector, - /*is_parallel=*/std::false_type) noexcept +__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept { return std::includes(__first1, __last1, __first2, __last2, __comp); } -template +template bool -__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector, - /*is_parallel=*/std::true_type) +__pattern_includes(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__first2 >= __last2) return true; @@ -2751,51 +2852,55 @@ __pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwa if (__last2 - __first2 == 1) return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1); - return __internal::__except_handler([&]() { - return !__internal::__parallel_or( - std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - [__first1, __last1, __first2, __last2, &__comp](_ForwardIterator2 __i, _ForwardIterator2 __j) { - _PSTL_ASSERT(__j > __i); - //assert(__j - __i > 1); - - //1. moving boundaries to "consume" subsequence of equal elements - auto __is_equal = [&__comp](_ForwardIterator2 __a, _ForwardIterator2 __b) -> bool { - return !__comp(*__a, *__b) && !__comp(*__b, *__a); - }; - - //1.1 left bound, case "aaa[aaaxyz...]" - searching "x" - if (__i > __first2 && __is_equal(__i, __i - 1)) + return __internal::__except_handler( + [&]() + { + return !__internal::__parallel_or( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) { - //whole subrange continues to content equal elements - return "no op" - if (__is_equal(__i, __j - 1)) - return false; + _PSTL_ASSERT(__j > __i); + //_PSTL_ASSERT(__j - __i > 1); - __i = std::upper_bound(__i, __last2, *__i, __comp); - } + //1. moving boundaries to "consume" subsequence of equal elements + auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool + { return !__comp(*__a, *__b) && !__comp(*__b, *__a); }; + + //1.1 left bound, case "aaa[aaaxyz...]" - searching "x" + if (__i > __first2 && __is_equal(__i, __i - 1)) + { + //whole subrange continues to content equal elements - return "no op" + if (__is_equal(__i, __j - 1)) + return false; - //1.2 right bound, case "[...aaa]aaaxyz" - searching "x" - if (__j < __last2 && __is_equal(__j - 1, __j)) - __j = std::upper_bound(__j, __last2, *__j, __comp); + __i = std::upper_bound(__i, __last2, *__i, __comp); + } - //2. testing is __a subsequence of the second range included into the first range - auto __b = std::lower_bound(__first1, __last1, *__i, __comp); + //1.2 right bound, case "[...aaa]aaaxyz" - searching "x" + if (__j < __last2 && __is_equal(__j - 1, __j)) + __j = std::upper_bound(__j, __last2, *__j, __comp); - _PSTL_ASSERT(!__comp(*(__last1 - 1), *__b)); - _PSTL_ASSERT(!__comp(*(__j - 1), *__i)); - return !std::includes(__b, __last1, __i, __j, __comp); - }); - }); + //2. testing is __a subsequence of the second range included into the first range + auto __b = std::lower_bound(__first1, __last1, *__i, __comp); + + _PSTL_ASSERT(!__comp(*(__last1 - 1), *__b)); + _PSTL_ASSERT(!__comp(*(__j - 1), *__i)); + return !std::includes(__b, __last1, __i, __j, __comp); + }); + }); } constexpr auto __set_algo_cut_off = 1000; -template +template _OutputIterator -__parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - _SizeFunction __size_func, _SetOP __set_op, _IsVector __is_vector) +__parallel_set_op(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, + _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, + _OutputIterator __result, _Compare __comp, _SizeFunction __size_func, _SetOP __set_op) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; @@ -2814,100 +2919,100 @@ __parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forwar __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]() { - auto __buffer = __buf.get(); - _DifferenceType __m{}; - auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan - if (!__s.empty()) - __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}, - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - //[__b; __e) - a subrange of the first sequence, to reduce - _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); + return __internal::__except_handler( + [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() + { + auto __buffer = __buf.get(); + _DifferenceType __m{}; + auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan + if (!__s.empty()) + __brick_move_destroy()(__buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), + __result + __s.__pos, _IsVector{}); + }; + __par_backend::__parallel_strict_scan( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0}, + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + //[__b; __e) - a subrange of the first sequence, to reduce + _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); - //try searching for the first element which not equal to *__b - if (__b != __first1) - __b = std::upper_bound(__b, __last1, *__b, __comp); + //try searching for the first element which not equal to *__b + if (__b != __first1) + __b = std::upper_bound(__b, __last1, *__b, __comp); - //try searching for the first element which not equal to *__e - if (__e != __last1) - __e = std::upper_bound(__e, __last1, *__e, __comp); + //try searching for the first element which not equal to *__e + if (__e != __last1) + __e = std::upper_bound(__e, __last1, *__e, __comp); - //check is [__b; __e) empty - if (__e - __b < 1) - { - _ForwardIterator2 __bb = __last2; - if (__b != __last1) - __bb = std::lower_bound(__first2, __last2, *__b, __comp); + //check is [__b; __e) empty + if (__e - __b < 1) + { + _ForwardIterator2 __bb = __last2; + if (__b != __last1) + __bb = std::lower_bound(__first2, __last2, *__b, __comp); - const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); - return _SetRange{0, 0, __buf_pos}; - } + const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); + return _SetRange{0, 0, __buf_pos}; + } - //try searching for "corresponding" subrange [__bb; __ee) in the second sequence - _ForwardIterator2 __bb = __first2; - if (__b != __first1) - __bb = std::lower_bound(__first2, __last2, *__b, __comp); + //try searching for "corresponding" subrange [__bb; __ee) in the second sequence + _ForwardIterator2 __bb = __first2; + if (__b != __first1) + __bb = std::lower_bound(__first2, __last2, *__b, __comp); - _ForwardIterator2 __ee = __last2; - if (__e != __last1) - __ee = std::lower_bound(__bb, __last2, *__e, __comp); + _ForwardIterator2 __ee = __last2; + if (__e != __last1) + __ee = std::lower_bound(__bb, __last2, *__e, __comp); - const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); - auto __buffer_b = __buffer + __buf_pos; - auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp); + const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); + auto __buffer_b = __buffer + __buf_pos; + auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp); - return _SetRange{0, __res - __buffer_b, __buf_pos}; - }, - [](const _SetRange& __a, const _SetRange& __b) { // Combine - if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty())) - return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos}; - return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos}; - }, - __scan, // Scan - [&__m, &__scan](const _SetRange& __total) { // Apex - //final scan - __scan(0, 0, __total); - __m = __total.__pos + __total.__len; - }); - return __result + __m; - }); + return _SetRange{0, __res - __buffer_b, __buf_pos}; + }, + [](const _SetRange& __a, const _SetRange& __b) { // Combine + if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty())) + return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos}; + return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos}; + }, + __scan, // Scan + [&__m, &__scan](const _SetRange& __total) { // Apex + //final scan + __scan(0, 0, __total); + __m = __total.__pos + __total.__len; + }); + return __result + __m; + }); } //a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference' -template +template _OutputIterator -__parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +__parallel_set_union_op(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _SetUnionOp __set_union_op, _IsVector __is_vector) + _Compare __comp, _SetUnionOp __set_union_op) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; - auto __copy_range1 = [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { - return __internal::__brick_copy(__begin, __end, __res, __is_vector); - }; - auto __copy_range2 = [__is_vector](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) { - return __internal::__brick_copy(__begin, __end, __res, __is_vector); - }; + auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) + { return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); }; + auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) + { return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); }; // {1} {}: parallel copying just first sequence if (__n2 == 0) - return __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __copy_range1, std::true_type()); + return __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result, copy_range1); // {} {2}: parallel copying justmake second sequence if (__n1 == 0) - return __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, - __copy_range2, std::true_type()); + return __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result, copy_range2); // testing whether the sequences are intersected _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); @@ -2916,14 +3021,16 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ { //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 __par_backend::__parallel_invoke( - std::forward<_ExecutionPolicy>(__exec), - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - __copy_range1, std::true_type()); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result, copy_range1); }, - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - __result + __n1, __copy_range2, std::true_type()); + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result + __n1, copy_range2); }); return __result + __n1 + __n2; } @@ -2935,14 +3042,16 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ { //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 __par_backend::__parallel_invoke( - std::forward<_ExecutionPolicy>(__exec), - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, - __copy_range2, std::true_type()); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, + __result, copy_range2); }, - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __result + __n2, __copy_range1, std::true_type()); + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + __result + __n2, copy_range1); }); return __result + __n1 + __n2; } @@ -2953,17 +3062,19 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ auto __res_or = __result; __result += __m1; //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) __par_backend::__parallel_invoke( - std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), //do parallel copying of [first1; left_bound_seq_1) - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1, - __res_or, __copy_range1, std::true_type()); + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, + __left_bound_seq_1, __res_or, copy_range1); }, - [=, &__result] { + [=, &__result] + { __result = __internal::__parallel_set_op( - std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, - __is_vector); + __tag, std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, + __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); }); return __result; } @@ -2975,24 +3086,26 @@ __parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ auto __res_or = __result; __result += __m2; //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) __par_backend::__parallel_invoke( - std::forward<_ExecutionPolicy>(__exec), + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), //do parallel copying of [first2; left_bound_seq_2) - [=] { - __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2, - __res_or, __copy_range2, std::true_type()); + [=] + { + __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, + __left_bound_seq_2, __res_or, copy_range2); }, - [=, &__result] { + [=, &__result] + { __result = __internal::__parallel_set_op( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, - __is_vector); + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, + __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); }); return __result; } return __internal::__parallel_set_op( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, __is_vector); + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op); } //------------------------------------------------------------------------ @@ -3019,33 +3132,33 @@ struct __BrickCopyConstruct } }; -template +template _OutputIterator -__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, +__brick_set_union(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _OutputIterator __result, _Compare __comp, /*__is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); } -template +template _OutputIterator -__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - _IsVector __is_vector, - /*is_parallel=*/std::false_type) noexcept +__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, + _Compare __comp) noexcept { - return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template +template _OutputIterator -__pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - _IsVector __is_vector, /*__is_parallel=*/std::true_type) +__pattern_set_union(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _OutputIterator __result, _Compare __comp) { const auto __n1 = __last1 - __first1; @@ -3057,13 +3170,13 @@ __pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _Forw 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, - _Tp* __result, _Compare __comp) { + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) + { return __pstl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); - }, - __is_vector); + }); } //------------------------------------------------------------------------ @@ -3079,35 +3192,37 @@ __brick_set_intersection(_ForwardIterator1 __first1, _ForwardIterator1 __last1, return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); } -template -_OutputIterator -__brick_set_intersection(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, +template +_RandomAccessIterator3 +__brick_set_intersection(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, _Compare __comp, /*__is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); } -template +template _OutputIterator -__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept + _Compare __comp) noexcept { - return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator3 +__pattern_set_intersection(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) { - typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; - typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; @@ -3117,13 +3232,13 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1 return __result; // testing whether the sequences are intersected - _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); + _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty if (__left_bound_seq_1 == __last1) return __result; // testing whether the sequences are intersected - _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); + _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty if (__left_bound_seq_2 == __last2) return __result; @@ -3133,14 +3248,13 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1 { //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) return __internal::__parallel_set_op( - 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, _Tp* __result, _Compare __comp) { + __tag, std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, + __comp, [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, + [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) { return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp); - }, - __is_vector); + }); } const auto __m2 = __last2 - __left_bound_seq_2 + __n1; @@ -3148,14 +3262,13 @@ __pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1 { //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) __result = __internal::__parallel_set_op( - 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, _Tp* __result, _Compare __comp) { + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, + __comp, [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, + [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) { return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp); - }, - __is_vector); + }); return __result; } @@ -3176,35 +3289,36 @@ __brick_set_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _F return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template -_OutputIterator -__brick_set_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, +template +_RandomAccessIterator3 +__brick_set_difference(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp, /*__is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template +template _OutputIterator -__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept + _Compare __comp) noexcept { - return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, __is_vector); + return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, + typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator3 +__pattern_set_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) { - typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; - typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; const auto __n1 = __last1 - __first1; const auto __n2 = __last2 - __first2; @@ -3216,44 +3330,38 @@ __pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, // {1} \ {}: parallel copying just first sequence if (__n2 == 0) return __internal::__pattern_walk2_brick( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { - return __internal::__brick_copy(__begin, __end, __res, __is_vector); - }, - std::true_type()); + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) + { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); // testing whether the sequences are intersected - _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); + _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence if (__left_bound_seq_1 == __last1) return __internal::__pattern_walk2_brick( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { - return __internal::__brick_copy(__begin, __end, __res, __is_vector); - }, - std::true_type()); + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) + { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); // testing whether the sequences are intersected - _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); + _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence if (__left_bound_seq_2 == __last2) return __internal::__pattern_walk2_brick( - std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { - return __internal::__brick_copy(__begin, __end, __res, __is_vector); - }, - std::true_type()); + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) + { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); if (__n1 + __n2 > __set_algo_cut_off) - 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); + return __parallel_set_op( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + [](_DifferenceType __n, _DifferenceType) { return __n; }, + [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) + { + return __pstl::__utils::__set_difference_construct(__first1, __last1, __first2, __last2, __result, + __comp, __BrickCopyConstruct<_IsVector>()); + }); // use serial algorithm return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); @@ -3272,33 +3380,35 @@ __brick_set_symmetric_difference(_ForwardIterator1 __first1, _ForwardIterator1 _ return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template -_OutputIterator -__brick_set_symmetric_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, +template +_RandomAccessIterator3 +__brick_set_symmetric_difference(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, _Compare __comp, /*__is_vector=*/std::true_type) noexcept { _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); } -template +template _OutputIterator -__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, +__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept + _Compare __comp) noexcept { return __internal::__brick_set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp, - __is_vector); + typename _Tag::__is_vector{}); } -template -_OutputIterator -__pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type) +template +_RandomAccessIterator3 +__pattern_set_symmetric_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, _Compare __comp) { const auto __n1 = __last1 - __first1; @@ -3308,15 +3418,15 @@ __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 _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator3>::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, - _Tp* __result, _Compare __comp) { + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, + [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) + { return __pstl::__utils::__set_symmetric_difference_construct(__first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); - }, - __is_vector); + }); } //------------------------------------------------------------------------ @@ -3344,12 +3454,12 @@ __brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __las [&__comp](_RandomAccessIterator __it, _SizeType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); } -template +template _RandomAccessIterator -__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept +__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_is_heap_until(__first, __last, __comp, __is_vector); + return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{}); } template @@ -3378,22 +3488,27 @@ __is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _D [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); } -template +template _RandomAccessIterator -__pattern_is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept +__pattern_is_heap_until(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__last - __first < 2) return __last; - return __internal::__except_handler([&]() { - return __parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __comp, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, __is_vector); - }, - std::less::difference_type>(), /*is_first=*/true); - }); + return __internal::__except_handler( + [&]() + { + return __parallel_find( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, + [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, + _IsVector{}); + }, + std::less::difference_type>(), /*is_first=*/true); + }); } //------------------------------------------------------------------------ @@ -3408,47 +3523,51 @@ __brick_min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare return std::min_element(__first, __last, __comp); } -template -_ForwardIterator -__brick_min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp, +template +_RandomAccessIterator +__brick_min_element(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, /* __is_vector = */ std::true_type) noexcept { -#if _PSTL_UDR_PRESENT +#if defined(_PSTL_UDR_PRESENT) return __unseq_backend::__simd_min_element(__first, __last - __first, __comp); #else return std::min_element(__first, __last, __comp); #endif } -template +template _ForwardIterator -__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept +__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_min_element(__first, __last, __comp, __is_vector); + return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{}); } -template +template _RandomAccessIterator -__pattern_min_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type) +__pattern_min_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { if (__first == __last) return __last; - return __internal::__except_handler([&]() { - return __par_backend::__parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, __first, - [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, - _RandomAccessIterator __init) -> _RandomAccessIterator { - const _RandomAccessIterator subresult = - __internal::__brick_min_element(__begin, __end, __comp, __is_vector); - return __internal::__cmp_iterators_by_values(__init, subresult, __comp); - }, - [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator { - return __internal::__cmp_iterators_by_values(__it1, __it2, __comp); - }); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler( + [&]() + { + return __par_backend::__parallel_reduce( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, __first, + [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, + _RandomAccessIterator __init) -> _RandomAccessIterator + { + const _RandomAccessIterator subresult = + __internal::__brick_min_element(__begin, __end, __comp, _IsVector{}); + return __internal::__cmp_iterators_by_values(__init, subresult, __comp); + }, + [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator + { return __internal::__cmp_iterators_by_values(__it1, __it2, __comp); }); + }); } //------------------------------------------------------------------------ @@ -3463,46 +3582,51 @@ __brick_minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compa return std::minmax_element(__first, __last, __comp); } -template -std::pair<_ForwardIterator, _ForwardIterator> -__brick_minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp, +template +std::pair<_RandomAccessIterator, _RandomAccessIterator> +__brick_minmax_element(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, /* __is_vector = */ std::true_type) noexcept { -#if _PSTL_UDR_PRESENT +#if defined(_PSTL_UDR_PRESENT) return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp); #else return std::minmax_element(__first, __last, __comp); #endif } -template +template std::pair<_ForwardIterator, _ForwardIterator> -__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept +__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, + _Compare __comp) noexcept { - return __internal::__brick_minmax_element(__first, __last, __comp, __is_vector); + return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{}); } -template -std::pair<_ForwardIterator, _ForwardIterator> -__pattern_minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ std::true_type) +template +std::pair<_RandomAccessIterator, _RandomAccessIterator> +__pattern_minmax_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, + _RandomAccessIterator __last, _Compare __comp) { if (__first == __last) return std::make_pair(__first, __first); + using __backend_tag = typename decltype(__tag)::__backend_tag; + return __internal::__except_handler([&]() { - typedef std::pair<_ForwardIterator, _ForwardIterator> _Result; + typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result; return __par_backend::__parallel_reduce( - 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); + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, + std::make_pair(__first, __first), + [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result + { + const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{}); 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 { + [=](_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, std::not_fn(__comp))); @@ -3518,7 +3642,7 @@ std::pair<_ForwardIterator1, _ForwardIterator2> __mismatch_serial(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __pred) { -#if _PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT +#if defined(_PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT) return std::mismatch(__first1, __last1, __first2, __last2, __pred); #else for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, ++__first2) @@ -3536,38 +3660,40 @@ __brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _Forward return __mismatch_serial(__first1, __last1, __first2, __last2, __pred); } -template -std::pair<_ForwardIterator1, _ForwardIterator2> -__brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::true_type) noexcept +template +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> +__brick_mismatch(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __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, std::not_fn(__pred)); } -template +template std::pair<_ForwardIterator1, _ForwardIterator2> -__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred, _IsVector __is_vector, - /* is_parallel = */ std::false_type) noexcept +__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred) noexcept { - return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, __is_vector); + return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{}); } -template +template std::pair<_RandomAccessIterator1, _RandomAccessIterator2> -__pattern_mismatch(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Predicate __pred, - _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept +__pattern_mismatch(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Predicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + return __internal::__except_handler([&]() { auto __n = std::min(__last1 - __first1, __last2 - __first2); auto __result = __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, __pred, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - __pred, __is_vector) + __pred, _IsVector{}) .first; }, std::less::difference_type>(), /*is_first=*/true); @@ -3588,10 +3714,11 @@ __brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __ return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp); } -template +template bool -__brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Compare __comp, /* __is_vector = */ std::true_type) noexcept +__brick_lexicographical_compare(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { if (__first2 == __last2) { // if second sequence is empty @@ -3603,12 +3730,12 @@ __brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __ } else { - typedef typename std::iterator_traits<_ForwardIterator1>::reference ref_type1; - typedef typename std::iterator_traits<_ForwardIterator2>::reference ref_type2; + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2; --__last1; --__last2; auto __n = std::min(__last1 - __first1, __last2 - __first2); - std::pair<_ForwardIterator1, _ForwardIterator2> __result = __unseq_backend::__simd_first( + std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first( __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable { return __comp(__x, __y) || __comp(__y, __x); }); @@ -3624,21 +3751,25 @@ __brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __ } } -template +template bool -__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept +__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept { - return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, __is_vector); + return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, + typename _Tag::__is_vector{}); } -template +template bool -__pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, - _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept +__pattern_lexicographical_compare(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, + _Compare __comp) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + if (__first2 == __last2) { // if second sequence is empty return false; @@ -3649,22 +3780,23 @@ __pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 _ } else { - typedef typename std::iterator_traits<_ForwardIterator1>::reference _RefType1; - typedef typename std::iterator_traits<_ForwardIterator2>::reference _RefType2; + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2; --__last1; --__last2; auto __n = std::min(__last1 - __first1, __last2 - __first2); auto __result = __internal::__parallel_find( - std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, &__comp, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { - return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - [&__comp](const _RefType1 __x, const _RefType2 __y) { - return !__comp(__x, __y) && !__comp(__y, __x); - }, - __is_vector) + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, + [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) + { + return __internal::__brick_mismatch( + __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), + [&__comp](const _RefType1 __x, const _RefType2 __y) + { return !__comp(__x, __y) && !__comp(__y, __x); }, + _IsVector{}) .first; }, - std::less::difference_type>(), /*is_first=*/true); + std::less::difference_type>(), /*is_first=*/true); if (__result == __last1 && __first2 + (__result - __first1) != __last2) { // if first sequence shorter than second diff --git a/libstdc++-v3/include/pstl/execution_defs.h b/libstdc++-v3/include/pstl/execution_defs.h index 3eca558dac22..522518c4116b 100644 --- a/libstdc++-v3/include/pstl/execution_defs.h +++ b/libstdc++-v3/include/pstl/execution_defs.h @@ -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 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::type>::value, _Tp>::type; #endif + +template +struct __serial_tag; +template +struct __parallel_tag; + } // namespace __internal } // namespace __pstl diff --git a/libstdc++-v3/include/pstl/execution_impl.h b/libstdc++-v3/include/pstl/execution_impl.h index e0969a1db9c1..64f6cc4357a7 100644 --- a/libstdc++-v3/include/pstl/execution_impl.h +++ b/libstdc++-v3/include/pstl/execution_impl.h @@ -20,140 +20,79 @@ namespace __pstl namespace __internal { -using namespace __pstl::execution; +template +using __are_iterators_of = std::conjunction< + std::is_base_of<_IteratorTag, typename std::iterator_traits>::iterator_category>...>; -/* predicate */ +template +using __are_random_access_iterators = __are_iterators_of; -template -std::false_type __lazy_and(_Tp, std::false_type) -{ - return std::false_type{}; -} - -template -inline _Tp -__lazy_and(_Tp __a, std::true_type) -{ - return __a; -} - -template -std::true_type __lazy_or(_Tp, std::true_type) -{ - return std::true_type{}; -} - -template -inline _Tp -__lazy_or(_Tp __a, std::false_type) -{ - return __a; -} - -/* iterator */ -template -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 type; -}; - -template -struct __is_random_access_iterator<_IteratorType> - : std::is_same::iterator_category, std::random_access_iterator_tag> +struct __serial_backend_tag { }; - -/* policy */ -template -struct __policy_traits +struct __tbb_backend_tag { }; - -template <> -struct __policy_traits +struct __openmp_backend_tag { - typedef std::false_type allow_parallel; - typedef std::false_type allow_unsequenced; - typedef std::false_type allow_vector; }; -template <> -struct __policy_traits -{ - typedef std::false_type allow_parallel; - typedef std::true_type allow_unsequenced; - typedef std::true_type allow_vector; -}; +#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 <> -struct __policy_traits +template +struct __serial_tag { - typedef std::true_type allow_parallel; - typedef std::false_type allow_unsequenced; - typedef std::false_type allow_vector; + using __is_vector = _IsVector; }; -template <> -struct __policy_traits +template +struct __parallel_tag { - typedef std::true_type allow_parallel; - typedef std::true_type allow_unsequenced; - typedef std::true_type allow_vector; + using __is_vector = _IsVector; + // backend tag can be change depending on + // TBB availability in the environment + using __backend_tag = __par_backend_tag; }; -template -using __collector_t = - typename __internal::__policy_traits::type>::__collector_type; - -template -using __allow_vector = - typename __internal::__policy_traits::type>::__allow_vector; +template +using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value, + __parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type; -template -using __allow_unsequenced = - typename __internal::__policy_traits::type>::__allow_unsequenced; - -template -using __allow_parallel = - typename __internal::__policy_traits::type>::__allow_parallel; - -template -auto -__is_vectorization_preferred(_ExecutionPolicy&& __exec) - -> decltype(__internal::__lazy_and(__exec.__allow_vector(), - typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) +template +__serial_tag +__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) { - return __internal::__lazy_and(__exec.__allow_vector(), - typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); + return {}; } -template -auto -__is_parallelization_preferred(_ExecutionPolicy&& __exec) - -> decltype(__internal::__lazy_and(__exec.__allow_parallel(), - typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) +template +__serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>> +__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) { - return __internal::__lazy_and(__exec.__allow_parallel(), - typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); + return {}; } -template -struct __prefer_unsequenced_tag +template +__tag_type +__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) { - static constexpr bool value = __internal::__allow_unsequenced<__policy>::value && - __internal::__is_random_access_iterator<_IteratorTypes...>::value; - typedef std::integral_constant type; -}; + return {}; +} -template -struct __prefer_parallel_tag +template +__tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...> +__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) { - static constexpr bool value = __internal::__allow_parallel<__policy>::value && - __internal::__is_random_access_iterator<_IteratorTypes...>::value; - typedef std::integral_constant type; -}; + return {}; +} } // namespace __internal } // namespace __pstl diff --git a/libstdc++-v3/include/pstl/glue_algorithm_impl.h b/libstdc++-v3/include/pstl/glue_algorithm_impl.h index b16306f2e990..5be45ce57fba 100644 --- a/libstdc++-v3/include/pstl/glue_algorithm_impl.h +++ b/libstdc++-v3/include/pstl/glue_algorithm_impl.h @@ -26,10 +26,10 @@ template __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 __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 __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 __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 @@ -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 @@ -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 @@ -150,23 +145,20 @@ template __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 __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 @@ -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 @@ -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 @@ -247,34 +235,28 @@ template 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 __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 @@ -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 ::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 @@ -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 @@ -407,10 +385,10 @@ template __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 @@ -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 __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 @@ -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 __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 @@ -493,10 +471,10 @@ template 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 @@ -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 @@ -532,10 +508,9 @@ template __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 @@ -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 __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 @@ -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 __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 __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 @@ -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 (__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 __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 @@ -651,10 +617,10 @@ template __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 @@ -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 @@ -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 @@ -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 @@ -751,17 +715,14 @@ template 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 @@ -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 @@ -815,11 +774,11 @@ template __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 __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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -1024,10 +969,10 @@ template __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 @@ -1059,10 +1004,9 @@ template __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 @@ -1094,10 +1038,9 @@ template __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 @@ -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 @@ -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 diff --git a/libstdc++-v3/include/pstl/glue_execution_defs.h b/libstdc++-v3/include/pstl/glue_execution_defs.h index 24ede331ac18..e7b36c7dd10e 100644 --- a/libstdc++-v3/include/pstl/glue_execution_defs.h +++ b/libstdc++-v3/include/pstl/glue_execution_defs.h @@ -18,10 +18,10 @@ namespace std { // Type trait using __pstl::execution::is_execution_policy; -#if _PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT -# if __INTEL_COMPILER -template -constexpr bool is_execution_policy_v = is_execution_policy::value; +#if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT) +# if defined(__INTEL_COMPILER) +template +constexpr bool is_execution_policy_v = is_execution_policy<_Tp>::value; # else using __pstl::execution::is_execution_policy_v; # endif diff --git a/libstdc++-v3/include/pstl/glue_memory_impl.h b/libstdc++-v3/include/pstl/glue_memory_impl.h index ea462e9ccddc..7850605f94a5 100644 --- a/libstdc++-v3/include/pstl/glue_memory_impl.h +++ b/libstdc++-v3/include/pstl/glue_memory_impl.h @@ -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 @@ -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 @@ -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(); }); }); } diff --git a/libstdc++-v3/include/pstl/glue_numeric_impl.h b/libstdc++-v3/include/pstl/glue_numeric_impl.h index 9db64b513a47..490175c8b835 100644 --- a/libstdc++-v3/include/pstl/glue_numeric_impl.h +++ b/libstdc++-v3/include/pstl/glue_numeric_impl.h @@ -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 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 @@ -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 @@ -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 (__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 diff --git a/libstdc++-v3/include/pstl/memory_impl.h b/libstdc++-v3/include/pstl/memory_impl.h index be5a103f93bf..8cb32d043e5e 100644 --- a/libstdc++-v3/include/pstl/memory_impl.h +++ b/libstdc++-v3/include/pstl/memory_impl.h @@ -36,13 +36,13 @@ __brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _O return __result; } -template +template _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 +template 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 +template _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( diff --git a/libstdc++-v3/include/pstl/numeric_fwd.h b/libstdc++-v3/include/pstl/numeric_fwd.h index d92cacb76447..e98e3b1e12b8 100644 --- a/libstdc++-v3/include/pstl/numeric_fwd.h +++ b/libstdc++-v3/include/pstl/numeric_fwd.h @@ -22,9 +22,10 @@ namespace __internal // transform_reduce (version with two binary functions, according to draft N4659) //------------------------------------------------------------------------ -template -_Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, _BinaryOperation1, - _BinaryOperation2, +template +_Tp __brick_transform_reduce(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Tp, + _BinaryOperation1, _BinaryOperation2, /*__is_vector=*/std::true_type) noexcept; template @@ -32,45 +33,41 @@ _Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardItera _BinaryOperation2, /*__is_vector=*/std::false_type) noexcept; -template +template _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 +template _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 -_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation, +template +_Tp __brick_transform_reduce(_RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation, _UnaryOperation, /*is_vector=*/std::true_type) noexcept; template _Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation, /*is_vector=*/std::false_type) noexcept; -template +template _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 +template _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 -std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _ForwardIterator, _OutputIterator, +template +std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, /*Inclusive*/ std::true_type) noexcept; -template +template _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 +template typename std::enable_if::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 +template typename std::enable_if::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 _OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation, /*is_vector*/ std::false_type) noexcept; -template -_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation, +template +_OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, + _BinaryOperation, /*is_vector*/ std::true_type) noexcept; -template +template _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 +template _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 diff --git a/libstdc++-v3/include/pstl/numeric_impl.h b/libstdc++-v3/include/pstl/numeric_impl.h index 0b02bcf07891..7ba83eeb7149 100644 --- a/libstdc++-v3/include/pstl/numeric_impl.h +++ b/libstdc++-v3/include/pstl/numeric_impl.h @@ -38,50 +38,56 @@ __brick_transform_reduce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, return std::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); } -template +template _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 +template _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 +template _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 +template _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 +template _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 +template _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 +template 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: // [restriction] - T shall be DefaultConstructible. // [violation] - default ctor of T shall set the identity value for binary_op. -template typename std::enable_if::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 typename std::enable_if::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 +template _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 +template typename std::enable_if::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 +template typename std::enable_if::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 -_ForwardIterator2 -__brick_adjacent_difference(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first, - _BinaryOperation __op, /*is_vector=*/std::true_type) noexcept +template +_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 +template _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 -_ForwardIterator2 -__pattern_adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first, _BinaryOperation __op, _IsVector __is_vector, - /*is_parallel=*/std::true_type) +template +_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); } diff --git a/libstdc++-v3/include/pstl/parallel_backend.h b/libstdc++-v3/include/pstl/parallel_backend.h index 4caa4a8e412b..e9a90e11dba5 100644 --- a/libstdc++-v3/include/pstl/parallel_backend.h +++ b/libstdc++-v3/include/pstl/parallel_backend.h @@ -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 diff --git a/libstdc++-v3/include/pstl/parallel_backend_serial.h b/libstdc++-v3/include/pstl/parallel_backend_serial.h index 16e773d411a9..db2da43eb060 100644 --- a/libstdc++-v3/include/pstl/parallel_backend_serial.h +++ b/libstdc++-v3/include/pstl/parallel_backend_serial.h @@ -50,15 +50,15 @@ __cancel_execution() template 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 _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 _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 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 _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 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 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 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)(); diff --git a/libstdc++-v3/include/pstl/parallel_backend_tbb.h b/libstdc++-v3/include/pstl/parallel_backend_tbb.h index 3fd1a06ebd89..3ff55237bffa 100644 --- a/libstdc++-v3/include/pstl/parallel_backend_tbb.h +++ b/libstdc++-v3/include/pstl/parallel_backend_tbb.h @@ -99,7 +99,7 @@ class __parallel_for_body // wrapper over tbb::parallel_for template 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 _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 _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 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 _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 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 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 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)); }); diff --git a/libstdc++-v3/include/pstl/parallel_impl.h b/libstdc++-v3/include/pstl/parallel_impl.h index 46560c642ea7..4cf2abde650b 100644 --- a/libstdc++-v3/include/pstl/parallel_impl.h +++ b/libstdc++-v3/include/pstl/parallel_impl.h @@ -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 +template _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 +template 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 __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); diff --git a/libstdc++-v3/include/pstl/pstl_config.h b/libstdc++-v3/include/pstl/pstl_config.h index d1bf08e5f3b3..74d2139c736a 100644 --- a/libstdc++-v3/include/pstl/pstl_config.h +++ b/libstdc++-v3/include/pstl/pstl_config.h @@ -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) +#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_EARLYEXIT_PRESENT (__INTEL_COMPILER >= 1800) -#define _PSTL_MONOTONIC_PRESENT (__INTEL_COMPILER >= 1800) +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1800 +# define _PSTL_EARLYEXIT_PRESENT +# define _PSTL_MONOTONIC_PRESENT +#endif -#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(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900) || \ + (!defined(__INTEL_COMPILER) && _PSTL_GCC_VERSION >= 40900) || \ + (defined(_OPENMP) && _OPENMP >= 201307) +# define _PSTL_UDR_PRESENT #endif -#define _PSTL_UDS_PRESENT (__INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626) +#if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1900 && __INTEL_COMPILER_BUILD_DATE >= 20180626 +# define _PSTL_UDS_PRESENT +#endif -#if _PSTL_EARLYEXIT_PRESENT +#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 */ diff --git a/libstdc++-v3/include/pstl/unseq_backend_simd.h b/libstdc++-v3/include/pstl/unseq_backend_simd.h index 7cda7ffeddc3..69784bcdbe66 100644 --- a/libstdc++-v3/include/pstl/unseq_backend_simd.h +++ b/libstdc++-v3/include/pstl/unseq_backend_simd.h @@ -61,7 +61,7 @@ template 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 _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 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) diff --git a/libstdc++-v3/include/pstl/utils.h b/libstdc++-v3/include/pstl/utils.h index 0e908f1c5394..e2611053f534 100644 --- a/libstdc++-v3/include/pstl/utils.h +++ b/libstdc++-v3/include/pstl/utils.h @@ -19,8 +19,8 @@ namespace __internal { template -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 -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 -void -__invoke_if_not(std::true_type, _Fp __f) +void __invoke_if_not(std::true_type, _Fp) { } template -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 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 -class __not_pred -{ - _Pred _M_pred; - - public: - explicit __not_pred(_Pred __pred) : _M_pred(__pred) {} - - template - bool - operator()(_Args&&... __args) - { - return !_M_pred(std::forward<_Args>(__args)...); - } -}; - template 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 - 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 - bool - operator()(_Xp&& __x, _Yp&& __y) const - { - return std::forward<_Xp>(__x) < std::forward<_Yp>(__y); - } -}; - //! Like a polymorphic lambda for pred(...,value) template class __equal_value_by_pred diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc index dc099410242b..407e4885327d 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_construct.cc @@ -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>(); test_uninit_construct_by_type>>(); #endif diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc index 73b09829574d..2558147a7f13 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_copy_move.cc @@ -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 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=*/std::true_type) { } template 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=*/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=*/std::true_type) { - typedef typename std::iterator_traits::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(); // 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>(); #endif diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc index 1683e64ad2db..fed9bdb88866 100644 --- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc +++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/pstl/uninitialized_fill_destroy.cc @@ -87,7 +87,7 @@ test_uninitialized_fill_destroy_by_type() } } -int32_t +int main() { // for trivial types diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc index 14993446f6b8..576f22423b88 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/inplace_merge.cc @@ -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 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 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::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 std::enable_if::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([](int32_t i) { return -2 * i; }, [](int32_t i) { return -(2 * i + 1); }, @@ -160,6 +157,13 @@ main() test_algo_basic_single(run_for_rnd_bi>()); + test_by_type( + [](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; } diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc index e6eeb1dde667..eab12608515a 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_merge/merge.cc @@ -23,6 +23,7 @@ #else #include #include +#include #endif // PSTL_STANDALONE_TESTS #include "pstl/test_utils.h" @@ -58,8 +59,7 @@ struct test_merge void operator()(Policy&& exec, std::reverse_iterator first1, std::reverse_iterator last1, std::reverse_iterator first2, std::reverse_iterator last2, - std::reverse_iterator out_first, std::reverse_iterator out_last, - Compare comp) + std::reverse_iterator out_first, std::reverse_iterator out_last, Compare) { using namespace std; typedef typename std::iterator_traits>::value_type T; @@ -106,13 +106,13 @@ struct test_non_const } }; -int32_t +int main() { test_merge_by_type([](size_t v) { return (v % 2 == 0 ? v : -v) * 3; }, [](size_t v) { return v * 2; }); test_merge_by_type([](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>([](size_t v) { return Wrapper(v % 100); }, [](size_t v) { return Wrapper(v % 10); }); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc index 5b90e83f983a..9c1f1725ac21 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_if.cc @@ -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 void @@ -131,7 +131,7 @@ struct test_non_const } }; -int32_t +int main() { test(-666.0, [](const float64_t& x) { return x * x <= 1024; }, @@ -140,12 +140,12 @@ main() test(-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(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j) { return Number(j, OddTag()); }); #endif -#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN - test(-666, [](const int32_t& x) { return true; }, [](size_t j) { return j; }, false); +#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN) + test(-666, [](const int32_t&) { return true; }, [](size_t j) { return j; }, false); #endif test_algo_basic_double(run_for_rnd_fw()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc index 73c368b69372..5f4f984ae067 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/copy_move.cc @@ -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 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 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 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 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 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 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 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 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 trash) { @@ -139,7 +137,7 @@ struct run_move> template 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 trash) { @@ -149,8 +147,7 @@ struct run_move> template 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 trash) + OutputIterator out_last, OutputIterator2, OutputIterator2, Size size, Size, Wrapper trash) { // Cleaning std::fill_n(out_first, size, trash); @@ -194,13 +191,13 @@ test(T trash, Convert convert) } } -int32_t +int main() { test(-666, [](size_t j) { return int32_t(j); }); test>(Wrapper(-666.0), [](int32_t j) { return Wrapper(j); }); -#if !_PSTL_ICC_16_17_TEST_64_TIMEOUT +#if !defined(_PSTL_ICC_16_17_TEST_64_TIMEOUT) test(-666.0, [](size_t j) { return float64_t(j); }); test(Number(42, OddTag()), [](int32_t j) { return Number(j, OddTag()); }); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc index 733657bf48fd..d5b40658d57e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/fill.cc @@ -84,14 +84,14 @@ template void test_fill_by_type(std::size_t n) { - Sequence in(n, [](std::size_t v) -> T { return T(0); }); //fill with zeros + Sequence 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() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc index 1bd26216098c..c04e51207c21 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/generate.cc @@ -57,17 +57,18 @@ struct test_generate { Generator_count 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 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 in(n, [](size_t v) -> T { return T(0); }); //fill by zero + Sequence 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() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc index 3c70b14b0198..20ee7d296f7e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/is_partitioned.cc @@ -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 void - operator()(pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred) + operator()(__pstl::execution::unsequenced_policy, Iterator1 begin1, Iterator1 end1, Predicate pred) { } template 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([](const float64_t x) { return x < 0; }); test([](const int32_t x) { return x > 1000; }); test([](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>([](const LocalWrapper& x) { return true; }); +#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN) && !defined(_PSTL_ICC_19_TEST_IS_PARTITIONED_RELEASE_BROKEN) + test>([](const LocalWrapper&) { return true; }); #endif test_algo_basic_single(run_for_rnd_fw()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc index d084995574a7..e13fe938d1f9 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition.cc @@ -66,15 +66,15 @@ is_equal(Iterator first, Iterator last, Iterator d_first) template typename std::enable_if::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 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 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 std::enable_if::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 std::enable_if::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 i) { return i; }, [](int32_t) { return true; }); #endif test_by_type([](int32_t i) { return -i; }, [](const float64_t x) { return x < 0; }); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc index 63e1f21da37d..804fcba2bf2b 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/partition_copy.cc @@ -35,24 +35,23 @@ struct test_partition_copy template 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(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 void - operator()(pstl::execution::unsequenced_policy, std::reverse_iterator first, + operator()(__pstl::execution::unsequenced_policy, std::reverse_iterator first, std::reverse_iterator last, std::reverse_iterator true_first, std::reverse_iterator true_last, std::reverse_iterator false_first, OutputIterator2 false_last, UnaryOp unary_op) @@ -60,7 +59,7 @@ struct test_partition_copy } template void - operator()(pstl::execution::parallel_unsequenced_policy, std::reverse_iterator first, + operator()(__pstl::execution::parallel_unsequenced_policy, std::reverse_iterator first, std::reverse_iterator last, std::reverse_iterator true_first, std::reverse_iterator true_last, std::reverse_iterator false_first, OutputIterator2 false_last, UnaryOp unary_op) @@ -106,13 +105,13 @@ struct test_non_const } }; -int32_t +int main() { test([](const int32_t value) { return value % 2; }); -#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN - test([](const int32_t value) { return true; }); +#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN) + test([](const int32_t) { return true; }); #endif test([](const float64_t value) { return value > 2 << 6; }); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc index f2e7520b82da..9d8e5b9b305e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove.cc @@ -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 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 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 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 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(666, 42, [](int32_t val) { return true; }, [](size_t j) { return j; }); +#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_MONOTONIC_RELEASE_BROKEN) + test(666, 42, [](int32_t) { return true; }, [](size_t j) { return j; }); #endif test(666, 2001, [](const int32_t& val) { return val != 2001; }, @@ -150,13 +150,20 @@ main() test(-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(-666, OddTag()), Number(42, OddTag()), IsMultiple(3, OddTag()), [](int32_t j) { return Number(j, OddTag()); }); #endif test_algo_basic_single(run_for_rnd_fw()); + test(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; } diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc index 9cc8c820a709..37d7b6679dd1 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/remove_copy.cc @@ -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() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc index db82b87bf176..c6a515e4c88d 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace.cc @@ -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 expected(max_len); Sequence actual(max_len); - Sequence data(max_len, [&value](std::size_t i) { + Sequence 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(__pstl::__internal::__equal_value(666)); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc index 6931162af294..18f6b5491685 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/replace_copy.cc @@ -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(-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(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 diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc index c7e00fb8570e..9ec9b3bcc9b4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate.cc @@ -83,8 +83,8 @@ struct compare> 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 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 std::enable_if< is_same_iterator_category::value && - !std::is_same::value && + !std::is_same::value && std::is_same::value_type, wrapper>::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& a) { bool temp = a.move_count > 0; @@ -139,10 +139,10 @@ struct test_one_policy template typename std::enable_if< !(is_same_iterator_category::value && - !std::is_same::value && + !std::is_same::value && std::is_same::value_type, wrapper>::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(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc index f80ec5a54a21..ea647c6c23a0 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc @@ -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 std::enable_if::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 std::enable_if::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(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc index d17c11d78db2..e371c3b2b048 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/swap_ranges.cc @@ -61,7 +61,7 @@ template struct check_swap { bool - operator()(T& a) + operator()(T&) { return true; } @@ -129,7 +129,7 @@ test() } } -int32_t +int main() { test>(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc index 226a81a04051..1f5f239a94be 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc @@ -70,10 +70,11 @@ struct test_one_policy template 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(n, [](size_t k) { return k % 5 != 1 ? 3 * k - 7 : 0; }); Sequence in2(n, [](size_t k) { return k % 7 != 2 ? 5 * k - 5 : 0; }); - Sequence out(n, [](size_t k) { return -1; }); + Sequence 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() diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc index cece4751891d..ddd8249b6787 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_unary.cc @@ -83,7 +83,7 @@ struct test_non_const } }; -int32_t +int main() { test(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc index 54c99530c4e7..0f21e0450896 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique.cc @@ -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 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 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 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 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([](size_t j) { return j / 3; }, [](const int32_t& val1, const int32_t& val2) { return val1 * val1 == val2 * val2; }); test([](size_t) { return float64_t(1); }, @@ -160,6 +160,12 @@ main() test_algo_basic_single(run_for_rnd_fw>()); + test( + [](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; } diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc index 0351db7498af..c5bc25c9140c 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/unique_copy_equal.cc @@ -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 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(42, OddTag()), std::equal_to(), [](int32_t j) { return Number(3 * j / 13 ^ (j & 8), OddTag()); }); test(float32_t(42), std::equal_to(), [](int32_t j) { return float32_t(5 * j / 23 ^ (j / 7)); }); -#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN - test(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(42), [](float32_t, float32_t) { return false; }, [](int32_t j) { return float32_t(j); }, + false); #endif test_algo_basic_double(run_for_rnd_fw>()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc index 81bca8229d86..a79f11bb1ed4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/adjacent_find.cc @@ -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 in(counts[c], [](int32_t v) -> T { return T(v); }); //fill 0...n - in[e] = in[e + 1] = -1; //make an adjacent pair + Sequence 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()); 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 in(expect, [](int32_t v) -> T { return T(v); }); //fill 0...n + Sequence in(expect, [](size_t v) -> T { return T(v); }); //fill 0...n auto i = std::adjacent_find(in.cbegin(), in.cend(), std::equal_to()); EXPECT_TRUE(i == in.cbegin() + expect, "std::adjacent_find returned wrong result"); @@ -109,7 +109,7 @@ struct test_non_const } }; -int32_t +int main() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc index d1c3b98da377..0f03d00cdbc8 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/all_of.cc @@ -69,7 +69,7 @@ test(size_t bits) { // Sequence of odd values - Sequence in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); }); + Sequence 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(8 * sizeof(int32_t)); test(8 * sizeof(uint16_t)); test(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(1); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc index 7b2f3c73a30a..a4bbb7d176e7 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/any_of.cc @@ -55,7 +55,7 @@ test(size_t bits) { // Sequence of odd values - Sequence in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); }); + Sequence 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(8 * sizeof(int32_t)); test(8 * sizeof(uint16_t)); test(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(1); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc index 25a1350edf87..b99754c51f15 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/count.cc @@ -98,12 +98,12 @@ struct test_non_const } }; -int32_t +int main() { test(42, IsEqual(50, OddTag()), [](int32_t j) { return j; }); -#if !_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN - test(42, [](const int32_t& x) { return true; }, [](int32_t j) { return j; }); +#if !defined(_PSTL_ICC_16_17_TEST_REDUCTION_RELEASE_BROKEN) + test(42, [](const int32_t&) { return true; }, [](int32_t j) { return j; }); #endif test(42, IsEqual(50, OddTag()), [](int32_t j) { return float64_t(j); }); test(Number(42, OddTag()), IsEqual(Number(50, OddTag()), OddTag()), diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc index cec6b20bd6ca..0e5ad030ee7d 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/equal.cc @@ -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(8 * sizeof(int32_t)); test(8 * sizeof(uint16_t)); test(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(1); #endif test(256); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc index 1eb9db3e7eb5..c303ba689d7c 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find.cc @@ -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 void - operator()(pstl::execution::unsequenced_policy, Iterator first, Iterator last, Value value) + operator()(__pstl::execution::unsequenced_policy, Iterator first, Iterator last, Value value) { } template 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(Weird(42, OddTag()), [](int32_t j) { return Number(42, OddTag()); }, // hit - [](int32_t j) { return Number(j == 42 ? 0 : j, OddTag()); }); // miss + test(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(-0.0, [](int32_t j) { return j & 1 ? 0.0 : -0.0; }, // hit diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc index e106b5c750e0..e6a65a9848b6 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_end.cc @@ -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 +#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 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 + template 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 + template 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 +template 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 in(max_n1, [max_n1, bits](std::size_t) { return T(2 * HashBits(max_n1, bits - 1) ^ 1); }); - Sequence 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 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()); - invoke_on_all_policies(test_one_policy(), in.cbegin(), in.cbegin() + n1, sub.cbegin(), - sub.cbegin() + n2, std::equal_to()); - } + 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 -struct test_non_const +// Type defined for sake of checking that std::find works with asymmetric ==. +class Weird { - template - 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())); - search(exec, first_iter, first_iter, second_iter, second_iter, non_const(std::equal_to())); - }); + return x == y.value; } + Weird(int32_t val, OddTag) : value(val, OddTag()) {} }; -int32_t +int main() { - test(8 * sizeof(int32_t)); - test(8 * sizeof(uint16_t)); - test(53); -#if !_PSTL_ICC_16_17_TEST_REDUCTION_BOOL_TYPE_RELEASE_64_BROKEN - test(1); -#endif + // Note that the "hit" and "miss" functions here avoid overflow issues. + test(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(run_for_rnd_fw>()); + // Test with value that is equal to two different bit patterns (-0.0 and 0.0) + test(-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; diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc index 365771d8af7b..5a4a81a8db7e 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_first_of.cc @@ -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 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 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 in1(max_n1, [](std::size_t k) { return T(1); }); - Sequence in2(max_n2, [](std::size_t k) { return T(0); }); + Sequence in1(max_n1, [](std::size_t) { return T(1); }); + Sequence 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(std::equal_to()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc index 0449cedbf74f..04ef148b5f3c 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/find_if.cc @@ -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 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 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(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 diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc index 412367c4583e..51c51221b3c3 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/for_each.cc @@ -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(1)); + std::for_each_n(std::execution::seq, expected_first, n, Flip(1)); for_each_n(exec, first, n, Flip(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(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc index 36096b1f1aae..1173186f65c0 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc @@ -53,7 +53,7 @@ struct test_mismatch using namespace std; typedef typename iterator_traits::value_type T; { - const auto expected = mismatch(__pstl::execution::seq, first1, last1, first2, last2, std::equal_to()); + const auto expected = mismatch(std::execution::seq, first1, last1, first2, last2, std::equal_to()); const auto res1 = mismatch(exec, first1, last1, first2, last2, std::equal_to()); 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() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc index b563e48409d4..a49b6b2d45fc 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/none_of.cc @@ -55,7 +55,7 @@ test(size_t bits) { // Sequence of odd values - Sequence in(n, [n, bits](size_t k) { return T(2 * HashBits(n, bits - 1) ^ 1); }); + Sequence 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(8 * sizeof(int32_t)); test(8 * sizeof(uint16_t)); test(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(1); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc index 9aca6d2a403e..61bbca758b4f 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/nth_element.cc @@ -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 std::enable_if::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 std::enable_if::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 std::enable_if::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 i) { return 10 * i; }, [](int32_t i) { return i + 1; }, std::less()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc index 7db9049ea18b..f3cc5d3bc0fe 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse.cc @@ -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 std::enable_if::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 std::enable_if::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 std::enable_if::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(); test(); test(); -#if !_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN +#if !defined(_PSTL_ICC_17_TEST_MAC_RELEASE_32_BROKEN) test>(); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc index 3ec0408c98e4..a6c39a2268ba 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/reverse_copy.cc @@ -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 std::enable_if::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 std::enable_if::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::value_type; - using DifferenceType = typename iterator_traits::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(); test(); test(); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc index c0b73868d256..fab146fc74c4 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/search_n.cc @@ -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 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 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 in(n1, [n1](std::size_t k) { return T(0); }); + Sequence 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(); test(); test(); -#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(); #endif diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc index 3cf06aacbf31..ed07810618d6 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/includes.cc @@ -67,8 +67,7 @@ struct test_one_policy template typename std::enable_if::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(__pstl::__internal::__pstl_less()); + test_includes(std::less<>()); test_includes, Num>([](const Num& x, const Num& y) { return x < y; }); std::cout << done() << std::endl; diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc index a4589937de78..bb3c3a57ecab 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_heap.cc @@ -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 std::enable_if::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 std::enable_if::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 std::enable_if::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 in(max_size / 10, [](size_t v) -> T { return T(1); }); + Sequence 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(std::greater()); diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc index 3c0230d981b6..d88144ebc277 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/is_sorted.cc @@ -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 in1(9, [](size_t v) -> T { return T(0); }); + Sequence 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() { diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc index 1cc480cc66f5..924aa78652e8 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc @@ -165,12 +165,12 @@ struct test_non_const } }; -int32_t +int main() { test(std::less()); test(std::greater()); -#if !_PSTL_ICC_18_TEST_EARLY_EXIT_AVX_RELEASE_BROKEN +#if !defined(_PSTL_ICC_18_TEST_EARLY_EXIT_AVX_RELEASE_BROKEN) test([](const float64_t x, const int32_t y) { return x * x < y * y; }); #endif test, LocalWrapper>( diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc index 60522a4dae5e..0a9f41ca1797 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc @@ -184,7 +184,7 @@ struct test_non_const } }; -int32_t +int main() { using TestUtils::float64_t; diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc index cf12bfc27b9a..6d441cc3ae9d 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort.cc @@ -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 +#ifdef _DEBUG +# if defined(_PSTL_PAR_BACKEND_TBB) auto p = tbb::this_task_arena::max_concurrency(); -#else +# else auto p = 1; -#endif - -#ifdef _DEBUG +# 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 std::enable_if::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; diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc index 7c5608ac248e..72336d628856 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/partial_sort_copy.cc @@ -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 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 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 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 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 x, Num y) { return x < y; }); @@ -195,6 +195,11 @@ main() test_algo_basic_double(run_for_rnd>()); + test_partial_sort_copy( + [](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; } diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc index 5d411a86bed2..0343739dfd10 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/set.cc @@ -60,7 +60,8 @@ struct Num } }; -struct test_one_policy +template +struct test_set_union { template typename std::enable_if::value, void>::type @@ -75,30 +76,98 @@ struct test_one_policy Sequence expect(n); Sequence 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"); + } + + template + typename std::enable_if::value, void>::type + operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare) + { + } +}; + +template +struct test_set_intersection +{ + template + typename std::enable_if::value, void>::type + operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, + Compare comp) + { + using T1 = typename std::iterator_traits::value_type; + + auto n1 = std::distance(first1, last1); + auto n2 = std::distance(first2, last2); + auto n = n1 + n2; + Sequence expect(n); + Sequence out(n); - //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); + 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"); + } + + template + typename std::enable_if::value, void>::type + operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare) + { + } +}; + +template +struct test_set_difference +{ + template + typename std::enable_if::value, void>::type + operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, + Compare comp) + { + using T1 = typename std::iterator_traits::value_type; - //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); + auto n1 = std::distance(first1, last1); + auto n2 = std::distance(first2, last2); + auto n = n1 + n2; + Sequence expect(n); + Sequence 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"); + } + + template + typename std::enable_if::value, void>::type + operator()(Policy&&, InputIterator1, InputIterator1, InputIterator2, InputIterator2, Compare) + { + } +}; + +template +struct test_set_symmetric_difference +{ + template + typename std::enable_if::value, void>::type + operator()(Policy&& exec, InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, + Compare comp) + { + using T1 = typename std::iterator_traits::value_type; + + auto n1 = std::distance(first1, last1); + auto n2 = std::distance(first2, last2); + auto n = n1 + n2; + Sequence expect(n); + Sequence out(n); - //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); + 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 std::enable_if::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 in1(n, [n](std::size_t k) { return rand() % (2 * k + 1); }); + Sequence in1(n, [](std::size_t k) { return rand() % (2 * k + 1); }); Sequence 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(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(), + compare); + + invoke_on_all_policies(test_set_intersection(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(), + compare); + + invoke_on_all_policies(test_set_difference(), in1.begin(), in1.end(), in2.cbegin(), in2.cend(), + compare); + + invoke_on_all_policies(test_set_symmetric_difference(), in1.begin(), in1.end(), in2.cbegin(), + in2.cend(), compare); } } } template -struct test_non_const +struct test_non_const_set_difference { template 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())); + } +}; +template +struct test_non_const_set_intersection +{ + template + 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())); + } +}; +template +struct test_non_const_set_symmetric_difference +{ + template + 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())); + } +}; +template +struct test_non_const_set_union +{ + template + 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())); } }; -int32_t +int main() { - test_set(__pstl::__internal::__pstl_less()); + test_set(std::less<>()); test_set, Num>([](const Num& x, const Num& y) { return x < y; }); - test_algo_basic_double(run_for_rnd_fw>()); + test_set([](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(run_for_rnd_fw>()); + + test_algo_basic_double(run_for_rnd_fw>()); + + test_algo_basic_double(run_for_rnd_fw>()); + + test_algo_basic_double(run_for_rnd_fw>()); std::cout << done() << std::endl; diff --git a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc index b460c595be9d..94257bd1ac34 100644 --- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc +++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/sort.cc @@ -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::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::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); diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc index b78410821fae..cf42b716acf6 100644 --- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc +++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/adjacent_difference.cc @@ -33,19 +33,19 @@ template struct wrapper { T t; - explicit wrapper(T t_) : t(t_) {} + constexpr explicit wrapper(T t_) : t(t_) {} template - wrapper(const wrapper& a) + constexpr wrapper(const wrapper& a) { t = a.t; } template - void + constexpr void operator=(const wrapper& a) { t = a.t; } - wrapper + constexpr wrapper operator-(const wrapper& a) const { return wrapper(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 std::enable_if::value, bool>::type -compute_and_check(Iterator1 first, Iterator1 last, Iterator2 d_first, T, Function) +typename std::enable_if::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 std::enable_if::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 std::enable_if::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 void test(Pred pred) { - typedef typename Sequence::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 actual(max_len, [](std::size_t i) { return T1(i); }); - Sequence data(max_len, [&value](std::size_t i) { return i % 3 == 2 ? T2(i * i) : value; }); + Sequence 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([](uint32_t a, uint32_t b) { return a - b; }); diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc index e9f506b370b3..5a8f921e8cd2 100644 --- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc +++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/reduce.cc @@ -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 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 diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc index 2173d7b32ea4..bcd5ad116d8f 100644 --- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc +++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/scan.cc @@ -108,12 +108,13 @@ struct test_scan_with_plus template 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::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 std::enable_if::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>(Matrix2x2(), multiply_matrix, Matrix2x2(-666, 666)); diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc index bec1c1412788..7497d60d8e9a 100644 --- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc +++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_reduce.cc @@ -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 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 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(42, std::plus(), std::multiplies(), std::negate(), - [](std::size_t a) -> int32_t { return int32_t(rand() % 1000); }); + [](std::size_t) -> int32_t { return int32_t(rand() % 1000); }); test_by_type(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(1.0f, std::multiplies(), - [](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( + 1.0f, std::multiplies(), [](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(), std::plus(), std::multiplies(), std::negate(), - [](std::size_t a) -> MyClass { return MyClass(rand() % 1000); }); + [](std::size_t) -> MyClass { return MyClass(rand() % 1000); }); std::cout << done() << std::endl; return 0; diff --git a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc index c9694af5bcaa..e785a95f450b 100644 --- a/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc +++ b/libstdc++-v3/testsuite/26_numerics/pstl/numeric_ops/transform_scan.cc @@ -47,15 +47,15 @@ struct test_transform_scan typename T, typename BinaryOp> typename std::enable_if::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 std::enable_if::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>([](const Matrix2x2 x) { return x; }, Matrix2x2(), multiply_matrix, Matrix2x2(-666, 666)); diff --git a/libstdc++-v3/testsuite/util/pstl/test_utils.h b/libstdc++-v3/testsuite/util/pstl/test_utils.h index 80a8f9c7b879..ed6d48b9471a 100644 --- a/libstdc++-v3/testsuite/util/pstl/test_utils.h +++ b/libstdc++-v3/testsuite/util/pstl/test_utils.h @@ -30,7 +30,7 @@ typedef float float32_t; template 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 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(_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 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 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 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(), 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::type; + using allow_unsequenced = + std::integral_constant::value || + std::is_same::value)>; + __pstl::__internal::__invoke_if_not(allow_unsequenced{}, f); #else f(); #endif