blob: 8ebfc73eca268e7eec2323b9cd25ba6141a825c1 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits>
#include <random>
#include <type_traits>
#include <utility>
// Utility to simplify random number generation and item selection on top of the
// STD random library.
class Random {
Random() = default;
// Trait to determine the underlying integer type of a given type T. Supports
// integral types and enumerations. Additional specializations may be added to
// support other countable or enumerable objects.
template <typename T, typename = void>
struct BaseType {
using Type = T;
template <typename Enum>
struct BaseType<Enum, std::enable_if_t<std::is_enum<Enum>::value>> {
using Type = std::underlying_type_t<Enum>;
template <typename T>
using Base = typename BaseType<T>::Type;
template <typename T>
T GetUniform() {
std::uniform_int_distribution<Base<T>> distribution{std::numeric_limits<Base<T>>::lowest(),
return static_cast<T>(distribution(generator_));
template <typename T>
T GetUniform(T min, T max) {
std::uniform_int_distribution<Base<T>> distribution{static_cast<Base<T>>(min),
return static_cast<T>(distribution(generator_));
template <typename T>
T SelectUniform(std::initializer_list<T> il) {
std::uniform_int_distribution<std::size_t> distribution{0, il.size() > 0 ? il.size() - 1 : 0};
return il.begin()[distribution(generator_)];
std::mt19937_64 generator_{std::random_device{}()};