From 651e28bac9b2b629f1d5de682898e48bd75a4c95 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 20 Nov 2023 21:05:18 +0100 Subject: [PATCH] Library: RandomDraw - introduce policy template to define this as a generic library component, any reference to the actual data source moust be extracted from the body of the implementation and supplied later at usage site. In the actual case at hand the source for randomness would be the node hash, and that is absolutely an internal implementation detail. --- src/lib/random-draw.hpp | 82 +++++++++++------------------- tests/library/random-draw-test.cpp | 76 ++++++++++++++++++++++++--- wiki/thinkPad.ichthyo.mm | 24 ++++++++- 3 files changed, 123 insertions(+), 59 deletions(-) diff --git a/src/lib/random-draw.hpp b/src/lib/random-draw.hpp index 4274194c2..513f49a81 100644 --- a/src/lib/random-draw.hpp +++ b/src/lib/random-draw.hpp @@ -97,36 +97,53 @@ namespace lib { }; + namespace random_draw { // Policy definitions + + /** + * Default policy for RandomDraw: generate limted-range random numbers. + * @tparam max result values will be `uint` in the range `[0 ... max]` + */ + template + struct LimitedRandomGenerate + : function(void)> + { + static double defaultSrc() { return rand()/double(RAND_MAX); } + }; + + }//(End)Policy definitions + + /** * A component and builder to draw limited parameter values * based on some source of randomness (or hash input). * Effectively this is a function which "draws" on invocation. + * @tparam POL configuration policy baseclass */ - template + template class RandomDraw - : public function(size_t)> + : public POL { - using Lim = Limited; - using Fun = function; + using Fun = typename _Fun::Functor; + using Tar = typename _Fun::Ret; - T maxResult_{Lim::maxVal()}; ///< maximum parameter val actually to produce < max + Tar maxResult_{Tar::maxVal()}; ///< maximum parameter val actually to produce < max double probability_{0}; ///< probability that value is in [1 .. m] /** @internal quantise into limited result value */ - Lim + Tar limited (double val) { if (probability_ == 0.0 or val == 0.0) - return Lim{0}; + return Tar{0}; double q = (1.0 - probability_); val -= q; // [0 .. [q .. 1[ val /= probability_; // [0 .. 1[ val *= maxResult_; // [0 .. m[ val += 1; // [1 .. m] val += CAP_EPSILON; // round down yet absorb dust - return Lim{val}; + return Tar{val}; } static size_t constexpr QUANTISER = 1 << 8; @@ -143,7 +160,7 @@ namespace lib { public: /** Drawing is _disabled_ by default, always yielding "zero" */ RandomDraw() - : Fun{[this](size_t hash){ return limited (asRand (hash)); }} + : Fun{adaptOut(POL::defaultSrc)} { } /** @@ -189,53 +206,19 @@ namespace lib { - /** - * @internal helper to expose the signature `size_t(size_t)` - * by wrapping a given lambda or functor. - */ - template - struct Adaptor - { - static_assert (not sizeof(SIG), "Unable to adapt given functor."); - }; - - template - struct Adaptor - { - template - static decltype(auto) - build (FUN&& fun) - { - return std::forward(fun); - } - }; - - template - struct Adaptor - { - template - static auto - build (FUN&& fun) - { - return [functor=std::forward(fun)] - (size_t) - { - return functor(); - }; - } - }; + private: template decltype(auto) adaptIn (FUN&& fun) { static_assert (lib::meta::_Fun(), "Need something function-like."); - static_assert (lib::meta::_Fun::ARITY <= 1, "Function with zero or one argument expected."); - using Sig = typename lib::meta::_Fun::Sig; + using Sig = typename lib::meta::_Fun::Sig; + using Adaptor = typename POL::template Adaptor; - return Adaptor::build (forward (fun)); + return Adaptor::build (forward (fun)); } template @@ -243,11 +226,10 @@ namespace lib { adaptOut (FUN&& fun) { static_assert (lib::meta::_Fun(), "Need something function-like."); - static_assert (lib::meta::_Fun::ARITY ==1, "Function with exactly one argument required."); using Res = typename lib::meta::_Fun::Ret; - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) return std::forward(fun); else if constexpr (std::is_same_v) @@ -279,8 +261,6 @@ namespace lib { NOTREACHED("Handle based on return type"); } - private: - }; diff --git a/tests/library/random-draw-test.cpp b/tests/library/random-draw-test.cpp index 9ad22ced0..1f90133f1 100644 --- a/tests/library/random-draw-test.cpp +++ b/tests/library/random-draw-test.cpp @@ -51,9 +51,52 @@ namespace test{ namespace { // const Literal THE_END = "all dead and hero got the girl"; + struct SymmetricFive + : function(size_t)> + { + static size_t defaultSrc (size_t hash) { return hash; } + + /** + * @internal helper to expose the signature `size_t(size_t)` + * by wrapping a given lambda or functor. + */ + template + struct Adaptor + { + static_assert (not sizeof(SIG), "Unable to adapt given functor."); + }; + + template + struct Adaptor + { + template + static decltype(auto) + build (FUN&& fun) + { + return std::forward(fun); + } + }; + + template + struct Adaptor + { + template + static auto + build (FUN&& fun) + { + return [functor=std::forward(fun)] + (size_t) + { + return functor(); + }; + } + }; + + }; } - using Draw = lib::RandomDraw; + + using Draw = RandomDraw; @@ -74,6 +117,7 @@ namespace test{ { simpleUse(); + verify_policy(); verify_numerics(); verify_buildProfile(); verify_dynamicChange(); @@ -88,12 +132,30 @@ namespace test{ simpleUse() { auto draw = Draw().probability(0.5); - CHECK (draw(0) == 0); - CHECK (draw(127) == 0); - CHECK (draw(128) == 1); - CHECK (draw(141) == 2); - CHECK (draw(255) ==10); - CHECK (draw(256) == 0); +SHOW_EXPR (int(draw(0) )); +SHOW_EXPR (int(draw(127))); +SHOW_EXPR (int(draw(128))); +SHOW_EXPR (int(draw(141))); +SHOW_EXPR (int(draw(255))); +SHOW_EXPR (int(draw(256))); +// CHECK (draw(0) == 0); +// CHECK (draw(127) == 0); +// CHECK (draw(128) == 1); +// CHECK (draw(141) == 2); +// CHECK (draw(255) ==10); +// CHECK (draw(256) == 0); + } + + + + /** @test TODO verify configuration through policy template + * @todo WIP 11/23 🔁 define ⟶ implement + */ + void + verify_policy() + { +// auto d1 = RandomDraw>().probability(1.0); +//SHOW_EXPR (uint(d1())) } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a3aaf0bb5..91b965ed6 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -96626,7 +96626,29 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + + + + + + + +