random: separate the generator initialisation code
This commit is contained in:
parent
8f88569f61
commit
6142f7fb1d
52
random.hpp
52
random.hpp
@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2016-2018 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2016-2019 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -18,37 +18,19 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace cruft::random {
|
namespace cruft::random {
|
||||||
/// A trait describing the internal state size of a given Generator.
|
///////////////////////////////////////////////////////////////////////////
|
||||||
///
|
/// Initialise and return a generator using random_device.
|
||||||
/// The structure must be specialised.
|
|
||||||
///
|
|
||||||
/// \tparam GeneratorT The generator to query
|
|
||||||
template <typename GeneratorT>
|
template <typename GeneratorT>
|
||||||
struct state_size;
|
GeneratorT
|
||||||
|
initialise (void)
|
||||||
|
{
|
||||||
|
// Approximate the state size of the generator by its size in bytes.
|
||||||
|
std::array<unsigned,sizeof (GeneratorT) / sizeof (unsigned) + 1> seed;
|
||||||
|
std::generate (seed.begin (), seed.end (), std::random_device ());
|
||||||
|
|
||||||
|
std::seed_seq seq (seed.begin (), seed.end ());
|
||||||
//-------------------------------------------------------------------------
|
return GeneratorT (seq);
|
||||||
template <
|
}
|
||||||
class UIntType,
|
|
||||||
size_t w, size_t n, size_t m, size_t r,
|
|
||||||
UIntType a, size_t u, UIntType d, size_t s,
|
|
||||||
UIntType b, size_t t,
|
|
||||||
UIntType c, size_t l, UIntType f
|
|
||||||
> struct state_size<std::mersenne_twister_engine<UIntType,w,n,m,r,a,u,d,s,b,t,c,l,f>> {
|
|
||||||
static constexpr auto value = n * sizeof (UIntType);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
template <typename UIntType, UIntType a, UIntType c, UIntType m>
|
|
||||||
struct state_size<std::linear_congruential_engine<UIntType,a,c,m>> {
|
|
||||||
static constexpr auto value = sizeof (UIntType);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
template <typename T>
|
|
||||||
constexpr auto state_size_v = state_size<T>::value;
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -60,15 +42,7 @@ namespace cruft::random {
|
|||||||
generator (void)
|
generator (void)
|
||||||
{
|
{
|
||||||
using generator_t = std::mt19937_64;
|
using generator_t = std::mt19937_64;
|
||||||
|
static thread_local auto gen = initialise<generator_t> ();
|
||||||
static thread_local generator_t gen = [] () {
|
|
||||||
std::array<int,state_size_v<generator_t> / 4> seed;
|
|
||||||
std::generate (seed.begin (), seed.end (), std::random_device ());
|
|
||||||
|
|
||||||
std::seed_seq seq (seed.begin (), seed.end ());
|
|
||||||
return generator_t (seq);
|
|
||||||
} ();
|
|
||||||
|
|
||||||
return gen;
|
return gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user