#ifndef ARBUTILS_RANDOM_HPP #define ARBUTILS_RANDOM_HPP #include #include #include #include "Assert.hpp" namespace Arbutils { template class BaseRandom { private: uint_fast32_t _seed; RandomT _rng; std::uniform_real_distribution _distribution; public: inline constexpr BaseRandom() noexcept : _seed(std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()) .count()), _rng(_seed), _distribution(0.0, 1.0) {} explicit inline constexpr BaseRandom(uint_fast32_t seed) noexcept : _seed(seed), _rng(seed), _distribution(0.0, 1.0){}; inline RandomT& GetRandomEngine() noexcept { return _rng; } /// Gets a random float between 0.0 and 1.0. [[nodiscard]] inline constexpr float GetFloat() noexcept { return static_cast(GetDouble()); } /// Gets a random double between 0.0 and 1.0. [[nodiscard]] inline constexpr double GetDouble() noexcept { return _distribution(_rng); } /// Gets a random 32 bit integer [[nodiscard]] inline constexpr int32_t Get() noexcept { return static_cast(_rng()); } /// Gets a random 32 bit integer between 0, and given max parameter. /// \param max The exclusive max value the random value should be. [[nodiscard]] inline int32_t Get(int32_t max) { Assert(max > 0); std::uniform_int_distribution distribution(0, max - 1); return distribution(_rng); } /// Gets a random 32 bit integer between given min and max parameters. /// \param min The inclusive min value the random value should be. /// \param max The exclusive max value the random value should be. [[nodiscard]] inline int32_t Get(int32_t min, int32_t max) { Assert(max > min); std::uniform_int_distribution distribution(min, max - 1); return distribution(_rng); } /// Gets a random 32 bit unsigned integer between 0 and max unsigned int. [[nodiscard]] inline constexpr uint32_t GetUnsigned() noexcept { return _rng(); } /// Gets a random 32 bit unsigned integer between 0, and given max parameter. /// \param max The exclusive max value the random value should be. [[nodiscard]] inline uint32_t GetUnsigned(uint32_t max) noexcept { std::uniform_int_distribution distribution(0, max - 1); return distribution(_rng); } /// Gets a random 32 bit unsigned integer between given min and max parameters. /// \param min The inclusive min value the random value should be. /// \param max The exclusive max value the random value should be. [[nodiscard]] inline uint32_t GetUnsigned(uint32_t min, uint32_t max) { Assert(max > min); std::uniform_int_distribution distribution(min, max - 1); return distribution(_rng); } [[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { return _seed; } }; class Random : public BaseRandom { public: constexpr Random() : BaseRandom() {} explicit constexpr Random(uint_fast32_t seed) : BaseRandom(seed) {} }; } #endif // ARBUTILS_RANDOM_HPP