diff --git a/memory/buffer/circular.cpp b/memory/buffer/circular.cpp index 457db4fe..c44435d3 100644 --- a/memory/buffer/circular.cpp +++ b/memory/buffer/circular.cpp @@ -48,7 +48,7 @@ tmpname (std::string &str, size_t length) str.resize (length); std::generate_n (str.begin (), length, [&] (void) { - return util::rand::choose (alphanum); + return util::random::choose (alphanum); }); } diff --git a/random.hpp b/random.hpp index b2bbe4a5..e75a3a97 100644 --- a/random.hpp +++ b/random.hpp @@ -14,36 +14,52 @@ * Copyright 2016 Danny Robson */ -#ifndef __UTIL_RANDOM_HPP -#define __UTIL_RANDOM_HPP +#ifndef CRUFT_UTIL_RANDOM_HPP +#define CRUFT_UTIL_RANDOM_HPP #include -/////////////////////////////////////////////////////////////////////////////// -namespace util::rand { - //------------------------------------------------------------------------- - using default_generator = std::minstd_rand; - - - //------------------------------------------------------------------------- - template - Generator& - thread_engine (void) +namespace util::random { + /////////////////////////////////////////////////////////////////////////// + /// return correctly initialised thread-local generator of an unspecified, + /// but not entirely useless, type. ie, not LCG. + auto& + generator (void) { - std::random_device rd; - thread_local Generator gen (rd ()); + static thread_local std::mt19937_64 gen { std::random_device {}() }; return gen; } - //------------------------------------------------------------------------- - template - T& - choose (T (&t)[N], Generator gen = thread_engine ()) + /////////////////////////////////////////////////////////////////////////// + /// select a value uniformly from the range [lo, hi) + template + std::enable_if_t,T> + uniform (T lo, T hi) { - std::uniform_int_distribution dist (0, N-1); - return t[dist (gen)]; + return std::uniform_real_distribution { lo, hi } (generator ()); + } + + + //------------------------------------------------------------------------- + /// select a value uniformly from the range [lo, hi) + template + std::enable_if_t,T> + uniform (T lo, T hi) + { + return std::uniform_int_distribution { lo, hi } (generator ()); + } + + + /////////////////////////////////////////////////////////////////////////// + /// choose a value at random from an array + template + T& + choose (T (&t)[N]) + { + std::uniform_int_distribution dist (0, N - 1); + return t[dist (generator ())]; } }