|
|
|
@ -34,6 +34,7 @@ struct InvalidRandomSample final : public std::exception {
|
|
|
|
|
|
|
|
|
|
const f64 value;
|
|
|
|
|
};
|
|
|
|
|
struct ObjectMoved final : public std::exception{};
|
|
|
|
|
|
|
|
|
|
/// Interface for a simple random number generator
|
|
|
|
|
///
|
|
|
|
@ -48,7 +49,26 @@ struct InvalidRandomSample final : public std::exception {
|
|
|
|
|
struct Random
|
|
|
|
|
{
|
|
|
|
|
template<typename T>
|
|
|
|
|
struct iterator; //TODO: Implement this in another file (has to be header because of template :/)
|
|
|
|
|
struct iterator { //TODO: Implement this in another file (has to be header because of template :/)
|
|
|
|
|
friend class Random;
|
|
|
|
|
|
|
|
|
|
//TODO: Make this work with foreach(), and STL iterator APIs somehow
|
|
|
|
|
|
|
|
|
|
inline CTOR_COPY(iterator<T>) : rng(copy.rng){}
|
|
|
|
|
inline CTOR_MOVE(iterator<T>) : rng(move.rng) {
|
|
|
|
|
*const_cast<Random**>(&move.rng) = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline virtual ~iterator(){}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
virtual T _sample() { if (rng) return rng->next<T>(); else throw ObjectMoved(); }
|
|
|
|
|
virtual inline void _init() {}
|
|
|
|
|
private:
|
|
|
|
|
inline explicit iterator(Random& rng) : rng(&rng){ _init(); }
|
|
|
|
|
|
|
|
|
|
Random* const rng;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr inline Random(){}
|
|
|
|
|
constexpr inline virtual ~Random(){}
|
|
|
|
@ -129,7 +149,7 @@ struct Random
|
|
|
|
|
return std::bit_cast<T>(arr);
|
|
|
|
|
}
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline iterator<T> iter(); //TODO: An iterator that yields `next<T>()` forever.
|
|
|
|
|
inline iterator<T> iter() { return iterator(*this); } //TODO: An iterator that yields `next<T>()` forever.
|
|
|
|
|
protected:
|
|
|
|
|
//constexpr inline virtual i8 _max() const { return 100; } // use limits.h stuff instead.
|
|
|
|
|
|
|
|
|
|