From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2062) id 54AAE3858D1E; Mon, 26 Jun 2023 18:35:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 54AAE3858D1E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1687804516; bh=3OkjUkVPp7y+6iMzDXAecipXKeboLKSJz89dBU+2V2w=; h=From:To:Subject:Date:From; b=KSknps/u22yomM6Hg1jzLnymxsMv/Q3MUMn8YsteyCHG8D9pXVkl1PIJOH5a1QCCF 8RzeQTq1WhYg1ZqmbjL6TLyeSRPfrwUIbD752mzSjQ8EQXJpYE2NTuEp4FewqaCbfJ 347aZ3DSFymDTf2rRq0CAHefn+onKVLt7vTDaFps= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Thomas Rodgers To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r14-2109] libstdc++: Synchronize PSTL with upstream X-Act-Checkin: gcc X-Git-Author: Thomas Rodgers X-Git-Refname: refs/heads/master X-Git-Oldrev: 3a39a31b8ae9c6465434aefa657f7fcc86f905c0 X-Git-Newrev: 3162ca09dbdc2ea3ff1d4b752edf76955b6d94f9 Message-Id: <20230626183516.54AAE3858D1E@sourceware.org> Date: Mon, 26 Jun 2023 18:35:16 +0000 (GMT) List-Id: https://gcc.gnu.org/g:3162ca09dbdc2ea3ff1d4b752edf76955b6d94f9 commit r14-2109-g3162ca09dbdc2ea3ff1d4b752edf76955b6d94f9 Author: Thomas Rodgers Date: Mon Jun 26 11:30:21 2023 -0700 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: --- libstdc++-v3/include/pstl/algorithm_fwd.h | 951 +++---- libstdc++-v3/include/pstl/algorithm_impl.h | 2830 ++++++++++---------- libstdc++-v3/include/pstl/execution_defs.h | 76 +- libstdc++-v3/include/pstl/execution_impl.h | 155 +- libstdc++-v3/include/pstl/glue_algorithm_impl.h | 545 ++-- libstdc++-v3/include/pstl/glue_execution_defs.h | 8 +- libstdc++-v3/include/pstl/glue_memory_impl.h | 293 +- libstdc++-v3/include/pstl/glue_numeric_impl.h | 83 +- libstdc++-v3/include/pstl/memory_impl.h | 20 +- libstdc++-v3/include/pstl/numeric_fwd.h | 94 +- libstdc++-v3/include/pstl/numeric_impl.h | 309 ++- libstdc++-v3/include/pstl/parallel_backend.h | 6 + .../include/pstl/parallel_backend_serial.h | 29 +- libstdc++-v3/include/pstl/parallel_backend_tbb.h | 30 +- libstdc++-v3/include/pstl/parallel_impl.h | 19 +- libstdc++-v3/include/pstl/pstl_config.h | 79 +- libstdc++-v3/include/pstl/unseq_backend_simd.h | 22 +- libstdc++-v3/include/pstl/utils.h | 65 +- .../pstl/uninitialized_construct.cc | 4 +- .../pstl/uninitialized_copy_move.cc | 14 +- .../pstl/uninitialized_fill_destroy.cc | 2 +- .../25_algorithms/pstl/alg_merge/inplace_merge.cc | 22 +- .../25_algorithms/pstl/alg_merge/merge.cc | 8 +- .../pstl/alg_modifying_operations/copy_if.cc | 10 +- .../pstl/alg_modifying_operations/copy_move.cc | 37 +- .../pstl/alg_modifying_operations/fill.cc | 4 +- .../pstl/alg_modifying_operations/generate.cc | 15 +- .../alg_modifying_operations/is_partitioned.cc | 12 +- .../pstl/alg_modifying_operations/partition.cc | 19 +- .../alg_modifying_operations/partition_copy.cc | 19 +- .../pstl/alg_modifying_operations/remove.cc | 31 +- .../pstl/alg_modifying_operations/remove_copy.cc | 11 +- .../pstl/alg_modifying_operations/replace.cc | 15 +- .../pstl/alg_modifying_operations/replace_copy.cc | 8 +- .../pstl/alg_modifying_operations/rotate.cc | 14 +- .../pstl/alg_modifying_operations/rotate_copy.cc | 10 +- .../pstl/alg_modifying_operations/swap_ranges.cc | 4 +- .../alg_modifying_operations/transform_binary.cc | 11 +- .../alg_modifying_operations/transform_unary.cc | 2 +- .../pstl/alg_modifying_operations/unique.cc | 22 +- .../alg_modifying_operations/unique_copy_equal.cc | 16 +- .../pstl/alg_nonmodifying/adjacent_find.cc | 14 +- .../25_algorithms/pstl/alg_nonmodifying/all_of.cc | 6 +- .../25_algorithms/pstl/alg_nonmodifying/any_of.cc | 6 +- .../25_algorithms/pstl/alg_nonmodifying/count.cc | 6 +- .../25_algorithms/pstl/alg_nonmodifying/equal.cc | 6 +- .../25_algorithms/pstl/alg_nonmodifying/find.cc | 14 +- .../pstl/alg_nonmodifying/find_end.cc | 110 +- .../pstl/alg_nonmodifying/find_first_of.cc | 14 +- .../25_algorithms/pstl/alg_nonmodifying/find_if.cc | 12 +- .../pstl/alg_nonmodifying/for_each.cc | 4 +- .../pstl/alg_nonmodifying/mismatch.cc | 4 +- .../25_algorithms/pstl/alg_nonmodifying/none_of.cc | 6 +- .../pstl/alg_nonmodifying/nth_element.cc | 13 +- .../25_algorithms/pstl/alg_nonmodifying/reverse.cc | 14 +- .../pstl/alg_nonmodifying/reverse_copy.cc | 13 +- .../pstl/alg_nonmodifying/search_n.cc | 14 +- .../25_algorithms/pstl/alg_sorting/includes.cc | 7 +- .../25_algorithms/pstl/alg_sorting/is_heap.cc | 15 +- .../25_algorithms/pstl/alg_sorting/is_sorted.cc | 4 +- .../pstl/alg_sorting/lexicographical_compare.cc | 4 +- .../pstl/alg_sorting/minmax_element.cc | 2 +- .../25_algorithms/pstl/alg_sorting/partial_sort.cc | 18 +- .../pstl/alg_sorting/partial_sort_copy.cc | 19 +- .../25_algorithms/pstl/alg_sorting/set.cc | 155 +- .../25_algorithms/pstl/alg_sorting/sort.cc | 10 +- .../pstl/numeric_ops/adjacent_difference.cc | 38 +- .../26_numerics/pstl/numeric_ops/reduce.cc | 4 +- .../testsuite/26_numerics/pstl/numeric_ops/scan.cc | 13 +- .../pstl/numeric_ops/transform_reduce.cc | 33 +- .../26_numerics/pstl/numeric_ops/transform_scan.cc | 24 +- libstdc++-v3/testsuite/util/pstl/test_utils.h | 94 +- 72 files changed, 3334 insertions(+), 3286 deletions(-) diff --git a/libstdc++-v3/include/pstl/algorithm_fwd.h b/libstdc++-v3/include/pstl/algorithm_fwd.h index e85125c4dc7..1ba9555e2a0 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 32c19990ed0..aec8c7484e7 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 3eca558dac2..522518c4116 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 e0969a1db9c..64f6cc4357a 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 b16306f2e99..5be45ce57fb 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 24ede331ac1..e7b36c7dd10 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 ea462e9ccdd..7850605f94a 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 9db64b513a4..490175c8b83 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 be5a103f93b..8cb32d043e5 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 d92cacb7644..e98e3b1e12b 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 0b02bcf0789..7ba83eeb714 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 4caa4a8e412..e9a90e11dba 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 16e773d411a..db2da43eb06 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 3fd1a06ebd8..3ff55237bff 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 46560c642ea..4cf2abde650 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[...] [diff truncated at 524288 bytes]