|
|
|
|
|
|
|
#include <rngxx.hpp>
|
|
|
|
#include <range.h>
|
|
|
|
|
|
|
|
constexpr const static util::range<f64> SAMPLE_RANGE { 0.0, 1.0 };
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
static inline constexpr T _scale(f64 sample, T max)
|
|
|
|
{
|
|
|
|
return (T)(sample * (f64)max);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
static inline constexpr T _scale(f64 sample, T min, T max)
|
|
|
|
{
|
|
|
|
return SAMPLE_RANGE.scale<T>({ min, max }, sample);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Random::next_bool() { return sample() < 0.5; }
|
|
|
|
#define NEXT(T) T Random::next_ ## T(T max) { return _scale<T >(sample(), max); }
|
|
|
|
#define NEXTT(n) NEXT(i ## n) NEXT(u ## n)
|
|
|
|
|
|
|
|
#define N_INTS \
|
|
|
|
NEXTT(8) \
|
|
|
|
NEXTT(16) \
|
|
|
|
NEXTT(32) \
|
|
|
|
NEXTT(64)
|
|
|
|
N_INTS
|
|
|
|
|
|
|
|
#undef NEXTT
|
|
|
|
#undef NEXT
|
|
|
|
|
|
|
|
f64 Random::sample()
|
|
|
|
{
|
|
|
|
auto s = _sample();
|
|
|
|
if (UNLIKELY(s < 0 || s > 1)) throw InvalidRandomSample{ s };
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Inefficient sample() based impl of `bytes()`
|
|
|
|
void Random::next_bytes(u8* ptr, usize n)
|
|
|
|
{
|
|
|
|
while( n --> 0 )
|
|
|
|
*ptr++ = next_u8();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non-vertorised impl of _v methods for base
|
|
|
|
void Random::next_v64(u64* p, usize n)
|
|
|
|
{
|
|
|
|
return next_bytes(reinterpret_cast<u8*>(p), n * sizeof(u64));
|
|
|
|
}
|
|
|
|
void Random::next_v32(u32* p, usize n)
|
|
|
|
{
|
|
|
|
return next_bytes(reinterpret_cast<u8*>(p), n * sizeof(u32));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Array getters
|
|
|
|
#define NEXT(T) void Random::next_ ## T(T* a, usize n) { while( n --> 0 ) *a++ = next_ ## T(); }
|
|
|
|
#define NEXTT(n) NEXT(i ## n) NEXT(u ## n)
|
|
|
|
|
|
|
|
N_INTS
|
|
|
|
|
|
|
|
#undef NEXTT
|
|
|
|
#undef NEXT
|
|
|
|
// ---
|
|
|
|
|
|
|
|
//next_*(min, max)
|
|
|
|
#define NEXT(T) T Random::next_ ## T(T min, T max) { return _scale(sample(), min, max); }
|
|
|
|
#define NEXTT(n) NEXT(i ## n) NEXT(u ## n)
|
|
|
|
|
|
|
|
N_INTS
|
|
|
|
|
|
|
|
#undef NEXTT
|
|
|
|
#undef NEXT
|
|
|
|
// ---
|
|
|
|
|
|
|
|
//TODO: Why does this have to be in a specific TU to work?
|
|
|
|
#include "../internal/dctor.h"
|