Arbutils/src/Random.hpp

93 lines
4.1 KiB
C++
Raw Normal View History

2020-02-26 11:57:18 +00:00
#ifndef ARBUTILS_RANDOM_HPP
#define ARBUTILS_RANDOM_HPP
#include <chrono>
2020-02-26 11:57:18 +00:00
#include <cstdint>
#include <random>
2022-02-05 12:37:47 +00:00
#include <pcg_random.hpp>
#include "Ensure.hpp"
2020-02-26 11:57:18 +00:00
namespace ArbUt {
2020-09-22 17:32:40 +00:00
/// @brief A helper class for getting random numbers.
/// @tparam RandomT A type for the desired random number generator.
2020-02-26 11:57:18 +00:00
template <class RandomT> class BaseRandom {
private:
2020-04-04 16:01:35 +00:00
uint_fast32_t _seed;
2020-02-26 11:57:18 +00:00
RandomT _rng;
std::uniform_real_distribution<double> _distribution;
2020-02-26 11:57:18 +00:00
public:
inline constexpr BaseRandom() noexcept
: _seed(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count()),
_rng(_seed), _distribution(0.0, 1.0) {}
2020-02-26 12:27:56 +00:00
2020-09-22 17:32:40 +00:00
/// @brief Instantiate random class with a specific seed.
/// @param seed The seed the random number generator should be instantiated with.
2020-04-04 16:01:35 +00:00
explicit inline constexpr BaseRandom(uint_fast32_t seed) noexcept
: _seed(seed), _rng(seed), _distribution(0.0, 1.0){};
2020-02-26 11:57:18 +00:00
2020-09-22 17:32:40 +00:00
/// @brief The random number generator that is backing the random class.
2020-04-22 20:54:57 +00:00
inline RandomT& GetRandomEngine() noexcept { return _rng; }
2020-09-22 17:32:40 +00:00
/// @brief Gets a random float between 0.0 and 1.0.
2020-04-04 16:01:35 +00:00
[[nodiscard]] inline constexpr float GetFloat() noexcept { return static_cast<float>(GetDouble()); }
2020-02-26 11:57:18 +00:00
2020-09-22 17:32:40 +00:00
/// @brief Gets a random double between 0.0 and 1.0.
2020-04-04 16:01:35 +00:00
[[nodiscard]] inline constexpr double GetDouble() noexcept { return _distribution(_rng); }
2020-02-26 11:57:18 +00:00
2020-09-22 17:32:40 +00:00
/// @brief Gets a random 32 bit integer
2020-04-04 16:01:35 +00:00
[[nodiscard]] inline constexpr int32_t Get() noexcept { return static_cast<int32_t>(_rng()); }
2020-02-26 11:57:18 +00:00
2020-09-22 17:32:40 +00:00
/// @brief 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) {
Ensure(max > 0);
2020-04-04 16:01:35 +00:00
std::uniform_int_distribution<int32_t> distribution(0, max - 1);
return distribution(_rng);
2020-02-26 11:57:18 +00:00
}
2020-09-22 17:32:40 +00:00
/// @brief 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) {
Ensure(max > min);
2020-04-04 16:01:35 +00:00
std::uniform_int_distribution<int32_t> distribution(min, max - 1);
return distribution(_rng);
2020-02-26 11:57:18 +00:00
}
2020-09-22 17:32:40 +00:00
/// @brief Gets a random 32 bit unsigned integer between 0 and max unsigned int.
2020-04-04 16:01:35 +00:00
[[nodiscard]] inline constexpr uint32_t GetUnsigned() noexcept { return _rng(); }
2020-02-26 11:57:18 +00:00
2020-09-22 17:32:40 +00:00
/// @brief 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 {
2020-04-04 16:01:35 +00:00
std::uniform_int_distribution<uint32_t> distribution(0, max - 1);
return distribution(_rng);
2020-02-26 11:57:18 +00:00
}
2020-09-22 17:32:40 +00:00
/// @brief 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) {
Ensure(max > min);
2020-04-04 16:01:35 +00:00
std::uniform_int_distribution<uint32_t> distribution(min, max - 1);
return distribution(_rng);
2020-02-26 11:57:18 +00:00
}
2020-09-22 17:32:40 +00:00
/// @brief The seed the random class is generating from.
2020-04-04 16:01:35 +00:00
[[nodiscard]] inline constexpr uint_fast32_t GetSeed() const noexcept { return _seed; }
2020-02-26 11:57:18 +00:00
};
2020-09-22 17:32:40 +00:00
/// @brief Implementation of the BaseRandom class with pcg32 as random number generator.
class Random : public BaseRandom<pcg32> {
2020-02-26 11:57:18 +00:00
public:
constexpr Random() noexcept : BaseRandom() {}
2020-09-22 17:32:40 +00:00
/// @brief Instantiate random class with a specific seed.
/// @param seed The seed the random number generator should be instantiated with.
explicit constexpr Random(uint_fast32_t seed) noexcept : BaseRandom(seed) {}
2020-02-26 11:57:18 +00:00
};
}
#endif // ARBUTILS_RANDOM_HPP