|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "../common.h"
|
|
|
|
|
|
|
|
#include "../rng.h"
|
|
|
|
#include "../mem.h"
|
|
|
|
|
|
|
|
namespace rng
|
|
|
|
{
|
|
|
|
struct crand final : public Random
|
|
|
|
{
|
|
|
|
// This range is inclusive
|
|
|
|
constexpr static inline i64 RANGE_MIN = - (1L << 31);
|
|
|
|
constexpr static inline i64 RANGE_MAX = (1L << 31) - 1;
|
|
|
|
|
|
|
|
crand();
|
|
|
|
crand(u64 seed);
|
|
|
|
|
|
|
|
inline ~crand(){}
|
|
|
|
|
|
|
|
inline i64 next_i64() override { return _sample_int(); }
|
|
|
|
u64 next_u64() override;
|
|
|
|
protected:
|
|
|
|
inline constexpr i64 _max_i64() const override { return RANGE_MAX; }
|
|
|
|
inline constexpr u64 _max_u64() const override { return (u64)RANGE_MAX; }
|
|
|
|
// the rest of the base `_max_*` functions are valid, as they will always be equal to or less than INT32_MAX (the upper bound of dr48.)
|
|
|
|
f64 _sample() override;
|
|
|
|
private:
|
|
|
|
struct _opaque;
|
|
|
|
struct _deleter { static void delete_object(_opaque** st); };
|
|
|
|
mem::aligned_ptr<_opaque, _deleter> _state;
|
|
|
|
|
|
|
|
explicit crand(_opaque* raw);
|
|
|
|
i64 _sample_int();
|
|
|
|
};
|
|
|
|
}
|