From 8139fb002eda0d312543cede70d18b5e1a1c0487 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Fri, 6 Apr 2018 10:17:29 -0500 Subject: [PATCH 1/6] Move execution policies to internal headers This is in preparation for libstdc++ integration The pstl policies themselves move to internal/execution_defs.h internal/execution_impl.h now refers to internal/execution_defs.h instead of ../execution The injection of pstl execution policies into namespace std:: moves to internal/glue_execution_defs.h In general, libstdc++ will re-export the internal/glue_*.h files from the pstl implementation. --- include/pstl/execution | 102 +------------------- include/pstl/internal/execution_defs.h | 94 ++++++++++++++++++ include/pstl/internal/execution_impl.h | 2 +- include/pstl/internal/glue_execution_defs.h | 60 ++++++++++++ 4 files changed, 157 insertions(+), 101 deletions(-) create mode 100644 include/pstl/internal/execution_defs.h create mode 100644 include/pstl/internal/glue_execution_defs.h diff --git a/include/pstl/execution b/include/pstl/execution index e51c9b53c1..9e85d93325 100644 --- a/include/pstl/execution +++ b/include/pstl/execution @@ -21,111 +21,13 @@ #ifndef __PSTL_execution_policy #define __PSTL_execution_policy -#include #include "internal/pstl_config.h" - -namespace pstl { -namespace execution { -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{};} -}; - -#if __PSTL_USE_PAR_POLICIES -// 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{};} -}; -#endif - -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 -constexpr sequenced_policy seq{}; -#if __PSTL_USE_PAR_POLICIES -constexpr parallel_policy par{}; -constexpr parallel_unsequenced_policy par_unseq{}; -#endif -constexpr unsequenced_policy unseq{}; - -// 2.3, Execution policy type trait -template struct is_execution_policy: std::false_type {}; - -template<> struct is_execution_policy: std::true_type {}; -#if __PSTL_USE_PAR_POLICIES -template<> struct is_execution_policy: std::true_type {}; -template<> struct is_execution_policy: std::true_type {}; -#endif -template<> struct is_execution_policy: std::true_type {}; - -#if __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT -template constexpr bool is_execution_policy_v = is_execution_policy::value; -#endif - -} //namespace v1 -} //namespace execution -} //namespace pstl +#include "internal/execution_defs.h" #if __PSTL_CPP17_EXECUTION_POLICIES_PRESENT __PSTL_PRAGMA_MESSAGE_POLICIES("The execution policies are defined in the namespace pstl::execution") #else -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; -#else - using pstl::execution::is_execution_policy_v; -#endif -#endif - - namespace execution { - // Standard C++ policy classes - using pstl::execution::sequenced_policy; -#if __PSTL_USE_PAR_POLICIES - using pstl::execution::parallel_policy; - using pstl::execution::parallel_unsequenced_policy; -#endif - // Standard predefined policy instances - using pstl::execution::seq; -#if __PSTL_USE_PAR_POLICIES - using pstl::execution::par; - using pstl::execution::par_unseq; -#endif - // Implementation-defined names - // Unsequenced policy is not yet standard, but for consistency - // we include it into namespace std::execution as well - using pstl::execution::unseq; - using pstl::execution::unsequenced_policy; - } -} +#include "internal/glue_execution_defs.h" __PSTL_PRAGMA_MESSAGE_POLICIES("The execution policies are injected into the standard namespace std::execution") #endif diff --git a/include/pstl/internal/execution_defs.h b/include/pstl/internal/execution_defs.h new file mode 100644 index 0000000000..819c02047d --- /dev/null +++ b/include/pstl/internal/execution_defs.h @@ -0,0 +1,94 @@ + +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_execution_policy_defs_H +#define __PSTL_execution_policy_defs_H + +#include + +namespace pstl { +namespace execution { +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{};} +}; + +#if __PSTL_USE_PAR_POLICIES +// 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{};} +}; +#endif + +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 +constexpr sequenced_policy seq{}; +#if __PSTL_USE_PAR_POLICIES +constexpr parallel_policy par{}; +constexpr parallel_unsequenced_policy par_unseq{}; +#endif +constexpr unsequenced_policy unseq{}; + +// 2.3, Execution policy type trait +template struct is_execution_policy: std::false_type {}; + +template<> struct is_execution_policy: std::true_type {}; +#if __PSTL_USE_PAR_POLICIES +template<> struct is_execution_policy: std::true_type {}; +template<> struct is_execution_policy: std::true_type {}; +#endif +template<> struct is_execution_policy: std::true_type {}; + +#if __PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT +template constexpr bool is_execution_policy_v = is_execution_policy::value; +#endif + +} //namespace v1 +} //namespace execution +} //namespace pstl +#endif /* __PSTL_execution_policy_defs_H */ diff --git a/include/pstl/internal/execution_impl.h b/include/pstl/internal/execution_impl.h index 27e4d9c81b..0cefa35aad 100644 --- a/include/pstl/internal/execution_impl.h +++ b/include/pstl/internal/execution_impl.h @@ -24,7 +24,7 @@ #include #include -#include "../execution" +#include "execution_defs.h" namespace pstl { namespace internal { diff --git a/include/pstl/internal/glue_execution_defs.h b/include/pstl/internal/glue_execution_defs.h new file mode 100644 index 0000000000..519decc708 --- /dev/null +++ b/include/pstl/internal/glue_execution_defs.h @@ -0,0 +1,60 @@ +// glue_execution_defs.h -*- C++ -*- + +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_glue_execution_defs_H +#define __PSTL_glue_execution_defs_H + +#include + +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; +#else + using pstl::execution::is_execution_policy_v; +#endif +#endif + + namespace execution { + // Standard C++ policy classes + using pstl::execution::sequenced_policy; +#if __PSTL_USE_PAR_POLICIES + using pstl::execution::parallel_policy; + using pstl::execution::parallel_unsequenced_policy; +#endif + // Standard predefined policy instances + using pstl::execution::seq; +#if __PSTL_USE_PAR_POLICIES + using pstl::execution::par; + using pstl::execution::par_unseq; +#endif + // Implementation-defined names + // Unsequenced policy is not yet standard, but for consistency + // we include it into namespace std::execution as well + using pstl::execution::unseq; + using pstl::execution::unsequenced_policy; + } +} + +#endif /* __PSTL_glue_execution_defs_H */ From d614e5930764c582c99a91fb1f7f162f5c02a81a Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Fri, 6 Apr 2018 17:36:54 -0500 Subject: [PATCH 2/6] Refacor header This change splits the contents of to two internal "glue" headers for integration with libstdc++ as follows - internal/glue_algorithm_defs.h - Includes only function prototypes, and is included by internal/glue_algorithm_impl.h - Has all implementation previously in this header is only included in . This will prevent compile-time regressions for consumers of (in libstdc++) which do not currently use the parallel versions of the algorithms, which are always dependent on execution policy, and thus always dependent on . --- include/pstl/algorithm | 901 +------------------ include/pstl/execution | 3 + include/pstl/internal/execution_defs.h | 5 + include/pstl/internal/execution_impl.h | 2 + include/pstl/internal/glue_algorithm_defs.h | 525 +++++++++++ include/pstl/internal/glue_algorithm_impl.h | 927 ++++++++++++++++++++ include/pstl/internal/glue_execution_defs.h | 2 + test/test_iterators.cpp | 1 + 8 files changed, 1466 insertions(+), 900 deletions(-) create mode 100644 include/pstl/internal/glue_algorithm_defs.h create mode 100644 include/pstl/internal/glue_algorithm_impl.h diff --git a/include/pstl/algorithm b/include/pstl/algorithm index a4c4c7912a..8c03c51ed3 100644 --- a/include/pstl/algorithm +++ b/include/pstl/algorithm @@ -21,906 +21,7 @@ #ifndef __PSTL_algorithm #define __PSTL_algorithm -#include - #include "internal/pstl_config.h" -#include "internal/utils.h" -#include "internal/algorithm_impl.h" -#include "internal/numeric_impl.h" /* count and count_if use pattern_transform_reduce */ - -namespace std { - -// [alg.any_of] - -template -pstl::internal::enable_if_execution_policy -any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { - using namespace pstl::internal; - return pattern_any_of( first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.all_of] - -template -pstl::internal::enable_if_execution_policy -all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Pred pred) { - return !any_of(std::forward(exec), first, last, pstl::internal::not_pred(pred)); -} - -// [alg.none_of] - -template -pstl::internal::enable_if_execution_policy -none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { - return !any_of( std::forward(exec), first, last, pred ); -} - -// [alg.foreach] - -template -pstl::internal::enable_if_execution_policy -for_each(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Function f) { - using namespace pstl::internal; - pattern_walk1( - first, last, f, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Function f) { - using namespace pstl::internal; - return pattern_walk1_n(first, n, f, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.find] - -template -pstl::internal::enable_if_execution_policy -find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { - using namespace pstl::internal; - return pattern_find_if( first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, -Predicate pred) { - return find_if(exec, first, last, pstl::internal::not_pred(pred)); -} - -template -pstl::internal::enable_if_execution_policy -find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, -const T& value) { - return find_if(exec, first, last, pstl::internal::equal_value(value)); -} - -// [alg.find.end] -template -pstl::internal::enable_if_execution_policy -find_end(ExecutionPolicy &&exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_find_end(first, last, s_first, s_last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -find_end(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { - return find_end(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); -} - -// [alg.find_first_of] -template -pstl::internal::enable_if_execution_policy -find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_find_first_of(first, last, s_first, s_last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { - return find_first_of(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); -} - -// [alg.adjacent_find] -template< class ExecutionPolicy, class ForwardIterator > -pstl::internal::enable_if_execution_policy -adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - return pattern_adjacent_find(first, last, std::equal_to(), - is_parallelization_preferred(exec), - is_vectorization_preferred(exec), /*first_semantic*/ false); -} - -template< class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> -pstl::internal::enable_if_execution_policy -adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_adjacent_find(first, last, pred, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec), /*first_semantic*/ false); -} - -// [alg.count] - -// Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce -// so that we do not have to include . - -template -pstl::internal::enable_if_execution_policy::difference_type> -count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - return pattern_count(first, last, [&value](const value_type& x) {return value==x;}, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy::difference_type> -count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { - using namespace pstl::internal; - return pattern_count(first, last, pred, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -// [alg.search] - -template -pstl::internal::enable_if_execution_policy -search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_search(first, last, s_first, s_last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { - return search(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); -} - -template -pstl::internal::enable_if_execution_policy -search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_search_n(first, last, count, value, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value) { - return search_n(exec, first, last, count, value, std::equal_to::value_type>()); -} - -// [alg.copy] - -template -pstl::internal::enable_if_execution_policy -copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { - using namespace pstl::internal; - const auto is_vector = is_vectorization_preferred(exec); - - return pattern_walk2_brick(first, last, result, [is_vector](ForwardIterator1 begin, ForwardIterator1 end, ForwardIterator2 res){ - return brick_copy(begin, end, res, is_vector); - }, is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result) { - using namespace pstl::internal; - const auto is_vector = is_vectorization_preferred(exec); - - return pattern_walk2_brick_n(first, n, result, [is_vector](ForwardIterator1 begin, Size sz, ForwardIterator2 res){ - return brick_copy_n(begin, sz, res, is_vector); - }, is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -copy_if(ExecutionPolicy&& exec, - ForwardIterator1 first, ForwardIterator1 last, - ForwardIterator2 result, Predicate pred) { - using namespace pstl::internal; - return pattern_copy_if( - first, last, result, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.swap] - -template -pstl::internal::enable_if_execution_policy -swap_ranges(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { - using namespace pstl::internal; - return pattern_swap_ranges(first1, last1, first2, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.transform] - -template -pstl::internal::enable_if_execution_policy -transform( ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryOperation op ) { - typedef typename iterator_traits::value_type input_type; - typedef typename iterator_traits::reference output_type; - using namespace pstl::internal; - return pattern_walk2(first, last, result, - [op](input_type x, output_type y ) mutable { y = op(x);}, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -transform( ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator result, BinaryOperation op ) { - typedef typename iterator_traits::value_type input1_type; - typedef typename iterator_traits::value_type input2_type; - typedef typename iterator_traits::reference output_type; - using namespace pstl::internal; - return pattern_walk3(first1, last1, first2, result, [op]( input1_type x, input2_type y, output_type z ) mutable {z = op(x,y);}, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.replace] - -template -pstl::internal::enable_if_execution_policy -replace_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value) { - using namespace pstl::internal; - typedef typename iterator_traits::reference element_type; - pattern_walk1(first, last, [&pred, &new_value] (element_type elem) { - if (pred(elem)) { - elem = new_value; - } - }, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -replace(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) { - replace_if(exec, first, last, pstl::internal::equal_value(old_value), new_value); -} - -template -pstl::internal::enable_if_execution_policy -replace_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryPredicate pred, const T& new_value) { - typedef typename iterator_traits::value_type input_type; - typedef typename iterator_traits::reference output_type; - using namespace pstl::internal; - return pattern_walk2( - first, last, result, - [pred, &new_value](input_type x, output_type y) mutable { y = pred(x) ? new_value : x; }, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -replace_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, const T& new_value) { - return replace_copy_if(exec, first, last, result, pstl::internal::equal_value(old_value), new_value); -} - -// [alg.fill] - -template -pstl::internal::enable_if_execution_policy -fill( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value ) { - using namespace pstl::internal; - pattern_fill(first, last, value, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator, class Size, class T> -pstl::internal::enable_if_execution_policy -fill_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, const T& value ) { - if(count <= 0) - return first; - - using namespace pstl::internal; - return pattern_fill_n(first, count, value, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -// [alg.generate] -template< class ExecutionPolicy, class ForwardIterator, class Generator> -pstl::internal::enable_if_execution_policy -generate( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Generator g ) { - using namespace pstl::internal; - pattern_generate(first, last, g, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator, class Size, class Generator> -pstl::internal::enable_if_execution_policy -generate_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, Generator g ) { - if(count <= 0) - return first; - - using namespace pstl::internal; - return pattern_generate_n(first, count, g, - is_parallelization_preferred(exec), - is_vectorization_preferred(exec)); -} - -// [alg.remove] - -template -pstl::internal::enable_if_execution_policy -remove_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred) { - return copy_if( exec, first, last, result, pstl::internal::not_pred(pred)); -} - -template -pstl::internal::enable_if_execution_policy -remove_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value) { - return copy_if( exec, first, last, result, pstl::internal::not_equal_value(value)); -} - -template -pstl::internal::enable_if_execution_policy -remove_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { - using namespace pstl::internal; - return pattern_remove_if(first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -remove(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { - return remove_if(exec, first, last, pstl::internal::equal_value(value)); -} - -// [alg.unique] - -template -pstl::internal::enable_if_execution_policy -unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_unique(first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - return unique(exec, first, last, pstl::internal::pstl_equal()); -} - -template -pstl::internal::enable_if_execution_policy -unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_unique_copy(first, last, result, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { - return unique_copy( exec, first, last, result, pstl::internal::pstl_equal() ); -} - -// [alg.reverse] - -template -pstl::internal::enable_if_execution_policy -reverse(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last) { - using namespace pstl::internal; - pattern_reverse(first, last, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -reverse_copy(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, ForwardIterator d_first) { - using namespace pstl::internal; - return pattern_reverse_copy(first, last, d_first, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.rotate] - -template -pstl::internal::enable_if_execution_policy -rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last) { - using namespace pstl::internal; - return pattern_rotate(first, middle, last, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -rotate_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result) { - using namespace pstl::internal; - return pattern_rotate_copy(first, middle, last, result, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.partitions] - -template -pstl::internal::enable_if_execution_policy -is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { - using namespace pstl::internal; - return pattern_is_partitioned(first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { - using namespace pstl::internal; - return pattern_partition(first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -stable_partition(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred) { - using namespace pstl::internal; - return pattern_stable_partition(first, last, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy> -partition_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, UnaryPredicate pred) { - using namespace pstl::internal; - return pattern_partition_copy(first, last, out_true, out_false, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [alg.sort] - -template -pstl::internal::enable_if_execution_policy -sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { - typedef typename iterator_traits::value_type input_type; - using namespace pstl::internal; - return pattern_sort(first, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec), - typename std::is_move_constructible::type()); -} - -template -pstl::internal::enable_if_execution_policy -sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - sort(exec, first, last, std::less()); -} - -// [stable.sort] - -template -pstl::internal::enable_if_execution_policy -stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_stable_sort(first, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - stable_sort(exec, first, last, std::less()); -} - -// [mismatch] - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > -pstl::internal::enable_if_execution_policy> -mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred) { - using namespace pstl::internal; - return pattern_mismatch(first1, last1, first2, last2, pred, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > -pstl::internal::enable_if_execution_policy> -mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred) { - return mismatch(exec, first1, last1, first2, std::next(first2, std::distance(first1, last1)), pred); -} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > -pstl::internal::enable_if_execution_policy> -mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { -return mismatch(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_equal());} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > -pstl::internal::enable_if_execution_policy> -mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { - return mismatch(exec, first1, last1, first2, std::next(first2, std::distance(first1, last1))); -} - -// [alg.equal] - -template -pstl::internal::enable_if_execution_policy -equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate p) { - using namespace pstl::internal; - return pattern_equal(first1, last1, first2, p, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec) - ); -} - -template -pstl::internal::enable_if_execution_policy -equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { - return equal(exec, first1, last1, first2, pstl::internal::pstl_equal()); -} - -template -pstl::internal::enable_if_execution_policy -equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate p) { - if ( std::distance(first1, last1) == std::distance(first2, last2) ) - return std::equal(first1, last1, first2, p); - else - return false; -} - -template -pstl::internal::enable_if_execution_policy -equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { - return equal(first1, last1, first2, pstl::internal::pstl_equal()); -} - -// [alg.move] -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > -pstl::internal::enable_if_execution_policy -move(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first) { - using namespace pstl::internal; - const auto is_vector = is_vectorization_preferred(exec); - - return pattern_walk2_brick(first, last, d_first, [is_vector](ForwardIterator1 begin, ForwardIterator1 end, ForwardIterator2 res) { - return brick_move(begin, end, res, is_vector); - }, is_parallelization_preferred(exec)); -} - -// [partial.sort] - -template -pstl::internal::enable_if_execution_policy -partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp) { - using namespace pstl::internal; - pattern_partial_sort(first, middle, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - partial_sort(exec, first, middle, last, std::less()); -} - -// [partial.sort.copy] - -template -pstl::internal::enable_if_execution_policy -partial_sort_copy(ExecutionPolicy&& exec, _InputIterator first, _InputIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, Compare comp) { - using namespace pstl::internal; - return pattern_partial_sort_copy(first, last, d_first, d_last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last) { - return partial_sort_copy(std::forward(exec), first, last, d_first, d_last, pstl::internal::pstl_less()); -} - -// [is.sorted] -template -pstl::internal::enable_if_execution_policy -is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { - using namespace pstl::internal; - const ForwardIterator res = pattern_adjacent_find(first, last, pstl::internal::reorder_pred(comp), - is_parallelization_preferred(exec), - is_vectorization_preferred(exec), /*first_semantic*/ false); - return res==last ? last : std::next(res); -} - -template -pstl::internal::enable_if_execution_policy -is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type input_type; - return is_sorted_until(exec, first, last, std::less()); -} - -template -pstl::internal::enable_if_execution_policy -is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_adjacent_find(first, last, reorder_pred(comp), - is_parallelization_preferred(exec), - is_vectorization_preferred(exec), /*or_semantic*/ true)==last; -} - -template -pstl::internal::enable_if_execution_policy -is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type input_type; - return is_sorted(exec, first, last, std::less()); -} - -// [alg.nth.element] - -template -pstl::internal::enable_if_execution_policy -nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp) { - using namespace pstl::internal; - pattern_nth_element(first, nth, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - nth_element(exec, first, nth, last, std::less()); -} - -// [alg.merge] -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> -pstl::internal::enable_if_execution_policy -merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator d_first, Compare comp) { - using namespace pstl::internal; - return pattern_merge(first1, last1, first2, last2, d_first, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> -pstl::internal::enable_if_execution_policy -merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator d_first) { - return merge(std::forward(exec), first1, last1, first2, last2, d_first, pstl::internal::pstl_less()); -} - -template< class ExecutionPolicy, class BidirectionalIterator, class Compare> -pstl::internal::enable_if_execution_policy -inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp) { - using namespace pstl::internal; - pattern_inplace_merge(first, middle, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class BidirectionalIterator> -pstl::internal::enable_if_execution_policy -inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last) { - typedef typename iterator_traits::value_type input_type; - inplace_merge(exec, first, middle, last, std::less()); -} - -// [includes] - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare> -pstl::internal::enable_if_execution_policy -includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp) { - using namespace pstl::internal; - return pattern_includes(first1, last1, first2, last2, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> -pstl::internal::enable_if_execution_policy -includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { - return includes(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_less());} - -// [set.union] - -template -pstl::internal::enable_if_execution_policy -set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { - using namespace pstl::internal; - return pattern_set_union(first1, last1, first2, last2, result, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, - ForwardIterator2 last2, ForwardIterator result) { - return set_union(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); -} - -// [set.intersection] - -template -pstl::internal::enable_if_execution_policy -set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { - using namespace pstl::internal; - return pattern_set_intersection(first1, last1, first2, last2, result, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { - return set_intersection(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); -} - -// [set.difference] - -template -pstl::internal::enable_if_execution_policy -set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { - using namespace pstl::internal; - return pattern_set_difference(first1, last1, first2, last2, result, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { - return set_difference(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); -} - -// [set.symmetric.difference] - -template -pstl::internal::enable_if_execution_policy -set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { - using namespace pstl::internal; - return pattern_set_symmetric_difference(first1, last1, first2, last2, result, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { - return set_symmetric_difference(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); -} - -// [is.heap] -template< class ExecutionPolicy, class RandomAccessIterator, class Compare > -pstl::internal::enable_if_execution_policy -is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_is_heap_until(first, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class RandomAccessIterator > -pstl::internal::enable_if_execution_policy -is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - return is_heap_until(exec, first, last, std::less()); -} - -template< class ExecutionPolicy, class RandomAccessIterator, class Compare > -pstl::internal::enable_if_execution_policy -is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { - return is_heap_until(exec, first, last, comp) == last; -} - -template< class ExecutionPolicy, class RandomAccessIterator > -pstl::internal::enable_if_execution_policy -is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { - typedef typename iterator_traits::value_type input_type; - return is_heap(exec, first, last, std::less()); -} - -// [alg.min.max] - -template< class ExecutionPolicy, class ForwardIterator, class Compare > -pstl::internal::enable_if_execution_policy -min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_min_element(first, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator > -pstl::internal::enable_if_execution_policy -min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type input_type; - return min_element(exec, first, last, std::less()); -} - -template< class ExecutionPolicy, class ForwardIterator, class Compare > -pstl::internal::enable_if_execution_policy -max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_min_element(first, last, pstl::internal::reorder_pred(comp), - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator > -pstl::internal::enable_if_execution_policy -max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type input_type; - return min_element(exec, first, last, pstl::internal::reorder_pred >(std::less())); -} - -template< class ExecutionPolicy, class ForwardIterator, class Compare > -pstl::internal::enable_if_execution_policy> -minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { - using namespace pstl::internal; - return pattern_minmax_element(first, last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator > -pstl::internal::enable_if_execution_policy> -minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type value_type; - return minmax_element(exec, first, last, std::less()); -} - -// [alg.lex.comparison] - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare > -pstl::internal::enable_if_execution_policy -lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp) { - using namespace pstl::internal; - return pattern_lexicographical_compare(first1, last1, first2, last2, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > -pstl::internal::enable_if_execution_policy -lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { - return lexicographical_compare(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_less()); -} - -} // namespace std +#include "internal/glue_algorithm_defs.h" #endif /* __PSTL_algorithm */ diff --git a/include/pstl/execution b/include/pstl/execution index 9e85d93325..6a08da1649 100644 --- a/include/pstl/execution +++ b/include/pstl/execution @@ -24,6 +24,9 @@ #include "internal/pstl_config.h" #include "internal/execution_defs.h" +// Algorithm implementation +#include "internal/glue_algorithm_impl.h" + #if __PSTL_CPP17_EXECUTION_POLICIES_PRESENT __PSTL_PRAGMA_MESSAGE_POLICIES("The execution policies are defined in the namespace pstl::execution") #else diff --git a/include/pstl/internal/execution_defs.h b/include/pstl/internal/execution_defs.h index 819c02047d..ba8a7f4d13 100644 --- a/include/pstl/internal/execution_defs.h +++ b/include/pstl/internal/execution_defs.h @@ -90,5 +90,10 @@ template constexpr bool is_execution_policy_v = is_execution_policy: } //namespace v1 } //namespace execution + +namespace internal { + template using enable_if_execution_policy = typename std::enable_if< + pstl::execution::is_execution_policy::type>::value, T>::type; +} // namespace internal } //namespace pstl #endif /* __PSTL_execution_policy_defs_H */ diff --git a/include/pstl/internal/execution_impl.h b/include/pstl/internal/execution_impl.h index 0cefa35aad..13746fe473 100644 --- a/include/pstl/internal/execution_impl.h +++ b/include/pstl/internal/execution_impl.h @@ -96,8 +96,10 @@ struct policy_traits { }; #endif +/* template using enable_if_execution_policy = typename std::enable_if< is_execution_policy::type>::value, T>::type; +*/ template using collector_t = typename policy_traits::type>::collector_type; diff --git a/include/pstl/internal/glue_algorithm_defs.h b/include/pstl/internal/glue_algorithm_defs.h new file mode 100644 index 0000000000..97a9fd2842 --- /dev/null +++ b/include/pstl/internal/glue_algorithm_defs.h @@ -0,0 +1,525 @@ +// glue_algorithm_defs.h -*- C++ -*- + +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_glue_algorithm_defs_H_ +#define __PSTL_glue_algorithm_defs_H_ + +#include + +#include "execution_defs.h" + + +namespace std { + +// [alg.any_of] + +template +pstl::internal::enable_if_execution_policy +any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + +// [alg.all_of] + +template +pstl::internal::enable_if_execution_policy +all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Pred pred); + +// [alg.none_of] + +template +pstl::internal::enable_if_execution_policy +none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + +// [alg.foreach] + +template +pstl::internal::enable_if_execution_policy +for_each(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Function f); + +template +pstl::internal::enable_if_execution_policy +for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Function f); + +// [alg.find] + +template +pstl::internal::enable_if_execution_policy +find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + +template +pstl::internal::enable_if_execution_policy +find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + +template +pstl::internal::enable_if_execution_policy +find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); + +// [alg.find.end] + +template +pstl::internal::enable_if_execution_policy +find_end(ExecutionPolicy &&exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, + BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +find_end(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last); + +// [alg.find_first_of] + +template +pstl::internal::enable_if_execution_policy +find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, + BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last); + +// [alg.adjacent_find] + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template< class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> +pstl::internal::enable_if_execution_policy +adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred); + +// [alg.count] + +template +pstl::internal::enable_if_execution_policy::difference_type> +count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); + +template +pstl::internal::enable_if_execution_policy::difference_type> +count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred); + +// [alg.search] + +template +pstl::internal::enable_if_execution_policy +search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, + BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last); + +template +pstl::internal::enable_if_execution_policy +search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value); + +// [alg.copy] + +template +pstl::internal::enable_if_execution_policy +copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template +pstl::internal::enable_if_execution_policy +copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result); + +template +pstl::internal::enable_if_execution_policy +copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred); + +// [alg.swap] + +template +pstl::internal::enable_if_execution_policy +swap_ranges(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); + +// [alg.transform] + +template +pstl::internal::enable_if_execution_policy +transform( ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryOperation op ); + +template +pstl::internal::enable_if_execution_policy +transform(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator result, + BinaryOperation op); + +// [alg.replace] + +template +pstl::internal::enable_if_execution_policy +replace_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value); + +template +pstl::internal::enable_if_execution_policy +replace(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); + +template +pstl::internal::enable_if_execution_policy +replace_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryPredicate pred, + const T& new_value); + +template +pstl::internal::enable_if_execution_policy +replace_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, + const T& new_value); + +// [alg.fill] + +template +pstl::internal::enable_if_execution_policy +fill( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value ); + +template< class ExecutionPolicy, class ForwardIterator, class Size, class T> +pstl::internal::enable_if_execution_policy +fill_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, const T& value ); + +// [alg.generate] +template< class ExecutionPolicy, class ForwardIterator, class Generator> +pstl::internal::enable_if_execution_policy +generate( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Generator g ); + +template< class ExecutionPolicy, class ForwardIterator, class Size, class Generator> +pstl::internal::enable_if_execution_policy +generate_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, Generator g ); + +// [alg.remove] + +template +pstl::internal::enable_if_execution_policy +remove_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred); + +template +pstl::internal::enable_if_execution_policy +remove_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value); + +template +pstl::internal::enable_if_execution_policy +remove_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +remove(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); + +// [alg.unique] + +template +pstl::internal::enable_if_execution_policy +unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +// [alg.reverse] + +template +pstl::internal::enable_if_execution_policy +reverse(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last); + +template +pstl::internal::enable_if_execution_policy +reverse_copy(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, ForwardIterator d_first); + +// [alg.rotate] + +template +pstl::internal::enable_if_execution_policy +rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +rotate_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result); + +// [alg.partitions] + +template +pstl::internal::enable_if_execution_policy +is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy +stable_partition(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred); + +template +pstl::internal::enable_if_execution_policy> +partition_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, + UnaryPredicate pred); + +// [alg.sort] + +template +pstl::internal::enable_if_execution_policy +sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); + +// [stable.sort] + +template +pstl::internal::enable_if_execution_policy +stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); + +// [mismatch] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + BinaryPredicate pred); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); + +// [alg.equal] + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate p); + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2); + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate p); + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); + +// [alg.move] +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy +move(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first); + +// [partial.sort] + +template +pstl::internal::enable_if_execution_policy +partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last); + +// [partial.sort.copy] + +template +pstl::internal::enable_if_execution_policy +partial_sort_copy(ExecutionPolicy&& exec, _InputIterator first, _InputIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, + Compare comp); + +template +pstl::internal::enable_if_execution_policy +partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last); + +// [is.sorted] +template +pstl::internal::enable_if_execution_policy +is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +// [alg.nth.element] + +template +pstl::internal::enable_if_execution_policy +nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp); + +template +pstl::internal::enable_if_execution_policy +nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last); + +// [alg.merge] +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> +pstl::internal::enable_if_execution_policy +merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator d_first, Compare comp); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> +pstl::internal::enable_if_execution_policy +merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator d_first); + +template< class ExecutionPolicy, class BidirectionalIterator, class Compare> +pstl::internal::enable_if_execution_policy +inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp); + +template< class ExecutionPolicy, class BidirectionalIterator> +pstl::internal::enable_if_execution_policy +inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last); + +// [includes] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare> +pstl::internal::enable_if_execution_policy +includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> +pstl::internal::enable_if_execution_policy +includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); + +// [set.union] + +template +pstl::internal::enable_if_execution_policy +set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +template +pstl::internal::enable_if_execution_policy +set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, + ForwardIterator2 last2, ForwardIterator result); + +// [set.intersection] + +template +pstl::internal::enable_if_execution_policy +set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +template +pstl::internal::enable_if_execution_policy +set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +// [set.difference] + +template +pstl::internal::enable_if_execution_policy +set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +template +pstl::internal::enable_if_execution_policy +set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +// [set.symmetric.difference] + +template +pstl::internal::enable_if_execution_policy +set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result, Compare comp); + +template +pstl::internal::enable_if_execution_policy +set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + ForwardIterator result); + +// [is.heap] +template< class ExecutionPolicy, class RandomAccessIterator, class Compare > +pstl::internal::enable_if_execution_policy +is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template< class ExecutionPolicy, class RandomAccessIterator > +pstl::internal::enable_if_execution_policy +is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); + +template< class ExecutionPolicy, class RandomAccessIterator, class Compare > +pstl::internal::enable_if_execution_policy +is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp); + +template< class ExecutionPolicy, class RandomAccessIterator > +pstl::internal::enable_if_execution_policy +is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last); + +// [alg.min.max] + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy +min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy +max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy> +minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp); + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy> +minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +// [alg.lex.comparison] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare > +pstl::internal::enable_if_execution_policy +lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, + Compare comp); + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy +lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); + +} // namespace std +#endif /* __PSTL_glue_algorithm_defs_H_ */ diff --git a/include/pstl/internal/glue_algorithm_impl.h b/include/pstl/internal/glue_algorithm_impl.h new file mode 100644 index 0000000000..7e4a685e56 --- /dev/null +++ b/include/pstl/internal/glue_algorithm_impl.h @@ -0,0 +1,927 @@ +// glue_algorithm_impl.h -*- C++ -*- + +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_glue_algorithm_impl_H_ + +#include + +#include "execution_defs.h" +#include "utils.h" +#include "algorithm_impl.h" +#include "numeric_impl.h" /* count and count_if use pattern_transform_reduce */ + +namespace std { +// [alg.any_of] + +template +pstl::internal::enable_if_execution_policy +any_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { + using namespace pstl::internal; + return pattern_any_of( first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.all_of] + +template +pstl::internal::enable_if_execution_policy +all_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Pred pred) { + return !any_of(std::forward(exec), first, last, pstl::internal::not_pred(pred)); +} + +// [alg.none_of] + +template +pstl::internal::enable_if_execution_policy +none_of(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { + return !any_of( std::forward(exec), first, last, pred ); +} + +// [alg.foreach] + +template +pstl::internal::enable_if_execution_policy +for_each(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Function f) { + using namespace pstl::internal; + pattern_walk1( + first, last, f, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +for_each_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, Function f) { + using namespace pstl::internal; + return pattern_walk1_n(first, n, f, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.find] + +template +pstl::internal::enable_if_execution_policy +find_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { + using namespace pstl::internal; + return pattern_find_if( first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +find_if_not(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, +Predicate pred) { + return find_if(exec, first, last, pstl::internal::not_pred(pred)); +} + +template +pstl::internal::enable_if_execution_policy +find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, +const T& value) { + return find_if(exec, first, last, pstl::internal::equal_value(value)); +} + +// [alg.find.end] +template +pstl::internal::enable_if_execution_policy +find_end(ExecutionPolicy &&exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_find_end(first, last, s_first, s_last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +find_end(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { + return find_end(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); +} + +// [alg.find_first_of] +template +pstl::internal::enable_if_execution_policy +find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_find_first_of(first, last, s_first, s_last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +find_first_of(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { + return find_first_of(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); +} + +// [alg.adjacent_find] +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + return pattern_adjacent_find(first, last, std::equal_to(), + is_parallelization_preferred(exec), + is_vectorization_preferred(exec), /*first_semantic*/ false); +} + +template< class ExecutionPolicy, class ForwardIterator, class BinaryPredicate> +pstl::internal::enable_if_execution_policy +adjacent_find(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_adjacent_find(first, last, pred, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec), /*first_semantic*/ false); +} + +// [alg.count] + +// Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce +// so that we do not have to include . + +template +pstl::internal::enable_if_execution_policy::difference_type> +count(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + return pattern_count(first, last, [&value](const value_type& x) {return value==x;}, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy::difference_type> +count_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Predicate pred) { + using namespace pstl::internal; + return pattern_count(first, last, pred, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +// [alg.search] + +template +pstl::internal::enable_if_execution_policy +search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_search(first, last, s_first, s_last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +search(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 s_first, ForwardIterator2 s_last) { + return search(std::forward(exec), first, last, s_first, s_last, pstl::internal::pstl_equal()); +} + +template +pstl::internal::enable_if_execution_policy +search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_search_n(first, last, count, value, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +search_n(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Size count, const T& value) { + return search_n(exec, first, last, count, value, std::equal_to::value_type>()); +} + +// [alg.copy] + +template +pstl::internal::enable_if_execution_policy +copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { + using namespace pstl::internal; + const auto is_vector = is_vectorization_preferred(exec); + + return pattern_walk2_brick(first, last, result, [is_vector](ForwardIterator1 begin, ForwardIterator1 end, ForwardIterator2 res){ + return brick_copy(begin, end, res, is_vector); + }, is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +copy_n(ExecutionPolicy&& exec, ForwardIterator1 first, Size n, ForwardIterator2 result) { + using namespace pstl::internal; + const auto is_vector = is_vectorization_preferred(exec); + + return pattern_walk2_brick_n(first, n, result, [is_vector](ForwardIterator1 begin, Size sz, ForwardIterator2 res){ + return brick_copy_n(begin, sz, res, is_vector); + }, is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +copy_if(ExecutionPolicy&& exec, + ForwardIterator1 first, ForwardIterator1 last, + ForwardIterator2 result, Predicate pred) { + using namespace pstl::internal; + return pattern_copy_if( + first, last, result, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.swap] + +template +pstl::internal::enable_if_execution_policy +swap_ranges(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { + using namespace pstl::internal; + return pattern_swap_ranges(first1, last1, first2, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.transform] + +template +pstl::internal::enable_if_execution_policy +transform( ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryOperation op ) { + typedef typename iterator_traits::value_type input_type; + typedef typename iterator_traits::reference output_type; + using namespace pstl::internal; + return pattern_walk2(first, last, result, + [op](input_type x, output_type y ) mutable { y = op(x);}, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +transform( ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator result, BinaryOperation op ) { + typedef typename iterator_traits::value_type input1_type; + typedef typename iterator_traits::value_type input2_type; + typedef typename iterator_traits::reference output_type; + using namespace pstl::internal; + return pattern_walk3(first1, last1, first2, result, [op]( input1_type x, input2_type y, output_type z ) mutable {z = op(x,y);}, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.replace] + +template +pstl::internal::enable_if_execution_policy +replace_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred, const T& new_value) { + using namespace pstl::internal; + typedef typename iterator_traits::reference element_type; + pattern_walk1(first, last, [&pred, &new_value] (element_type elem) { + if (pred(elem)) { + elem = new_value; + } + }, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +replace(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) { + replace_if(exec, first, last, pstl::internal::equal_value(old_value), new_value); +} + +template +pstl::internal::enable_if_execution_policy +replace_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, UnaryPredicate pred, const T& new_value) { + typedef typename iterator_traits::value_type input_type; + typedef typename iterator_traits::reference output_type; + using namespace pstl::internal; + return pattern_walk2( + first, last, result, + [pred, &new_value](input_type x, output_type y) mutable { y = pred(x) ? new_value : x; }, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +replace_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& old_value, const T& new_value) { + return replace_copy_if(exec, first, last, result, pstl::internal::equal_value(old_value), new_value); +} + +// [alg.fill] + +template +pstl::internal::enable_if_execution_policy +fill( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value ) { + using namespace pstl::internal; + pattern_fill(first, last, value, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator, class Size, class T> +pstl::internal::enable_if_execution_policy +fill_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, const T& value ) { + if(count <= 0) + return first; + + using namespace pstl::internal; + return pattern_fill_n(first, count, value, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +// [alg.generate] +template< class ExecutionPolicy, class ForwardIterator, class Generator> +pstl::internal::enable_if_execution_policy +generate( ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Generator g ) { + using namespace pstl::internal; + pattern_generate(first, last, g, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator, class Size, class Generator> +pstl::internal::enable_if_execution_policy +generate_n( ExecutionPolicy&& exec, ForwardIterator first, Size count, Generator g ) { + if(count <= 0) + return first; + + using namespace pstl::internal; + return pattern_generate_n(first, count, g, + is_parallelization_preferred(exec), + is_vectorization_preferred(exec)); +} + +// [alg.remove] + +template +pstl::internal::enable_if_execution_policy +remove_copy_if(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, Predicate pred) { + return copy_if( exec, first, last, result, pstl::internal::not_pred(pred)); +} + +template +pstl::internal::enable_if_execution_policy +remove_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, const T& value) { + return copy_if( exec, first, last, result, pstl::internal::not_equal_value(value)); +} + +template +pstl::internal::enable_if_execution_policy +remove_if(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { + using namespace pstl::internal; + return pattern_remove_if(first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +remove(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { + return remove_if(exec, first, last, pstl::internal::equal_value(value)); +} + +// [alg.unique] + +template +pstl::internal::enable_if_execution_policy +unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_unique(first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +unique(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + return unique(exec, first, last, pstl::internal::pstl_equal()); +} + +template +pstl::internal::enable_if_execution_policy +unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_unique_copy(first, last, result, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +unique_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { + return unique_copy( exec, first, last, result, pstl::internal::pstl_equal() ); +} + +// [alg.reverse] + +template +pstl::internal::enable_if_execution_policy +reverse(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last) { + using namespace pstl::internal; + pattern_reverse(first, last, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +reverse_copy(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, ForwardIterator d_first) { + using namespace pstl::internal; + return pattern_reverse_copy(first, last, d_first, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.rotate] + +template +pstl::internal::enable_if_execution_policy +rotate(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator middle, ForwardIterator last) { + using namespace pstl::internal; + return pattern_rotate(first, middle, last, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +rotate_copy(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last, ForwardIterator2 result) { + using namespace pstl::internal; + return pattern_rotate_copy(first, middle, last, result, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.partitions] + +template +pstl::internal::enable_if_execution_policy +is_partitioned(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { + using namespace pstl::internal; + return pattern_is_partitioned(first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +partition(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, UnaryPredicate pred) { + using namespace pstl::internal; + return pattern_partition(first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +stable_partition(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred) { + using namespace pstl::internal; + return pattern_stable_partition(first, last, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy> +partition_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, ForwardIterator1 out_true, ForwardIterator2 out_false, UnaryPredicate pred) { + using namespace pstl::internal; + return pattern_partition_copy(first, last, out_true, out_false, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [alg.sort] + +template +pstl::internal::enable_if_execution_policy +sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { + typedef typename iterator_traits::value_type input_type; + using namespace pstl::internal; + return pattern_sort(first, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec), + typename std::is_move_constructible::type()); +} + +template +pstl::internal::enable_if_execution_policy +sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + sort(exec, first, last, std::less()); +} + +// [stable.sort] + +template +pstl::internal::enable_if_execution_policy +stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_stable_sort(first, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +stable_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + stable_sort(exec, first, last, std::less()); +} + +// [mismatch] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred) { + using namespace pstl::internal; + return pattern_mismatch(first1, last1, first2, last2, pred, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class BinaryPredicate > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate pred) { + return mismatch(exec, first1, last1, first2, std::next(first2, std::distance(first1, last1)), pred); +} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { +return mismatch(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_equal());} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy> +mismatch(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { + return mismatch(exec, first1, last1, first2, std::next(first2, std::distance(first1, last1))); +} + +// [alg.equal] + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, BinaryPredicate p) { + using namespace pstl::internal; + return pattern_equal(first1, last1, first2, p, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec) + ); +} + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2) { + return equal(exec, first1, last1, first2, pstl::internal::pstl_equal()); +} + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate p) { + if ( std::distance(first1, last1) == std::distance(first2, last2) ) + return std::equal(first1, last1, first2, p); + else + return false; +} + +template +pstl::internal::enable_if_execution_policy +equal(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { + return equal(first1, last1, first2, pstl::internal::pstl_equal()); +} + +// [alg.move] +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy +move(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first) { + using namespace pstl::internal; + const auto is_vector = is_vectorization_preferred(exec); + + return pattern_walk2_brick(first, last, d_first, [is_vector](ForwardIterator1 begin, ForwardIterator1 end, ForwardIterator2 res) { + return brick_move(begin, end, res, is_vector); + }, is_parallelization_preferred(exec)); +} + +// [partial.sort] + +template +pstl::internal::enable_if_execution_policy +partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last, Compare comp) { + using namespace pstl::internal; + pattern_partial_sort(first, middle, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + partial_sort(exec, first, middle, last, std::less()); +} + +// [partial.sort.copy] + +template +pstl::internal::enable_if_execution_policy +partial_sort_copy(ExecutionPolicy&& exec, _InputIterator first, _InputIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, Compare comp) { + using namespace pstl::internal; + return pattern_partial_sort_copy(first, last, d_first, d_last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last) { + return partial_sort_copy(std::forward(exec), first, last, d_first, d_last, pstl::internal::pstl_less()); +} + +// [is.sorted] +template +pstl::internal::enable_if_execution_policy +is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { + using namespace pstl::internal; + const ForwardIterator res = pattern_adjacent_find(first, last, pstl::internal::reorder_pred(comp), + is_parallelization_preferred(exec), + is_vectorization_preferred(exec), /*first_semantic*/ false); + return res==last ? last : std::next(res); +} + +template +pstl::internal::enable_if_execution_policy +is_sorted_until(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type input_type; + return is_sorted_until(exec, first, last, std::less()); +} + +template +pstl::internal::enable_if_execution_policy +is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_adjacent_find(first, last, reorder_pred(comp), + is_parallelization_preferred(exec), + is_vectorization_preferred(exec), /*or_semantic*/ true)==last; +} + +template +pstl::internal::enable_if_execution_policy +is_sorted(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type input_type; + return is_sorted(exec, first, last, std::less()); +} + +// [alg.nth.element] + +template +pstl::internal::enable_if_execution_policy +nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp) { + using namespace pstl::internal; + pattern_nth_element(first, nth, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +nth_element(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + nth_element(exec, first, nth, last, std::less()); +} + +// [alg.merge] +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator, class Compare> +pstl::internal::enable_if_execution_policy +merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator d_first, Compare comp) { + using namespace pstl::internal; + return pattern_merge(first1, last1, first2, last2, d_first, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class ForwardIterator> +pstl::internal::enable_if_execution_policy +merge(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator d_first) { + return merge(std::forward(exec), first1, last1, first2, last2, d_first, pstl::internal::pstl_less()); +} + +template< class ExecutionPolicy, class BidirectionalIterator, class Compare> +pstl::internal::enable_if_execution_policy +inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp) { + using namespace pstl::internal; + pattern_inplace_merge(first, middle, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class BidirectionalIterator> +pstl::internal::enable_if_execution_policy +inplace_merge(ExecutionPolicy&& exec, BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last) { + typedef typename iterator_traits::value_type input_type; + inplace_merge(exec, first, middle, last, std::less()); +} + +// [includes] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare> +pstl::internal::enable_if_execution_policy +includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp) { + using namespace pstl::internal; + return pattern_includes(first1, last1, first2, last2, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2> +pstl::internal::enable_if_execution_policy +includes(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { + return includes(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_less());} + +// [set.union] + +template +pstl::internal::enable_if_execution_policy +set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { + using namespace pstl::internal; + return pattern_set_union(first1, last1, first2, last2, result, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +set_union(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, + ForwardIterator2 last2, ForwardIterator result) { + return set_union(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); +} + +// [set.intersection] + +template +pstl::internal::enable_if_execution_policy +set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { + using namespace pstl::internal; + return pattern_set_intersection(first1, last1, first2, last2, result, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +set_intersection(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { + return set_intersection(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); +} + +// [set.difference] + +template +pstl::internal::enable_if_execution_policy +set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { + using namespace pstl::internal; + return pattern_set_difference(first1, last1, first2, last2, result, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +set_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { + return set_difference(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); +} + +// [set.symmetric.difference] + +template +pstl::internal::enable_if_execution_policy +set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result, Compare comp) { + using namespace pstl::internal; + return pattern_set_symmetric_difference(first1, last1, first2, last2, result, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +set_symmetric_difference(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, ForwardIterator result) { + return set_symmetric_difference(std::forward(exec), first1, last1, first2, last2, result, pstl::internal::pstl_less()); +} + +// [is.heap] +template< class ExecutionPolicy, class RandomAccessIterator, class Compare > +pstl::internal::enable_if_execution_policy +is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_is_heap_until(first, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class RandomAccessIterator > +pstl::internal::enable_if_execution_policy +is_heap_until(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + return is_heap_until(exec, first, last, std::less()); +} + +template< class ExecutionPolicy, class RandomAccessIterator, class Compare > +pstl::internal::enable_if_execution_policy +is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, Compare comp) { + return is_heap_until(exec, first, last, comp) == last; +} + +template< class ExecutionPolicy, class RandomAccessIterator > +pstl::internal::enable_if_execution_policy +is_heap(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) { + typedef typename iterator_traits::value_type input_type; + return is_heap(exec, first, last, std::less()); +} + +// [alg.min.max] + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy +min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_min_element(first, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +min_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type input_type; + return min_element(exec, first, last, std::less()); +} + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy +max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_min_element(first, last, pstl::internal::reorder_pred(comp), + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy +max_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type input_type; + return min_element(exec, first, last, pstl::internal::reorder_pred >(std::less())); +} + +template< class ExecutionPolicy, class ForwardIterator, class Compare > +pstl::internal::enable_if_execution_policy> +minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, Compare comp) { + using namespace pstl::internal; + return pattern_minmax_element(first, last, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator > +pstl::internal::enable_if_execution_policy> +minmax_element(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type value_type; + return minmax_element(exec, first, last, std::less()); +} + +// [alg.lex.comparison] + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2, class Compare > +pstl::internal::enable_if_execution_policy +lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, Compare comp) { + using namespace pstl::internal; + return pattern_lexicographical_compare(first1, last1, first2, last2, comp, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template< class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2 > +pstl::internal::enable_if_execution_policy +lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) { + return lexicographical_compare(std::forward(exec), first1, last1, first2, last2, pstl::internal::pstl_less()); +} + +} // namespace std + +#define __PSTL_glue_algorithm_impl_H_ +#endif /* __PSTL_glue_algorithm_impl_H_ */ diff --git a/include/pstl/internal/glue_execution_defs.h b/include/pstl/internal/glue_execution_defs.h index 519decc708..87f8cf179d 100644 --- a/include/pstl/internal/glue_execution_defs.h +++ b/include/pstl/internal/glue_execution_defs.h @@ -25,6 +25,8 @@ #include +#include "execution_defs.h" + namespace std { // Type trait using pstl::execution::is_execution_policy; diff --git a/test/test_iterators.cpp b/test/test_iterators.cpp index d118b9f3da..b605ab6d0e 100644 --- a/test/test_iterators.cpp +++ b/test/test_iterators.cpp @@ -21,6 +21,7 @@ #include #include +#include "pstl/execution" #include "pstl/algorithm" #include "pstl/iterators.h" #include "test/utils.h" From 6621df6f05ba4aa9e6b777e21f7d3dd836eef54f Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Fri, 6 Apr 2018 17:36:54 -0500 Subject: [PATCH 3/6] Refacor header This change splits the contents of to two internal "glue" headers for integration with libstdc++ as follows - internal/glue_algorithm_defs.h - Includes only function prototypes, and is included by internal/glue_algorithm_impl.h - Has all implementation previously in this header is only included in . This will prevent compile-time regressions for consumers of (in libstdc++) which do not currently use the parallel versions of the algorithms, which are always dependent on execution policy, and thus always dependent on . --- include/pstl/internal/glue_algorithm_defs.h | 4 ++-- include/pstl/internal/glue_algorithm_impl.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/pstl/internal/glue_algorithm_defs.h b/include/pstl/internal/glue_algorithm_defs.h index 97a9fd2842..acff25751a 100644 --- a/include/pstl/internal/glue_algorithm_defs.h +++ b/include/pstl/internal/glue_algorithm_defs.h @@ -354,9 +354,9 @@ partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIte // [partial.sort.copy] -template +template pstl::internal::enable_if_execution_policy -partial_sort_copy(ExecutionPolicy&& exec, _InputIterator first, _InputIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, +partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, Compare comp); template diff --git a/include/pstl/internal/glue_algorithm_impl.h b/include/pstl/internal/glue_algorithm_impl.h index 7e4a685e56..f3b90d5c52 100644 --- a/include/pstl/internal/glue_algorithm_impl.h +++ b/include/pstl/internal/glue_algorithm_impl.h @@ -640,13 +640,13 @@ partial_sort(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIte // [partial.sort.copy] -template +template pstl::internal::enable_if_execution_policy -partial_sort_copy(ExecutionPolicy&& exec, _InputIterator first, _InputIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, Compare comp) { +partial_sort_copy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, RandomAccessIterator d_first, RandomAccessIterator d_last, Compare comp) { using namespace pstl::internal; return pattern_partial_sort_copy(first, last, d_first, d_last, comp, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); } template From 6a1401c2ccee36126051857b45210f73c681e7ff Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Mon, 9 Apr 2018 14:44:37 -0500 Subject: [PATCH 4/6] Move and details to internal headers This is in preparation for integration with libstdc++ These changes are analogous to the changes in a previous commit for --- include/pstl/execution | 2 + include/pstl/internal/glue_algorithm_defs.h | 2 - include/pstl/internal/glue_algorithm_impl.h | 4 +- include/pstl/internal/glue_memory_defs.h | 89 ++++++++ include/pstl/internal/glue_numeric_defs.h | 107 ++++++++++ include/pstl/internal/glue_numeric_impl.h | 171 ++++++++++++++++ include/pstl/memory | 214 +------------------- include/pstl/numeric | 150 +------------- 8 files changed, 372 insertions(+), 367 deletions(-) create mode 100644 include/pstl/internal/glue_memory_defs.h create mode 100644 include/pstl/internal/glue_numeric_defs.h create mode 100644 include/pstl/internal/glue_numeric_impl.h diff --git a/include/pstl/execution b/include/pstl/execution index 6a08da1649..e24aa77096 100644 --- a/include/pstl/execution +++ b/include/pstl/execution @@ -26,6 +26,8 @@ // Algorithm implementation #include "internal/glue_algorithm_impl.h" +#include "internal/glue_numeric_impl.h" +#include "internal/glue_memory_impl.h" #if __PSTL_CPP17_EXECUTION_POLICIES_PRESENT __PSTL_PRAGMA_MESSAGE_POLICIES("The execution policies are defined in the namespace pstl::execution") diff --git a/include/pstl/internal/glue_algorithm_defs.h b/include/pstl/internal/glue_algorithm_defs.h index acff25751a..48504bce4d 100644 --- a/include/pstl/internal/glue_algorithm_defs.h +++ b/include/pstl/internal/glue_algorithm_defs.h @@ -1,5 +1,3 @@ -// glue_algorithm_defs.h -*- C++ -*- - /* Copyright (c) 2017-2018 Intel Corporation diff --git a/include/pstl/internal/glue_algorithm_impl.h b/include/pstl/internal/glue_algorithm_impl.h index f3b90d5c52..82fed18b78 100644 --- a/include/pstl/internal/glue_algorithm_impl.h +++ b/include/pstl/internal/glue_algorithm_impl.h @@ -1,5 +1,3 @@ -// glue_algorithm_impl.h -*- C++ -*- - /* Copyright (c) 2017-2018 Intel Corporation @@ -21,6 +19,7 @@ */ #ifndef __PSTL_glue_algorithm_impl_H_ +#define __PSTL_glue_algorithm_impl_H_ #include @@ -923,5 +922,4 @@ lexicographical_compare(ExecutionPolicy&& exec, ForwardIterator1 first1, Forward } // namespace std -#define __PSTL_glue_algorithm_impl_H_ #endif /* __PSTL_glue_algorithm_impl_H_ */ diff --git a/include/pstl/internal/glue_memory_defs.h b/include/pstl/internal/glue_memory_defs.h new file mode 100644 index 0000000000..6bff12aede --- /dev/null +++ b/include/pstl/internal/glue_memory_defs.h @@ -0,0 +1,89 @@ +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_glue_memory_defs_H +#define __PSTL_glue_memory_defs_H + +#include "execution_defs.h" + +namespace std { + +// [uninitialized.copy] + +template +pstl::internal::enable_if_execution_policy +uninitialized_copy(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result); + +template +pstl::internal::enable_if_execution_policy +uninitialized_copy_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result); + +// [uninitialized.move] + +template +pstl::internal::enable_if_execution_policy +uninitialized_move(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result); + +template +pstl::internal::enable_if_execution_policy +uninitialized_move_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result); + +// [uninitialized.fill] + +template +pstl::internal::enable_if_execution_policy +uninitialized_fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value); + +template +pstl::internal::enable_if_execution_policy +uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value); + +// [specialized.destroy] + +template +pstl::internal::enable_if_execution_policy +destroy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n); + +// [uninitialized.construct.default] + +template +pstl::internal::enable_if_execution_policy +uninitialized_default_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n); + +// [uninitialized.construct.value] + +template +pstl::internal::enable_if_execution_policy +uninitialized_value_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n); + +} // namespace std +#endif /* __PSTL_glue_memory_defs_H */ diff --git a/include/pstl/internal/glue_numeric_defs.h b/include/pstl/internal/glue_numeric_defs.h new file mode 100644 index 0000000000..ccf449456a --- /dev/null +++ b/include/pstl/internal/glue_numeric_defs.h @@ -0,0 +1,107 @@ +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or defsied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ +#ifndef __PSTL_glue_numeric_defs_H_ +#define __PSTL_glue_numeric_defs_H_ + +#include "execution_defs.h" + +namespace std { +// [reduce] + +template +pstl::internal::enable_if_execution_policy +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op); + +template +pstl::internal::enable_if_execution_policy +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init); + +template +pstl::internal::enable_if_execution_policy::value_type> +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last); + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init); + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init, BinaryOperation1 binary_op1, + BinaryOperation2 binary_op2); + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op); + +// [exclusive.scan] + +template +pstl::internal::enable_if_execution_policy +exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init); + +template +ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, + BinaryOperation binary_op); + +// [inclusive.scan] + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result); + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op); + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init); + +// [transform.exclusive.scan] + +template +pstl::internal::enable_if_execution_policy +transform_exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, + BinaryOperation binary_op, UnaryOperation unary_op); + +// [transform.inclusive.scan] + +template +pstl::internal::enable_if_execution_policy +transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, + UnaryOperation unary_op, T init); + +template +pstl::internal::enable_if_execution_policy +transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, + UnaryOperation unary_op); + +// [adjacent.difference] + +template +pstl::internal::enable_if_execution_policy +adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first, BinaryOperation op); + +template +pstl::internal::enable_if_execution_policy +adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first); + +} // namespace std +#endif /* __PSTL_glue_numeric_defs_H_ */ diff --git a/include/pstl/internal/glue_numeric_impl.h b/include/pstl/internal/glue_numeric_impl.h new file mode 100644 index 0000000000..50327944e0 --- /dev/null +++ b/include/pstl/internal/glue_numeric_impl.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ +#ifndef __PSTL_glue_numeric_impl_H +#define __PSTL_glue_numeric_impl_H + +#include + +#include "utils.h" +#include "numeric_impl.h" + +namespace std { + +// [reduce] + +template +pstl::internal::enable_if_execution_policy +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op) { + return transform_reduce(exec, first, last, init, binary_op, pstl::internal::no_op()); +} + +template +pstl::internal::enable_if_execution_policy +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init) { + return transform_reduce(exec, first, last, init, std::plus(), pstl::internal::no_op()); +} + +template +pstl::internal::enable_if_execution_policy::value_type> +reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type T; + return transform_reduce(exec, first, last, T{}, std::plus(), pstl::internal::no_op()); +} + +// [transform.reduce] + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init) { + typedef typename iterator_traits::value_type input_type; + using namespace pstl::internal; + return pattern_transform_reduce(first1, last1, first2, init, std::plus(), std::multiplies(), + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2) { + using namespace pstl::internal; + return pattern_transform_reduce(first1, last1, first2, init, binary_op1, binary_op2, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +transform_reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op) { + using namespace pstl::internal; + return pattern_transform_reduce(first, last, init, binary_op, unary_op, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [exclusive.scan] + +template +pstl::internal::enable_if_execution_policy +exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init) { + return transform_exclusive_scan(exec, first, last, result, init, std::plus(), pstl::internal::no_op()); +} + +template +ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op) { + return transform_exclusive_scan(exec, first, last, result, init, binary_op, pstl::internal::no_op()); +} + +// [inclusive.scan] + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { + typedef typename iterator_traits::value_type input_type; + return transform_inclusive_scan(exec, first, last, result, std::plus(), pstl::internal::no_op()); +} + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op) { + return transform_inclusive_scan(exec, first, last, result, binary_op, pstl::internal::no_op()); +} + +template +pstl::internal::enable_if_execution_policy +inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init) { + return transform_inclusive_scan(exec, first, last, result, binary_op, pstl::internal::no_op(), init); +} + +// [transform.exclusive.scan] + +template +pstl::internal::enable_if_execution_policy +transform_exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op, UnaryOperation unary_op) { + using namespace pstl::internal; + return pattern_transform_scan( + first, last, result, unary_op, init, binary_op, + /*inclusive=*/std::false_type(), + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +// [transform.inclusive.scan] + +template +pstl::internal::enable_if_execution_policy +transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init) { + using namespace pstl::internal; + return pattern_transform_scan( + first, last, result, unary_op, init, binary_op, + /*inclusive=*/std::true_type(), + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op) { + if( first!=last ) { + auto tmp = unary_op(*first); + *result = tmp; + return transform_inclusive_scan(exec, ++first, last, ++result, binary_op, unary_op, tmp); + } else { + return result; + } +} + +// [adjacent.difference] + +template +pstl::internal::enable_if_execution_policy +adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first, BinaryOperation op) { + using namespace pstl::internal; + return pattern_adjacent_difference(first, last, d_first, op, + is_vectorization_preferred(exec), + is_parallelization_preferred(exec)); +} + +template +pstl::internal::enable_if_execution_policy +adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first) { + typedef typename iterator_traits::value_type value_type; + return adjacent_difference(exec, first, last, d_first, std::minus()); +} +} // namespace std +#endif /* __PSTL_glue_numeric_impl_H_ */ \ No newline at end of file diff --git a/include/pstl/memory b/include/pstl/memory index 2b272a87a6..0ea213bcdf 100644 --- a/include/pstl/memory +++ b/include/pstl/memory @@ -22,218 +22,6 @@ #define __PSTL_memory_H #include "internal/pstl_config.h" -#include "internal/utils.h" -#include "internal/algorithm_impl.h" +#include "internal/glue_memory_defs.h" -namespace std { - -template -pstl::internal::enable_if_execution_policy -uninitialized_copy(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result) { - typedef typename iterator_traits::value_type value_type1; - typedef typename iterator_traits::value_type value_type2; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), - [&]() { return pattern_walk2_brick(first, last, result, [is_vector](InputIterator begin, InputIterator end, ForwardIterator res) - { return brick_copy(begin, end, res, is_vector); }, is_parallel); }, - [&]() { return pattern_it_walk2(first, last, result, [](InputIterator it1, ForwardIterator it2) - { ::new (reduce_to_ptr(it2)) value_type2(*it1); }, is_vector, is_parallel); } - ); -} - -template -pstl::internal::enable_if_execution_policy -uninitialized_copy_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result) { - typedef typename iterator_traits::value_type value_type1; - typedef typename iterator_traits::value_type value_type2; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), - [&]() { return pattern_walk2_brick_n(first, n, result, [is_vector](InputIterator begin, Size sz, ForwardIterator res) - { return brick_copy_n(begin, sz, res, is_vector); }, is_parallel); }, - [&]() { return pattern_it_walk2_n(first, n, result, [](InputIterator it1, ForwardIterator it2) - { ::new (reduce_to_ptr(it2)) value_type2(*it1); }, is_vector, is_parallel); } - ); -} - -// [uninitialized.move] - -template -pstl::internal::enable_if_execution_policy -uninitialized_move(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result) { - typedef typename iterator_traits::value_type value_type1; - typedef typename iterator_traits::value_type value_type2; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), - [&]() { return pattern_walk2_brick(first, last, result, [is_vector](InputIterator begin, InputIterator end, ForwardIterator res) - { return brick_copy(begin, end, res, is_vector);}, is_parallel); }, - [&]() { return pattern_it_walk2(first, last, result, [](InputIterator it1, ForwardIterator it2) - { ::new (reduce_to_ptr(it2)) value_type2(std::move(*it1)); }, is_vector, is_parallel); } - ); -} - -template -pstl::internal::enable_if_execution_policy -uninitialized_move_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result) { - typedef typename iterator_traits::value_type value_type1; - typedef typename iterator_traits::value_type value_type2; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), - [&]() { return pattern_walk2_brick_n(first, n, result, [is_vector](InputIterator begin, Size sz, ForwardIterator res) - { return brick_copy_n(begin, sz, res, is_vector);}, is_parallel); }, - [&]() { return pattern_it_walk2_n(first, n, result, [](InputIterator it1, ForwardIterator it2) - { ::new (reduce_to_ptr(it2)) value_type2(std::move(*it1)); }, is_vector, is_parallel); } - ); -} - -// [uninitialized.fill] - -template -pstl::internal::enable_if_execution_policy -uninitialized_fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - invoke_if_else(std::is_arithmetic(), - [&]() { pattern_walk_brick(first, last, [&value, &is_vector](ForwardIterator begin, ForwardIterator end) - { brick_fill(begin, end, value_type(value), is_vector);}, is_parallel); }, - [&]() { pattern_it_walk1(first, last, [&value](ForwardIterator it) - { ::new (reduce_to_ptr(it)) value_type(value); }, is_vector, is_parallel); } - ); -} - -template -pstl::internal::enable_if_execution_policy -uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::is_arithmetic(), - [&]() { return pattern_walk_brick_n(first, n, [&value, &is_vector](ForwardIterator begin, Size count) - { return brick_fill_n(begin, count, value_type(value), is_vector);}, is_parallel); }, - [&]() { return pattern_it_walk1_n(first, n, [&value](ForwardIterator it) - { ::new (reduce_to_ptr(it)) value_type(value); }, is_vector, is_parallel); } - ); -} - -// [specialized.destroy] - -template -pstl::internal::enable_if_execution_policy -destroy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - invoke_if_not(std::is_trivially_destructible(), - [&]() { pattern_it_walk1(first, last, [](ForwardIterator it){ (*it).~value_type(); }, is_vector, is_parallel); } - ); -} - -template -pstl::internal::enable_if_execution_policy -destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::is_trivially_destructible(), - [&]() { return std::next(first, n);}, - [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it){ (*it).~value_type(); }, is_vector, is_parallel); } - ); -} - -// [uninitialized.construct.default] - -template -pstl::internal::enable_if_execution_policy -uninitialized_default_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - invoke_if_not(std::is_trivial(), - [&]() { pattern_it_walk1(first, last, [](ForwardIterator it) { ::new (reduce_to_ptr(it)) value_type; }, is_vector, is_parallel); }); -} - -template -pstl::internal::enable_if_execution_policy -uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::is_trivial(), - [&]() { return std::next(first, n);}, - [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it) - { ::new (reduce_to_ptr(it)) value_type; }, is_vector, is_parallel); } - ); -} - -// [uninitialized.construct.value] - -template -pstl::internal::enable_if_execution_policy -uninitialized_value_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - invoke_if_else(std::is_trivial(), - [&]() { pattern_walk_brick(first, last, [is_vector](ForwardIterator begin, ForwardIterator end) - { brick_fill(begin, end, value_type(), is_vector);}, is_parallel); }, - [&]() { pattern_it_walk1(first, last, [](ForwardIterator it) - { ::new (reduce_to_ptr(it)) value_type(); }, is_vector, is_parallel); } - ); -} - -template -pstl::internal::enable_if_execution_policy -uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { - typedef typename iterator_traits::value_type value_type; - using namespace pstl::internal; - - const auto is_parallel = is_parallelization_preferred(exec); - const auto is_vector = is_vectorization_preferred(exec); - - return invoke_if_else(std::is_trivial(), - [&]() { return pattern_walk_brick_n(first, n, [is_vector](ForwardIterator begin, Size count) - { return brick_fill_n(begin, count, value_type(), is_vector);}, is_parallel); }, - [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it) - { ::new (reduce_to_ptr(it)) value_type(); }, is_vector, is_parallel); } - ); -} - -} // namespace std #endif /*__PSTL_memory_H */ diff --git a/include/pstl/numeric b/include/pstl/numeric index b0f822a095..91b46842c0 100644 --- a/include/pstl/numeric +++ b/include/pstl/numeric @@ -21,155 +21,7 @@ #ifndef __PSTL_numeric #define __PSTL_numeric -#include - #include "internal/pstl_config.h" -#include "internal/utils.h" -#include "internal/numeric_impl.h" - -namespace std { - -// [reduce] - -template -pstl::internal::enable_if_execution_policy -reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op) { - return transform_reduce(exec, first, last, init, binary_op, pstl::internal::no_op()); -} - -template -pstl::internal::enable_if_execution_policy -reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init) { - return transform_reduce(exec, first, last, init, std::plus(), pstl::internal::no_op()); -} - -template -pstl::internal::enable_if_execution_policy::value_type> -reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { - typedef typename iterator_traits::value_type T; - return transform_reduce(exec, first, last, T{}, std::plus(), pstl::internal::no_op()); -} - -// [transform.reduce] - -template -pstl::internal::enable_if_execution_policy -transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init) { - typedef typename iterator_traits::value_type input_type; - using namespace pstl::internal; - return pattern_transform_reduce(first1, last1, first2, init, std::plus(), std::multiplies(), - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -transform_reduce(ExecutionPolicy&& exec, ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2) { - using namespace pstl::internal; - return pattern_transform_reduce(first1, last1, first2, init, binary_op1, binary_op2, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -transform_reduce(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op) { - using namespace pstl::internal; - return pattern_transform_reduce(first, last, init, binary_op, unary_op, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [exclusive.scan] - -template -pstl::internal::enable_if_execution_policy -exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init) { - return transform_exclusive_scan(exec, first, last, result, init, std::plus(), pstl::internal::no_op()); -} - -template -ForwardIterator2 exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op) { - return transform_exclusive_scan(exec, first, last, result, init, binary_op, pstl::internal::no_op()); -} - -// [inclusive.scan] - -template -pstl::internal::enable_if_execution_policy -inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result) { - typedef typename iterator_traits::value_type input_type; - return transform_inclusive_scan(exec, first, last, result, std::plus(), pstl::internal::no_op()); -} - -template -pstl::internal::enable_if_execution_policy -inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op) { - return transform_inclusive_scan(exec, first, last, result, binary_op, pstl::internal::no_op()); -} - -template -pstl::internal::enable_if_execution_policy -inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, T init) { - return transform_inclusive_scan(exec, first, last, result, binary_op, pstl::internal::no_op(), init); -} - -// [transform.exclusive.scan] - -template -pstl::internal::enable_if_execution_policy -transform_exclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, T init, BinaryOperation binary_op, UnaryOperation unary_op) { - using namespace pstl::internal; - return pattern_transform_scan( - first, last, result, unary_op, init, binary_op, - /*inclusive=*/std::false_type(), - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -// [transform.inclusive.scan] - -template -pstl::internal::enable_if_execution_policy -transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op, T init) { - using namespace pstl::internal; - return pattern_transform_scan( - first, last, result, unary_op, init, binary_op, - /*inclusive=*/std::true_type(), - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -transform_inclusive_scan(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result, BinaryOperation binary_op, UnaryOperation unary_op) { - if( first!=last ) { - auto tmp = unary_op(*first); - *result = tmp; - return transform_inclusive_scan(exec, ++first, last, ++result, binary_op, unary_op, tmp); - } else { - return result; - } -} - -// [adjacent.difference] - -template -pstl::internal::enable_if_execution_policy -adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first, BinaryOperation op) { - using namespace pstl::internal; - return pattern_adjacent_difference(first, last, d_first, op, - is_vectorization_preferred(exec), - is_parallelization_preferred(exec)); -} - -template -pstl::internal::enable_if_execution_policy -adjacent_difference(ExecutionPolicy&& exec, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 d_first) { - typedef typename iterator_traits::value_type value_type; - return adjacent_difference(exec, first, last, d_first, std::minus()); -} - -} +#include "internal/glue_numeric_defs.h" #endif /* __PSTL_numeric */ From 59c375be17b28b75c0155925cdfd76ecc8aa37a6 Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Tue, 10 Apr 2018 10:54:37 -0500 Subject: [PATCH 5/6] Pick up file missed on previous checkin internal/glue_memory_impl.h was not in previous commit --- include/pstl/internal/glue_memory_impl.h | 238 +++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 include/pstl/internal/glue_memory_impl.h diff --git a/include/pstl/internal/glue_memory_impl.h b/include/pstl/internal/glue_memory_impl.h new file mode 100644 index 0000000000..f87c1a2f53 --- /dev/null +++ b/include/pstl/internal/glue_memory_impl.h @@ -0,0 +1,238 @@ +/* + Copyright (c) 2017-2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + +*/ + +#ifndef __PSTL_glue_memory_impl_H +#define __PSTL_glue_memory_impl_H + +#include "utils.h" +#include "algorithm_impl.h" + +namespace std { + +template +pstl::internal::enable_if_execution_policy +uninitialized_copy(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result) { + typedef typename iterator_traits::value_type value_type1; + typedef typename iterator_traits::value_type value_type2; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), + [&]() { return pattern_walk2_brick(first, last, result, [is_vector](InputIterator begin, InputIterator end, ForwardIterator res) + { return brick_copy(begin, end, res, is_vector); }, is_parallel); }, + [&]() { return pattern_it_walk2(first, last, result, [](InputIterator it1, ForwardIterator it2) + { ::new (reduce_to_ptr(it2)) value_type2(*it1); }, is_vector, is_parallel); } + ); +} + +template +pstl::internal::enable_if_execution_policy +uninitialized_copy_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result) { + typedef typename iterator_traits::value_type value_type1; + typedef typename iterator_traits::value_type value_type2; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), + [&]() { return pattern_walk2_brick_n(first, n, result, [is_vector](InputIterator begin, Size sz, ForwardIterator res) + { return brick_copy_n(begin, sz, res, is_vector); }, is_parallel); }, + [&]() { return pattern_it_walk2_n(first, n, result, [](InputIterator it1, ForwardIterator it2) + { ::new (reduce_to_ptr(it2)) value_type2(*it1); }, is_vector, is_parallel); } + ); +} + +// [uninitialized.move] + +template +pstl::internal::enable_if_execution_policy +uninitialized_move(ExecutionPolicy&& exec, InputIterator first, InputIterator last, ForwardIterator result) { + typedef typename iterator_traits::value_type value_type1; + typedef typename iterator_traits::value_type value_type2; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), + [&]() { return pattern_walk2_brick(first, last, result, [is_vector](InputIterator begin, InputIterator end, ForwardIterator res) + { return brick_copy(begin, end, res, is_vector);}, is_parallel); }, + [&]() { return pattern_it_walk2(first, last, result, [](InputIterator it1, ForwardIterator it2) + { ::new (reduce_to_ptr(it2)) value_type2(std::move(*it1)); }, is_vector, is_parallel); } + ); +} + +template +pstl::internal::enable_if_execution_policy +uninitialized_move_n(ExecutionPolicy&& exec, InputIterator first, Size n, ForwardIterator result) { + typedef typename iterator_traits::value_type value_type1; + typedef typename iterator_traits::value_type value_type2; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::integral_constant::value && std::is_trivial::value>(), + [&]() { return pattern_walk2_brick_n(first, n, result, [is_vector](InputIterator begin, Size sz, ForwardIterator res) + { return brick_copy_n(begin, sz, res, is_vector);}, is_parallel); }, + [&]() { return pattern_it_walk2_n(first, n, result, [](InputIterator it1, ForwardIterator it2) + { ::new (reduce_to_ptr(it2)) value_type2(std::move(*it1)); }, is_vector, is_parallel); } + ); +} + +// [uninitialized.fill] + +template +pstl::internal::enable_if_execution_policy +uninitialized_fill(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, const T& value) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + invoke_if_else(std::is_arithmetic(), + [&]() { pattern_walk_brick(first, last, [&value, &is_vector](ForwardIterator begin, ForwardIterator end) + { brick_fill(begin, end, value_type(value), is_vector);}, is_parallel); }, + [&]() { pattern_it_walk1(first, last, [&value](ForwardIterator it) + { ::new (reduce_to_ptr(it)) value_type(value); }, is_vector, is_parallel); } + ); +} + +template +pstl::internal::enable_if_execution_policy +uninitialized_fill_n(ExecutionPolicy&& exec, ForwardIterator first, Size n, const T& value) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::is_arithmetic(), + [&]() { return pattern_walk_brick_n(first, n, [&value, &is_vector](ForwardIterator begin, Size count) + { return brick_fill_n(begin, count, value_type(value), is_vector);}, is_parallel); }, + [&]() { return pattern_it_walk1_n(first, n, [&value](ForwardIterator it) + { ::new (reduce_to_ptr(it)) value_type(value); }, is_vector, is_parallel); } + ); +} + +// [specialized.destroy] + +template +pstl::internal::enable_if_execution_policy +destroy(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + invoke_if_not(std::is_trivially_destructible(), + [&]() { pattern_it_walk1(first, last, [](ForwardIterator it){ (*it).~value_type(); }, is_vector, is_parallel); } + ); +} + +template +pstl::internal::enable_if_execution_policy +destroy_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::is_trivially_destructible(), + [&]() { return std::next(first, n);}, + [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it){ (*it).~value_type(); }, is_vector, is_parallel); } + ); +} + +// [uninitialized.construct.default] + +template +pstl::internal::enable_if_execution_policy +uninitialized_default_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + invoke_if_not(std::is_trivial(), + [&]() { pattern_it_walk1(first, last, [](ForwardIterator it) { ::new (reduce_to_ptr(it)) value_type; }, is_vector, is_parallel); }); +} + +template +pstl::internal::enable_if_execution_policy +uninitialized_default_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::is_trivial(), + [&]() { return std::next(first, n);}, + [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it) + { ::new (reduce_to_ptr(it)) value_type; }, is_vector, is_parallel); } + ); +} + +// [uninitialized.construct.value] + +template +pstl::internal::enable_if_execution_policy +uninitialized_value_construct(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + invoke_if_else(std::is_trivial(), + [&]() { pattern_walk_brick(first, last, [is_vector](ForwardIterator begin, ForwardIterator end) + { brick_fill(begin, end, value_type(), is_vector);}, is_parallel); }, + [&]() { pattern_it_walk1(first, last, [](ForwardIterator it) + { ::new (reduce_to_ptr(it)) value_type(); }, is_vector, is_parallel); } + ); +} + +template +pstl::internal::enable_if_execution_policy +uninitialized_value_construct_n(ExecutionPolicy&& exec, ForwardIterator first, Size n) { + typedef typename iterator_traits::value_type value_type; + using namespace pstl::internal; + + const auto is_parallel = is_parallelization_preferred(exec); + const auto is_vector = is_vectorization_preferred(exec); + + return invoke_if_else(std::is_trivial(), + [&]() { return pattern_walk_brick_n(first, n, [is_vector](ForwardIterator begin, Size count) + { return brick_fill_n(begin, count, value_type(), is_vector);}, is_parallel); }, + [&]() { return pattern_it_walk1_n(first, n, [](ForwardIterator it) + { ::new (reduce_to_ptr(it)) value_type(); }, is_vector, is_parallel); } + ); +} + +} // namespace std +#endif /* __PSTL_glue_memory_imple_H */ From 8e8016f635bd1f52c93ebde18897557a863ba47f Mon Sep 17 00:00:00 2001 From: Thomas Rodgers Date: Mon, 16 Apr 2018 14:50:22 -0500 Subject: [PATCH 6/6] Conditionally include implementations if has been included Also, conditionally pulls in only those implementation headers required if and are included before --- include/pstl/algorithm | 9 ++++++++- include/pstl/execution | 10 ++++++++++ include/pstl/memory | 8 +++++++- include/pstl/numeric | 10 +++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/pstl/algorithm b/include/pstl/algorithm index 8c03c51ed3..a0ca677be8 100644 --- a/include/pstl/algorithm +++ b/include/pstl/algorithm @@ -22,6 +22,13 @@ #define __PSTL_algorithm #include "internal/pstl_config.h" -#include "internal/glue_algorithm_defs.h" +#if __PSTL_EXECUTION_POLICIES_DEFINED +// If has already been included, pull in implementations +#include "internal/glue_algorithm_impl.h" +#else +// Otherwise just pull in forward declarations +#include "internal/glue_algorithm_defs.h" +#define __PSTL_ALGORITHM_FORWARD_DECLARED 1 +#endif #endif /* __PSTL_algorithm */ diff --git a/include/pstl/execution b/include/pstl/execution index e24aa77096..9c175aa9e9 100644 --- a/include/pstl/execution +++ b/include/pstl/execution @@ -24,10 +24,20 @@ #include "internal/pstl_config.h" #include "internal/execution_defs.h" +#define __PSTL_EXECUTION_POLICIES_DEFINED 1 + // Algorithm implementation +#if __PSTL_ALGORITHM_FORWARD_DECLARED #include "internal/glue_algorithm_impl.h" +#endif + +#if __PSTL_NUMERIC_FORWARD_DECLARED #include "internal/glue_numeric_impl.h" +#endif + +#if __PSTL_NUMERIC_FORWARD_DECLARED #include "internal/glue_memory_impl.h" +#endif #if __PSTL_CPP17_EXECUTION_POLICIES_PRESENT __PSTL_PRAGMA_MESSAGE_POLICIES("The execution policies are defined in the namespace pstl::execution") diff --git a/include/pstl/memory b/include/pstl/memory index 0ea213bcdf..c947d860a9 100644 --- a/include/pstl/memory +++ b/include/pstl/memory @@ -22,6 +22,12 @@ #define __PSTL_memory_H #include "internal/pstl_config.h" -#include "internal/glue_memory_defs.h" +#if __PSTL_EXECUTION_POLICIES_DEFINED +// If has already been included, pull in implementations +#include "internal/glue_memory_impl.h" +#else +// Otherwise just pull in forward declarations +#include "internal/glue_memory_defs.h" +#endif #endif /*__PSTL_memory_H */ diff --git a/include/pstl/numeric b/include/pstl/numeric index 91b46842c0..bb28ca14c0 100644 --- a/include/pstl/numeric +++ b/include/pstl/numeric @@ -22,6 +22,14 @@ #define __PSTL_numeric #include "internal/pstl_config.h" -#include "internal/glue_numeric_defs.h" + +#if __PSTL_EXECUTION_POLICIES_DEFINED +// If has already been included, pull in implementations +#include "internal/glue_numeric_impl.h" +#else +// Otherwise just pull in forward declarations +#include "internal/glue_numeric_defs.h" +#define __PSTL_NUMERIC_FORWARD_DECLARED 1 +#endif #endif /* __PSTL_numeric */