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
- + + + + + + + + + + + + + + + + + + + + + + +