You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rngxx/src/rng.cpp

78 lines
1.5 KiB

#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
// ---