diff --git a/src/lib/random.cpp b/src/lib/random.cpp index 91efd7e78..390ead38d 100644 --- a/src/lib/random.cpp +++ b/src/lib/random.cpp @@ -72,14 +72,21 @@ namespace lib { /// @todo this one should somehow be configurable EternalNucleus eternalNucleus; + + Random::Seed defaultNucleus{defaultGen}; } - - SeedNucleus::~SeedNucleus() { } - Random defaultGen{eternalNucleus}; Random entropyGen{entropyNucleus}; + SeedNucleus& + seedFromDefaultGen() + { + return defaultNucleus; + } + + + SeedNucleus::~SeedNucleus() { } void randomiseRandomness() @@ -88,4 +95,5 @@ namespace lib { defaultGen.reseed(entropyNucleus); } + } // namespace lib diff --git a/src/lib/random.hpp b/src/lib/random.hpp index 2156ab0d5..11046f1fa 100644 --- a/src/lib/random.hpp +++ b/src/lib/random.hpp @@ -81,8 +81,29 @@ namespace lib { /** inject controlled randomisation */ void reseed (SeedNucleus&); + + /** wrapper to use this generator for seeding other generators */ + class Seed; }; + template + class RandomSequencer::Seed + : public SeedNucleus + { + RandomSequencer& srcGen_; + public: + Seed(RandomSequencer& parent) + : srcGen_{parent} + { } + + uint64_t + getSeed() override + { + return srcGen_.u64(); + } + }; + + /** * PRNG engine to use by default: 64bit mersenne twister. */ @@ -106,6 +127,10 @@ namespace lib { /** inject true randomness into the #defaultGen */ void randomiseRandomness(); + /** draw seed another Generator from the default RandomSequencer */ + SeedNucleus& seedFromDefaultGen(); + + /* ===== Implementation details ===== */ diff --git a/src/lib/test/suite.cpp b/src/lib/test/suite.cpp index 89a3b4456..4b1fc402d 100644 --- a/src/lib/test/suite.cpp +++ b/src/lib/test/suite.cpp @@ -36,7 +36,7 @@ #include "lib/util.hpp" #include -#include +#include #include #include #include @@ -48,12 +48,14 @@ namespace test { using std::map; using std::vector; + using std::optional; using std::shared_ptr; using boost::algorithm::trim; using util::isnil; using util::contains; using util::typeStr; + using lib::SeedNucleus; using lib::Random; typedef map TestMap; @@ -97,7 +99,22 @@ namespace test { (*group)[testID] = test; } }; - + + class SuiteSeedNucleus + : public SeedNucleus + { + optional fixedSeed_; + + uint64_t + getSeed() override + { + return fixedSeed_? *fixedSeed_ + : lib::entropyGen.u64(); + } + }; + + /* ===== global implementation state ===== */ + SuiteSeedNucleus suiteSeed; Registry testcases; } @@ -192,17 +209,19 @@ namespace test { } + /** draw a new random seed from a common nucleus, and re-seed the default-Gen. */ void Test::seedRand() { - UNIMPLEMENTED ("draw a new random seed from a common nucleus, and re-seed the default-Gen"); + lib::defaultGen.reseed (suiteSeed); } + /** build a dedicated new RandomGen, seeded from the default-Gen */ Random Test::makeRandGen() { - UNIMPLEMENTED ("build a dedicated new RandomGen, seeded from the default-Gen"); + return Random{lib::seedFromDefaultGen()}; } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index f73c40ae4..3375642ed 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -14875,9 +14875,7 @@ - - - +

...und die IterSource dann nur über WrapIter definieren. @@ -16158,9 +16156,7 @@ - - - +

das mag überraschend klingen, @@ -16878,9 +16874,7 @@ - - - +

muß kein Manager sein @@ -17498,9 +17492,7 @@ - - - +

Brücke: gemeinsamer Controller @@ -18756,9 +18748,7 @@ - - - +

...was normalerweise ja auch irrelevant ist, denn per Voraussetzung sollte ein Container die Werte von seinen Kindern bereits bei seiner initialen Meldung berücksichtigt haben @@ -46521,9 +46511,7 @@ - - - +

...ist immer ein tangible @@ -46885,9 +46873,7 @@ - - - +

ganz bewußt verzichten wir darauf, @@ -47469,9 +47455,7 @@ - - - +

aber was dann wenn out-of-order @@ -47765,9 +47749,7 @@ - - - +

then move into target @@ -47983,9 +47965,7 @@ - - - +

Mutator enthält die Bindung auf die konkreten Daten @@ -57406,8 +57386,35 @@ - - + + + + +

+ das ist der klassische Fall, in dem eine »saubere« Repräsentation in der einzelnen Testklasse zu massiver Speicherverschwendung führt, weil jede Testklasse einen redundanten Pointer auf den gleichen globalen Kontext bekommt +

+ + +
+
+ + + + + + + + + + + + + + + + + +