-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate seq_fwd from variant_policy, make both independent headers
- Loading branch information
Showing
4 changed files
with
230 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Copyright (C) 2023 Adam Lugowski. All rights reserved. | ||
// Use of this source code is governed by: | ||
// the BSD 2-clause license, the MIT license, or at your choosing the BSL-1.0 license found in the LICENSE.*.txt files. | ||
// SPDX-License-Identifier: BSD-2-Clause OR MIT OR BSL-1.0 | ||
|
||
#ifndef POOLSTL_VARIANT_POLICY_HPP | ||
#define POOLSTL_VARIANT_POLICY_HPP | ||
|
||
#include <algorithm> | ||
#include <numeric> | ||
|
||
/* INDEPENDENT FILE. DOES NOT REQUIRE REST OF POOLSTL. | ||
* | ||
* An execution policy that simply forwards to the basic non-policy (sequential) standard library functions. | ||
* | ||
* Allows writing code in the parallel style even if tooling does not support doing so. | ||
* | ||
* The sequential policy will be poolstl::seq_fwd. | ||
* You may override by defining POOLSTL_SEQ_FWD_POLICY to be the policy you'd prefer instead. | ||
*/ | ||
|
||
|
||
#ifndef POOLSTL_SEQ_FWD_POLICY | ||
namespace poolstl { | ||
namespace execution { | ||
struct seq_fwd_policy { | ||
}; | ||
|
||
constexpr seq_fwd_policy seq_fwd; | ||
} | ||
using execution::seq_fwd; | ||
} | ||
#define POOLSTL_SEQ_FWD_POLICY poolstl::execution::seq_fwd_policy | ||
#endif | ||
|
||
#if (__cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)) && \ | ||
(!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 9) | ||
#define POOLSTL_SEQ_FWD_HAVE_CXX17_LIB 1 | ||
#else | ||
#define POOLSTL_SEQ_FWD_HAVE_CXX17_LIB 0 | ||
#endif | ||
|
||
namespace poolstl { | ||
namespace internal { | ||
/** | ||
* To enable/disable seq_fwd overload resolution | ||
*/ | ||
template <class ExecPolicy, class Tp> | ||
using enable_if_seq_fwd = | ||
typename std::enable_if< | ||
std::is_same<POOLSTL_SEQ_FWD_POLICY, | ||
typename std::remove_cv<typename std::remove_reference<ExecPolicy>::type>::type>::value, | ||
Tp>::type; | ||
} | ||
} | ||
|
||
/* | ||
* Forward a specified policy to the native sequential (no policy) method. | ||
*/ | ||
|
||
#define POOLSTL_DEFINE_SEQ_FWD(NS, FNAME) \ | ||
template<class EP, typename...ARGS> \ | ||
auto FNAME(EP&&, ARGS&&...args) -> \ | ||
poolstl::internal::enable_if_seq_fwd<EP, decltype(NS::FNAME(std::forward<ARGS>(args)...))> { \ | ||
return NS::FNAME(std::forward<ARGS>(args)...); \ | ||
} | ||
|
||
#define POOLSTL_DEFINE_SEQ_FWD_VOID(NS, FNAME) \ | ||
template<class EP, typename...ARGS> \ | ||
poolstl::internal::enable_if_seq_fwd<EP, void> FNAME(EP&&, ARGS&&... args) { \ | ||
NS::FNAME(std::forward<ARGS>(args)...); \ | ||
} | ||
|
||
|
||
namespace std { | ||
// <algorithm> | ||
|
||
POOLSTL_DEFINE_SEQ_FWD(std, all_of) | ||
POOLSTL_DEFINE_SEQ_FWD(std, any_of) | ||
POOLSTL_DEFINE_SEQ_FWD(std, none_of) | ||
|
||
POOLSTL_DEFINE_SEQ_FWD(std, count) | ||
POOLSTL_DEFINE_SEQ_FWD(std, count_if) | ||
|
||
POOLSTL_DEFINE_SEQ_FWD(std, copy) | ||
POOLSTL_DEFINE_SEQ_FWD(std, copy_n) | ||
|
||
POOLSTL_DEFINE_SEQ_FWD_VOID(std, fill) | ||
POOLSTL_DEFINE_SEQ_FWD(std, fill_n) | ||
|
||
POOLSTL_DEFINE_SEQ_FWD(std, find) | ||
POOLSTL_DEFINE_SEQ_FWD(std, find_if) | ||
POOLSTL_DEFINE_SEQ_FWD(std, find_if_not) | ||
|
||
POOLSTL_DEFINE_SEQ_FWD_VOID(std, for_each) | ||
#if POOLSTL_SEQ_FWD_HAVE_CXX17_LIB | ||
POOLSTL_DEFINE_SEQ_FWD(std, for_each_n) | ||
#endif | ||
|
||
POOLSTL_DEFINE_SEQ_FWD(std, transform) | ||
|
||
// <numeric> | ||
|
||
#if POOLSTL_SEQ_FWD_HAVE_CXX17_LIB | ||
POOLSTL_DEFINE_SEQ_FWD(std, exclusive_scan) | ||
POOLSTL_DEFINE_SEQ_FWD(std, reduce) | ||
POOLSTL_DEFINE_SEQ_FWD(std, transform_reduce) | ||
#endif | ||
} | ||
|
||
#ifdef POOLSTL_VERSION_MAJOR | ||
namespace poolstl { | ||
// <poolstl/algorithm> | ||
|
||
POOLSTL_DEFINE_SEQ_FWD_VOID(poolstl, for_each_chunk) | ||
} | ||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (C) 2023 Adam Lugowski. All rights reserved. | ||
// Use of this source code is governed by: | ||
// the BSD 2-clause license, the MIT license, or at your choosing the BSL-1.0 license found in the LICENSE.*.txt files. | ||
// SPDX-License-Identifier: BSD-2-Clause OR MIT OR BSL-1.0 | ||
|
||
|
||
#include <algorithm> | ||
#include <atomic> | ||
|
||
#include <catch2/catch_test_macros.hpp> | ||
|
||
#if __has_include(<poolstl/seq_fwd.hpp>) | ||
// seq_fwd not included in the poolSTL amalgam, so skip these tests on CI steps that test the amalgam. | ||
|
||
#include <poolstl/seq_fwd.hpp> | ||
|
||
#include "utils.hpp" | ||
|
||
|
||
TEST_CASE("fwd_count", "[alg][algorithm][seq_fwd]") { | ||
for (auto vec_size : test_arr_sizes) { | ||
auto haystack = iota_vector(vec_size); | ||
|
||
{ | ||
int needle = 5; | ||
auto seq = std::count( haystack.cbegin(), haystack.cend(), needle); | ||
auto par = std::count(poolstl::seq_fwd, haystack.cbegin(), haystack.cend(), needle); | ||
REQUIRE(seq == par); | ||
} | ||
{ | ||
auto pred = [&](auto x) { return x % 2 == 0; }; | ||
auto seq = std::count_if( haystack.cbegin(), haystack.cend(), pred); | ||
auto par = std::count_if(poolstl::seq_fwd, haystack.cbegin(), haystack.cend(), pred); | ||
REQUIRE(seq == par); | ||
} | ||
} | ||
} | ||
|
||
TEST_CASE("fwd_for_each", "[alg][algorithm][seq_fwd]") { | ||
std::atomic<int> sum{0}; | ||
for (auto num_iters : test_arr_sizes) { | ||
auto v = iota_vector(num_iters); | ||
|
||
for (auto which_impl : {0, 1}) { | ||
sum = 0; | ||
auto f = [&](auto) { ++sum; }; | ||
switch (which_impl) { | ||
case 0: | ||
std::for_each(v.cbegin(), v.cend(), f); | ||
break; | ||
case 1: | ||
std::for_each(poolstl::seq_fwd, v.cbegin(), v.cend(), f); | ||
break; | ||
default: break; | ||
} | ||
REQUIRE(sum == num_iters); | ||
} | ||
} | ||
} | ||
|
||
std::mt19937 rng{1}; | ||
#endif |