Add PCG32 generator to pcg

This commit is contained in:
Nikita Lisitsa 2020-09-23 11:00:19 +03:00
parent 06916083bb
commit 83aba92c42

View file

@ -0,0 +1,66 @@
#pragma once
#include <cstdint>
#include <limits>
namespace psemek::pcg
{
// based on www.pcg-random.org
struct generator
{
generator() = default;
generator(generator const &) = default;
generator(std::uint64_t state, std::uint64_t inc)
: state_{state}
, inc_{inc}
{}
template <typename RD>
generator(RD && rd, std::uint64_t inc)
: state_{gen64(rd)}
, inc_{inc}
{}
template <typename RD>
generator(RD && rd)
: state_{gen64(rd)}
, inc_{gen64(rd)}
{}
generator & operator = (generator const &) = default;
using result_type = std::uint32_t;
result_type operator()()
{
std::uint64_t oldstate = state_;
state_ = oldstate * 6364136223846793005ULL + (inc_ | 1);
std::uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
std::uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}
static result_type min()
{
return 0;
}
static result_type max()
{
return std::numeric_limits<result_type>::max();
}
private:
std::uint64_t state_;
std::uint64_t inc_;
template <typename RD>
static std::uint64_t gen64(RD & rd)
{
return (static_cast<std::uint64_t>(rd()) << 32) | rd();
}
};
}