1/*
2 *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_RANDOM_H_
12#define WEBRTC_BASE_RANDOM_H_
13
14#include <limits>
15
16#include "webrtc/typedefs.h"
17#include "webrtc/base/constructormagic.h"
18#include "webrtc/base/checks.h"
19
20namespace webrtc {
21
22class Random {
23 public:
24  explicit Random(uint64_t seed);
25
26  // Return pseudo-random integer of the specified type.
27  // We need to limit the size to 32 bits to keep the output close to uniform.
28  template <typename T>
29  T Rand() {
30    static_assert(std::numeric_limits<T>::is_integer &&
31                      std::numeric_limits<T>::radix == 2 &&
32                      std::numeric_limits<T>::digits <= 32,
33                  "Rand is only supported for built-in integer types that are "
34                  "32 bits or smaller.");
35    return static_cast<T>(NextOutput());
36  }
37
38  // Uniformly distributed pseudo-random number in the interval [0, t].
39  uint32_t Rand(uint32_t t);
40
41  // Uniformly distributed pseudo-random number in the interval [low, high].
42  uint32_t Rand(uint32_t low, uint32_t high);
43
44  // Uniformly distributed pseudo-random number in the interval [low, high].
45  int32_t Rand(int32_t low, int32_t high);
46
47  // Normal Distribution.
48  double Gaussian(double mean, double standard_deviation);
49
50  // Exponential Distribution.
51  double Exponential(double lambda);
52
53 private:
54  // Outputs a nonzero 64-bit random number.
55  uint64_t NextOutput() {
56    state_ ^= state_ >> 12;
57    state_ ^= state_ << 25;
58    state_ ^= state_ >> 27;
59    RTC_DCHECK(state_ != 0x0ULL);
60    return state_ * 2685821657736338717ull;
61  }
62
63  uint64_t state_;
64
65  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
66};
67
68// Return pseudo-random number in the interval [0.0, 1.0).
69template <>
70float Random::Rand<float>();
71
72// Return pseudo-random number in the interval [0.0, 1.0).
73template <>
74double Random::Rand<double>();
75
76// Return pseudo-random boolean value.
77template <>
78bool Random::Rand<bool>();
79
80}  // namespace webrtc
81
82#endif  // WEBRTC_BASE_RANDOM_H_
83