random: separate the generator initialisation code

This commit is contained in:
Danny Robson 2019-02-21 20:53:32 +11:00
parent 8f88569f61
commit 6142f7fb1d

View File

@ -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;
} }