Newer
Older
ForwardPlusRenderer / include / RNG.h
#pragma once
#include <stdafx.h>
#include <random>
#include <type_traits>
#include <vector>
template<typename T>
concept distribution_type = requires
{
  T::param_type::distribution_type;
}
|| requires
{
  T::distribution_type;
};

template<distribution_type Distribution>
class RNG
{
  using result_type = typename Distribution::result_type;
  mutable std::mt19937 mt;
  std::random_device   random_device;
  Distribution         m_distribution;
  std::seed_seq        m_seed;
public:
  RNG(result_type min = 0, result_type max = 1): m_distribution(min, max)
  {
    mt.seed(random_device());
  }

  [[nodiscard]] constexpr result_type Get() const
  {
    return m_distribution(mt);
  }

  [[nodiscard]] constexpr std::vector<result_type> Get(size_t count) const
  {
    std::vector<result_type> result;
    result.reserve(count);
    for(size_t i = 0; i < count; ++i) { result.push_back(m_distribution(mt)); }
    return result;
  }

  void Seed(std::seed_seq seed)
  {
    mt.seed(seed);
  }

  [[nodiscard]] constexpr auto& GetSeed() const FPR_NOEXCEPT
  {
    return m_seed;
  }
};