random.cxx 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #include "random/random.h"
  2. #include <cassert>
  3. #include <cfloat>
  4. #include <random>
  5. #include <scope_guard/scope_guard.hpp>
  6. #include "random/device.h"
  7. #include "random/distribution.h"
  8. #include "random/tape.h"
  9. #define IMPLEMENT_RANDOM(T) \
  10. template T Random::operator()(Distribution<T> const &) const;
  11. namespace engine::random {
  12. class DefaultDevice : public Device {
  13. public:
  14. result_type operator()() final { return rng(); }
  15. private:
  16. std::mt19937 rng{std::random_device{}()};
  17. };
  18. Random::Random() : impl_(std::make_shared<DefaultDevice>()) {}
  19. Random::Random(Random const & other, std::shared_ptr<Tape> with_tape)
  20. : impl_(other.impl_), tape_(with_tape) {}
  21. Random::Random(Random const & other, Tape & with_tape)
  22. : impl_(other.impl_), tape_(&with_tape, [](void *) {}) {}
  23. template <typename Rand>
  24. Rand Random::operator()(Distribution<Rand> const & dist) const {
  25. return tape_ ? tape_->apply(dist, impl_->apply(dist)) : impl_->apply(dist);
  26. }
  27. scope_exit Random::record(std::shared_ptr<Tape> tape) {
  28. assert(tape && !tape_);
  29. tape_ = tape;
  30. return [this]() { tape_.reset(); };
  31. }
  32. IMPLEMENT_DEVICE(IMPLEMENT_RANDOM)
  33. }