From 1d30d47b9a42088d9b382a8ba421a855bbdaa9b2 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 29 Sep 2023 18:45:47 +0200 Subject: [PATCH] Library: add a simple usage for clarity --- src/lib/iter-explorer.hpp | 24 +++++++++++++++++ src/lib/scoped-collection.hpp | 6 +++++ tests/library/thread-wrapper-test.cpp | 39 ++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/lib/iter-explorer.hpp b/src/lib/iter-explorer.hpp index c60867712..9e2323574 100644 --- a/src/lib/iter-explorer.hpp +++ b/src/lib/iter-explorer.hpp @@ -1647,6 +1647,30 @@ namespace lib { return IterExplorer::reduce ([](const reference val){ return val; }); } + /** simplified _terminal builder_ to check if any result yields `true` (short-circuit) */ + bool + has_any() + { + static_assert (std::is_constructible()); + SRC& pipeline = *this; + for ( ; pipeline; ++pipeline) + if (*pipeline) + return true; + return false; + } + + /** simplified _terminal builder_ to check if all results yields `true` (short-circuit) */ + bool + and_all() + { + static_assert (std::is_constructible()); + SRC& pipeline = *this; + for ( ; pipeline; ++pipeline) + if (not *pipeline) + return false; + return true; + } + /** _terminal builder_ to pour and materialise all results from this Pipeline. * @tparam CON a STL compliant container to store generated values (defaults to `vector`) diff --git a/src/lib/scoped-collection.hpp b/src/lib/scoped-collection.hpp index 4be262287..a6eae5b58 100644 --- a/src/lib/scoped-collection.hpp +++ b/src/lib/scoped-collection.hpp @@ -350,6 +350,12 @@ namespace lib { bool empty () const { return 0 == level_; } + // use in standard range for loops... + friend iterator begin (ScopedCollection& sco) { return sco.begin(); } + friend const iterator begin (ScopedCollection const& sco){ return sco.begin(); } + friend iterator end (ScopedCollection& sco) { return sco.end(); } + friend const iterator end (ScopedCollection const& sco){ return sco.end(); } + private: /* ==== Storage: heap allocated array of element buffers ==== */ diff --git a/tests/library/thread-wrapper-test.cpp b/tests/library/thread-wrapper-test.cpp index 00d4ead0c..32fd48566 100644 --- a/tests/library/thread-wrapper-test.cpp +++ b/tests/library/thread-wrapper-test.cpp @@ -26,12 +26,18 @@ #include "lib/test/run.hpp" +#include "lib/test/test-helper.hpp"///////////TODO #include "lib/thread.hpp" +#include "lib/iter-explorer.hpp" #include "lib/scoped-collection.hpp" +#include #include using test::Test; +using lib::explore; +using std::atomic_uint; +using std::this_thread::yield; using std::this_thread::sleep_for; using std::chrono::microseconds; @@ -84,6 +90,36 @@ namespace lib { virtual void run (Arg) + { + demonstrateSimpleUsage(); + verifyConcurrentExecution(); + } + + /** + * @test demonstrate simple usage of the thread-wrapper + */ + void + demonstrateSimpleUsage() + { + lib::ScopedCollection threads{NUM_THREADS}; + + atomic_uint invocations{0}; + for (uint i=0; i ("counter" + ,[&]{ ++invocations; }); + + while (explore(threads).has_any()) + yield(); + + CHECK (invocations == NUM_THREADS); + } + + + /** + * @test verify the thread function is actually performed concurrently + */ + void + verifyConcurrentExecution() { lib::ScopedCollection threads{NUM_THREADS}; @@ -95,7 +131,8 @@ namespace lib { threads.emplace (&TestThread::doIt, uint{i}, uint{x}); } - usleep (200000); // pause 200ms for the threads to terminate..... + while (explore(threads).has_any()) + yield(); size_t checkSum = 0; for (auto& t : threads)