From d0017a0175e544c2193a30c960f87f51216bc6a8 Mon Sep 17 00:00:00 2001 From: Sean Parent Date: Wed, 21 Feb 2024 15:16:51 -0800 Subject: [PATCH] Moved initial_draft.cpp into a unit test and got it building/running added dependency to stlab libraries. --- Dependencies.cmake | 4 + include/chains/tuple.hpp | 20 +- test/CMakeLists.txt | 85 ++++---- test/constexpr_tests.cpp | 12 -- initial_draft.cpp => test/initial_draft.cpp | 221 +------------------- test/tests.cpp | 14 -- test/tuple_tests.cpp | 2 + 7 files changed, 58 insertions(+), 300 deletions(-) delete mode 100644 test/constexpr_tests.cpp rename initial_draft.cpp => test/initial_draft.cpp (68%) delete mode 100644 test/tests.cpp diff --git a/Dependencies.cmake b/Dependencies.cmake index 082008e..7c6fdc8 100644 --- a/Dependencies.cmake +++ b/Dependencies.cmake @@ -8,6 +8,10 @@ function(chains_setup_dependencies) # For each dependency, see if it's # already been provided to us by a parent project +if(NOT TARGET stlab::libraries) + cpmaddpackage("gh:stlab/libraries@2.0.0a2") +endif() + if(NOT TARGET fmtlib::fmtlib) cpmaddpackage("gh:fmtlib/fmt#9.1.0") endif() diff --git a/include/chains/tuple.hpp b/include/chains/tuple.hpp index 916174d..2475a25 100644 --- a/include/chains/tuple.hpp +++ b/include/chains/tuple.hpp @@ -1,7 +1,10 @@ -#include -#include +#include // std::apply, std::forward_as_tuple, std::tuple +#include // std::is_same_v +#include // std::forward, std::move +#include // std::monostate #ifndef CHAIN_TUPLE_HPP +#define CHAIN_TUPLE_HPP namespace chain::inline v0 { @@ -35,19 +38,6 @@ auto operator|(tuple_pipeable&& p, F& f) { return tuple_pipeable{void_to_monostate(f)(std::move(p._value))}; } -/* REVISIT (sparent) : how to forward a value through `just`? */ - -template -struct just_ref { - T& _value; - just_ref(T& a) : _value{a} {} -}; - -template -auto operator|(just_ref&& p, F&& f) { - return tuple_pipeable{std::apply(std::forward(f), std::move(p._value))}; -} - } // namespace detail //-------------------------------------------------------------------------------------------------- diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bdf1f94..9394e30 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,12 +29,13 @@ add_test(NAME cli.has_help COMMAND intro --help) add_test(NAME cli.version_matches COMMAND intro --version) set_tests_properties(cli.version_matches PROPERTIES PASS_REGULAR_EXPRESSION "${PROJECT_VERSION}") -add_executable(tests tests.cpp tuple_tests.cpp) +add_executable(tests tuple_tests.cpp initial_draft.cpp) target_link_libraries( tests PRIVATE chains::chains_warnings chains::chains_options chains::sample_library + stlab::stlab Catch2::Catch2WithMain) if(WIN32 AND BUILD_SHARED_LIBS) @@ -61,47 +62,47 @@ catch_discover_tests( .xml) # Add a file containing a set of constexpr tests -add_executable(constexpr_tests constexpr_tests.cpp) -target_link_libraries( - constexpr_tests - PRIVATE chains::chains_warnings - chains::chains_options - chains::sample_library - Catch2::Catch2WithMain) - -catch_discover_tests( - constexpr_tests - TEST_PREFIX - "constexpr." - REPORTER - XML - OUTPUT_DIR - . - OUTPUT_PREFIX - "constexpr." - OUTPUT_SUFFIX - .xml) +# add_executable(constexpr_tests constexpr_tests.cpp) +# target_link_libraries( +# constexpr_tests +# PRIVATE chains::chains_warnings +# chains::chains_options +# chains::sample_library +# Catch2::Catch2WithMain) + +# catch_discover_tests( +# constexpr_tests +# TEST_PREFIX +# "constexpr." +# REPORTER +# XML +# OUTPUT_DIR +# . +# OUTPUT_PREFIX +# "constexpr." +# OUTPUT_SUFFIX +# .xml) # Disable the constexpr portion of the test, and build again this allows us to have an executable that we can debug when # things go wrong with the constexpr testing -add_executable(relaxed_constexpr_tests constexpr_tests.cpp) -target_link_libraries( - relaxed_constexpr_tests - PRIVATE chains::chains_warnings - chains::chains_options - chains::sample_library - Catch2::Catch2WithMain) -target_compile_definitions(relaxed_constexpr_tests PRIVATE -DCATCH_CONFIG_RUNTIME_STATIC_REQUIRE) - -catch_discover_tests( - relaxed_constexpr_tests - TEST_PREFIX - "relaxed_constexpr." - REPORTER - XML - OUTPUT_DIR - . - OUTPUT_PREFIX - "relaxed_constexpr." - OUTPUT_SUFFIX - .xml) +# add_executable(relaxed_constexpr_tests constexpr_tests.cpp) +# target_link_libraries( +# relaxed_constexpr_tests +# PRIVATE chains::chains_warnings +# chains::chains_options +# chains::sample_library +# Catch2::Catch2WithMain) +# target_compile_definitions(relaxed_constexpr_tests PRIVATE -DCATCH_CONFIG_RUNTIME_STATIC_REQUIRE) + +# catch_discover_tests( +# relaxed_constexpr_tests +# TEST_PREFIX +# "relaxed_constexpr." +# REPORTER +# XML +# OUTPUT_DIR +# . +# OUTPUT_PREFIX +# "relaxed_constexpr." +# OUTPUT_SUFFIX +# .xml) diff --git a/test/constexpr_tests.cpp b/test/constexpr_tests.cpp deleted file mode 100644 index 9fe9918..0000000 --- a/test/constexpr_tests.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include - -TEST_CASE("Factorials are computed with constexpr", "[factorial]") -{ - STATIC_REQUIRE(factorial_constexpr(0) == 1); - STATIC_REQUIRE(factorial_constexpr(1) == 1); - STATIC_REQUIRE(factorial_constexpr(2) == 2); - STATIC_REQUIRE(factorial_constexpr(3) == 6); - STATIC_REQUIRE(factorial_constexpr(10) == 3628800); -} diff --git a/initial_draft.cpp b/test/initial_draft.cpp similarity index 68% rename from initial_draft.cpp rename to test/initial_draft.cpp index 087e59d..9d940c3 100644 --- a/initial_draft.cpp +++ b/test/initial_draft.cpp @@ -1,3 +1,6 @@ + +#include + #include #include @@ -352,7 +355,7 @@ inline auto then(F&& future) { using namespace std; using namespace stlab; -int main() { +TEST_CASE("Initial draft", "[initial_draft]") { auto a0 = on(default_executor) | [] { cout << "Hello from thread: " << std::this_thread::get_id() << "\n"; return 42; @@ -397,219 +400,3 @@ int main() { pre_exit(); } - -#if 0 - -#include -#include - -#include -#include -#include - -namespace stlab {namespace detail { - -template -struct pipeable { - T _value; - pipeable(T&& a) : _value{std::move(a)} { } -}; - -template -auto operator|(pipeable&& p, F&& f) { - return pipeable{f(std::move(p._value))}; -} - -template -struct just { - T& _value; - just(T& a) : _value{a} { } -}; - -template -auto operator|(just&& p, F&& f) { - return pipeable{std::apply(std::forward(f), p._value)}; -} - -} - -/* - Operations on a chain: - chain(f) // a chain can be created from a function - chain(f, applyr) // optionally, an applyr can be provided - chain | f -> chain - compose(chain, chain) -> chain - // return applyr(op, args...) where op is a function that represents the composed functions in the chain. - operator()(args...) -> value -*/ - -template -class chain -{ - I _applyr; - std::tuple _functions; - -public: - // REVISIT: Should `forward_as_tuple(args...)` be `forward_as_tuple(std::forward(args)...)`? - static auto default_applyr = [](chain& c, auto&&... args) { - return std::apply([_args = std::forward_as_tuple(args...)](auto&&... functions) mutable { - return (detail::just{_args} | ... | functions); - }, c._functions)._value; - }; - - chain(I&& applyr, Fs&&... functions) : _applyr{std::forward(applyr)}, _functions{std::make_tuple(std::forward(functions)...)} {} - explicit chain(Fs&&... functions) : chain{default_applyr, std::forward(functions)...} {} - - template - chain(I&& applyr, chain&& c): _applyr{std::forward(applyr)}, _functions{std::move(c._functions)} {} - - template - auto operator()(Args&&... args) { - _applyr(*this, std::forward(args)...); - } - - chain(const chain&) = delete; - chain& operator=(const chain&) = delete; - - chain(chain&&) noexcept = default; - chain& operator=(chain&&) noexcept = default; -}; - -template -auto resume_on(chain&& c, E&& executor) { - return chain{[_executor = std::forward(executor), c = std::move(c)](auto& ch, auto&&... args) mutable { - return stlab::async(std::move(_executor), [_chain = chain{default_applyr, std::move(ch)}]() mutable { - return _chain(); - }); - }, std::identity{}}; -} - -#if 0 - -namespace detail { - -template -struct pipeable { - T _value; - pipeable(T&& a) : _value{std::move(a)} { } -}; - -template -auto operator|(pipeable&& p, F&& f) { - return pipeable{f(std::move(p._value))}; -} - -template -struct just { - T& _value; - - just(T& a) : _value{a} { } -}; - -template -auto operator|(just&& p, F&& f) { - return pipeable{std::apply(std::forward(f), p._value)}; -} - -} - - -template -struct chain { - static constexpr bool chainable{true}; - std::tuple _functions; - - template - using next_type = chain; - - template - chain(C&&, std::tuple&& t) : _functions{std::move(t)} { } - - chain(std::tuple&& t) : _functions{std::move(t)} { } - - // chain(Fs&&... args) : _functions{std::forward(args)...} { } - - template - auto operator()(Args&&... args) { - return std::apply([_args = std::forward_as_tuple(args...)](auto&&... functions) mutable { - return (detail::just{_args} | ... | functions); - }, _functions)._value; - } -}; - -// REVISIT : This is binding the executer and arguments to a chainable. I need to factor out -// the bind/wrap operation as a build block for composing algorithms. - -template -struct spawner : chain { - E _executor; - O _op; - - template - using next_type = spawner; - - template - spawner(S&& s, std::tuple&& t) : _executor{std::move(s._executor)}, _op{std::move(s._op)}, - chain{std::move(t)} { } - - spawner(E&& e, O&& op) : _executor{std::forward(e)}, _op{std::forward(op)}, chain<>{std::tuple{}} { } - - auto operator()() { - return stlab::async(std::move(_executor), [_chain = chain{std::move(this->_functions)}, _op = std::move(_op)]() mutable { - return _chain(_op()); - }); - } -}; - - -template -auto operator|(C&& c, F&& f) requires C::chainable { - auto functions{std::tuple_cat(std::move(c._functions), std::make_tuple(std::forward(f)))}; - using next_type = C::template next_type>; - return next_type{std::move(c), std::move(functions)}; -} - -/* - return a chainable (void)->future that will schedule the task and any chained operations on - the executer when apply. The `T` is the result type of the last chained operation. -*/ - -template -auto schedule_on(E executor, F&& f) { - return spawner, std::decay_t>{std::move(executor), std::forward(f)}; -} - -#endif - -} - -#include - -using namespace std; -using namespace stlab; - -int main() { -#if 0 - stlab::chain c{[](int x) -> float { return x; }, [](float a){ return a + 0.5; }}; - auto c2{std::move(c) | [](float a){ return std::to_string(a + 2.0); }}; - std::cout << c2(42) << "\n"; -#endif - - auto a0 = schedule_on(default_executor, []{ - cout << "Hello from thread: " << std::this_thread::get_id() << "\n"; - return 42; - }); - - auto a1 = std::move(a0) | [](int x){ - cout << "received: " << x << "\n"; - return "forwarding: " + std::to_string(x + 1); - }; - - cout << "Main thread: " << std::this_thread::get_id() << "\n"; - cout << "Ready to go async!\n"; - - std::cout << await(a1()) << "\n"; - - pre_exit(); -} -#endif diff --git a/test/tests.cpp b/test/tests.cpp deleted file mode 100644 index d897ea0..0000000 --- a/test/tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include - - -#include - - -TEST_CASE("Factorials are computed", "[factorial]") -{ - REQUIRE(factorial(0) == 1); - REQUIRE(factorial(1) == 1); - REQUIRE(factorial(2) == 2); - REQUIRE(factorial(3) == 6); - REQUIRE(factorial(10) == 3628800); -} diff --git a/test/tuple_tests.cpp b/test/tuple_tests.cpp index 4d8673b..1dfbb23 100644 --- a/test/tuple_tests.cpp +++ b/test/tuple_tests.cpp @@ -1,3 +1,5 @@ +#include + #include #include