Library: extract summation of pipeline results
...first used as part of the test harness; seemingly this is a generic and generally useful shortcut, similar to algorithm::reduce (or some kind of fold-left operation)
This commit is contained in:
parent
b15281d44b
commit
b416a67bb9
3 changed files with 52 additions and 17 deletions
|
|
@ -389,12 +389,13 @@ namespace lib {
|
|||
* within the same processing step; and in addition, it allows the processing step to
|
||||
* remain agnostic with respect to the adaptation and concrete type of the functor/lambda.
|
||||
* @tparam FUN either the signature, or something _"function-like"_ passed as functor to be bound
|
||||
* @tparam SRC (optional) but need to specify the source iterator type to apply when passing
|
||||
* a generic lambda or template as FUN. Such a generic functor will be _instantiated_
|
||||
* passing the type `SRC&` as argument. This instantiation may fail (and abort compilation),
|
||||
* but when it succeeds, we can infer the result type `Res` from the generic lambda
|
||||
* @tparam SRC source type to feed to the function to be adapted.
|
||||
* @remark Especially need to specify the source iterator type to apply when passing a generic lambda
|
||||
* or template as FUN. Such a generic functor will be _instantiated_ passing the type `SRC&`
|
||||
* as argument. This instantiation may fail (and abort compilation), but when it succeeds,
|
||||
* the result type `Res` can be inferred from the generic lambda.
|
||||
*/
|
||||
template<class FUN, typename SRC =void>
|
||||
template<class FUN, typename SRC>
|
||||
struct _FunTraits
|
||||
{
|
||||
/** handle all regular "function-like" entities */
|
||||
|
|
@ -1588,7 +1589,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
/**
|
||||
* _terminal builder_ to invoke a functor for side effect on the complete pipeline.
|
||||
* _terminal builder_ to invoke a functor for side effect on the complete pipeline.
|
||||
* @note exhausts and discards the pipeline itself
|
||||
*/
|
||||
template<class FUN>
|
||||
|
|
@ -1601,6 +1602,29 @@ namespace lib {
|
|||
consumeFun (pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* _terminal builder_ to invoke sum up resulting number values from the pipeline.
|
||||
* @return accumulation of all results from the pipeline, combined by `std::plus`
|
||||
*/
|
||||
template<class FUN>
|
||||
auto
|
||||
resultSum (FUN&& accessor)
|
||||
{
|
||||
auto accessVal = iter_explorer::_FunTraits<FUN,SRC>::adaptFunctor (forward<FUN> (accessor));
|
||||
value_type sum{};
|
||||
SRC& pipeline = *this;
|
||||
for ( ; pipeline; ++pipeline)
|
||||
sum += accessVal (pipeline);
|
||||
return sum;
|
||||
}
|
||||
|
||||
auto
|
||||
resultSum()
|
||||
{
|
||||
return IterExplorer::resultSum ([](const reference val){ return val; });
|
||||
}
|
||||
|
||||
|
||||
/** _terminal builder_ to pour and materialise all results from this Pipeline.
|
||||
* @tparam CON a STL compliant container to store generated values (defaults to `vector`)
|
||||
* @return new instance of the target container, filled with all values
|
||||
|
|
|
|||
|
|
@ -44,9 +44,6 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
//#include "include/logging.h"
|
||||
//#include "lib/meta/function.hpp"
|
||||
//#include "lib/result.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
|
@ -54,12 +51,6 @@
|
|||
|
||||
namespace lib {
|
||||
|
||||
// using lib::Literal;
|
||||
// namespace error = lumiera::error;
|
||||
// using error::LERR_(STATE);
|
||||
// using error::LERR_(EXTERNAL);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A one time N-fold mutual synchronisation barrier.
|
||||
|
|
@ -76,12 +67,13 @@ namespace lib {
|
|||
std::atomic_int latch_;
|
||||
|
||||
public:
|
||||
/** @param nFold the number of participants to sync */
|
||||
/** @param nFold the number of participants to sync (min. 2)*/
|
||||
explicit
|
||||
SyncBarrier (uint nFold =2)
|
||||
: latch_{int(nFold)}
|
||||
{
|
||||
REQUIRE (nFold >= 2, "Pointless to sync less than two participants.");
|
||||
ENSURE (nFold < 100'000, "Danger territory.... sync 100k Threads??");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -93,7 +85,7 @@ namespace lib {
|
|||
while (0 < latch_.load (std::memory_order_relaxed));
|
||||
else
|
||||
latch_.store (0, std::memory_order_relaxed);
|
||||
}
|
||||
} // prevent spurious calls from wrapping
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ namespace test{
|
|||
verify_FilterChanges();
|
||||
verify_asIterSource();
|
||||
verify_IterSource();
|
||||
verify_resultSum();
|
||||
verify_effuse();
|
||||
|
||||
verify_depthFirstExploration();
|
||||
|
|
@ -1069,6 +1070,24 @@ namespace test{
|
|||
|
||||
|
||||
|
||||
/** @test verify _terminal operation_ to sum up all values from the pipeline.
|
||||
*/
|
||||
void
|
||||
verify_resultSum()
|
||||
{
|
||||
auto accumulated = explore(CountDown{6})
|
||||
.transform([](int i){ return i-1; })
|
||||
.resultSum();
|
||||
|
||||
using Res = decltype(accumulated);
|
||||
CHECK (lib::test::showType<Res>() == "int"_expect);
|
||||
|
||||
auto expectedSum = [](auto N){ return N*(N+1) / 2; };
|
||||
CHECK (accumulated == expectedSum(5));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test verify _terminal operation_ to append all results into a container.
|
||||
*/
|
||||
void
|
||||
|
|
|
|||
Loading…
Reference in a new issue