diff --git a/include/envoy/runtime/runtime.h b/include/envoy/runtime/runtime.h index 6494289402dfb..7eda91473c904 100644 --- a/include/envoy/runtime/runtime.h +++ b/include/envoy/runtime/runtime.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -30,10 +31,30 @@ class RandomGenerator { public: virtual ~RandomGenerator() = default; + using result_type = uint64_t; // NOLINT(readability-identifier-naming) + /** * @return uint64_t a new random number. */ - virtual uint64_t random() PURE; + virtual result_type random() PURE; + + /* + * @return the smallest value that `operator()` may return. The value is + * strictly less than `max()`. + */ + constexpr static result_type min() noexcept { return std::numeric_limits::min(); }; + + /* + * @return the largest value that `operator()` may return. The value is + * strictly greater than `min()`. + */ + constexpr static result_type max() noexcept { return std::numeric_limits::max(); }; + + /* + * @return a value in the closed interval `[min(), max()]`. Has amortized + * constant complexity. + */ + result_type operator()() { return result_type(random()); }; /** * @return std::string containing uuid4 of 36 char length. diff --git a/test/common/runtime/runtime_impl_test.cc b/test/common/runtime/runtime_impl_test.cc index e53097f5d74b1..d591e3b6d7638 100644 --- a/test/common/runtime/runtime_impl_test.cc +++ b/test/common/runtime/runtime_impl_test.cc @@ -48,6 +48,23 @@ TEST(Random, SanityCheckOfUniquenessRandom) { EXPECT_EQ(num_of_results, results.size()); } +TEST(Random, SanityCheckOfStdLibRandom) { + Runtime::RandomGeneratorImpl random; + + static const auto num_of_items = 100; + std::vector v(num_of_items); + std::iota(v.begin(), v.end(), 0); + + static const auto num_of_checks = 10000; + for (size_t i = 0; i < num_of_checks; ++i) { + const auto prev = v; + std::shuffle(v.begin(), v.end(), random); + EXPECT_EQ(v.size(), prev.size()); + EXPECT_NE(v, prev); + EXPECT_FALSE(std::is_sorted(v.begin(), v.end())); + } +} + TEST(UUID, CheckLengthOfUUID) { RandomGeneratorImpl random;