| // 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. |
| |
| #ifndef SRC_TESTING_LOADBENCH_RANDOM_H_ |
| #define SRC_TESTING_LOADBENCH_RANDOM_H_ |
| |
| #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 { |
| public: |
| 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(), |
| std::numeric_limits<Base<T>>::max()}; |
| 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), |
| static_cast<Base<T>>(max)}; |
| 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_)]; |
| } |
| |
| private: |
| std::mt19937_64 generator_{std::random_device{}()}; |
| }; |
| |
| #endif // SRC_TESTING_LOADBENCH_RANDOM_H_ |