pcg.hpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_CORE_DETAIL_PCG_HPP
  10. #define BOOST_BEAST_CORE_DETAIL_PCG_HPP
  11. #include <boost/core/ignore_unused.hpp>
  12. #include <cstdint>
  13. #include <random>
  14. namespace boost {
  15. namespace beast {
  16. namespace detail {
  17. class pcg
  18. {
  19. std::uint64_t state_ = 0;
  20. std::uint64_t increment_;
  21. public:
  22. using result_type = std::uint32_t;
  23. // Initialize the generator.
  24. // There are no restrictions on the input values.
  25. pcg(
  26. std::uint64_t seed,
  27. std::uint64_t stream)
  28. {
  29. // increment must be odd
  30. increment_ = 2 * stream + 1;
  31. boost::ignore_unused((*this)());
  32. state_ += seed;
  33. boost::ignore_unused((*this)());
  34. }
  35. std::uint32_t
  36. operator()()
  37. {
  38. std::uint64_t const p = state_;
  39. state_ = p *
  40. 6364136223846793005ULL +
  41. increment_;
  42. std::uint32_t const x =
  43. static_cast<std::uint32_t>(
  44. ((p >> 18) ^ p) >> 27);
  45. std::uint32_t const r = p >> 59;
  46. #ifdef BOOST_MSVC
  47. return _rotr(x, r);
  48. #else
  49. return (x >> r) | (x << ((1 + ~r) & 31));
  50. #endif
  51. }
  52. };
  53. } // detail
  54. } // beast
  55. } // boost
  56. #endif