X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FRandom.h;h=a8682dc09bb4b0a1c5a2a10e77841475bbdaac46;hp=53283a286a3d01f07d0a3e783562e7e64bcfdc04;hb=b8ec2ef5137cb75cb75bb27c6b003c5f4e21bcb2;hpb=321542683a01c3f334047531e9b487f047129775 diff --git a/folly/Random.h b/folly/Random.h index 53283a28..a8682dc0 100644 --- a/folly/Random.h +++ b/folly/Random.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -#ifndef FOLLY_RANDOM_H_ +#pragma once #define FOLLY_RANDOM_H_ #include @@ -65,9 +65,9 @@ class ThreadLocalPRNG { ThreadLocalPRNG(); - private: class LocalInstancePRNG; + private: static result_type getImpl(LocalInstancePRNG* local); LocalInstancePRNG* local_; }; @@ -76,10 +76,10 @@ class ThreadLocalPRNG { class Random { private: - template + template using ValidRNG = typename std::enable_if< - std::is_unsigned::type>::value, - RNG>::type; + std::is_unsigned::type>::value, + RNG>::type; public: // Default generator type. @@ -115,8 +115,8 @@ class Random { * to create a RNG with a good seed in production, and seed it yourself * in test. */ - template - static void seed(ValidRNG& rng); + template > + static void seed(RNG& rng); /** * Create a new RNG, seeded with a good seed. @@ -126,104 +126,153 @@ class Random { * to create a RNG with a good seed in production, and seed it yourself * in test. */ - template - static ValidRNG create(); + template > + static RNG create(); /** * Returns a random uint32_t */ - template - static uint32_t rand32(ValidRNG rng = RNG()) { - uint32_t r = rng.operator()(); - return r; + static uint32_t rand32() { + return rand32(ThreadLocalPRNG()); + } + + /** + * Returns a random uint32_t given a specific RNG + */ + template > + static uint32_t rand32(RNG&& rng) { + return rng(); } /** * Returns a random uint32_t in [0, max). If max == 0, returns 0. */ - template - static uint32_t rand32(uint32_t max, ValidRNG rng = RNG()) { - if (max == 0) { - return 0; - } + static uint32_t rand32(uint32_t max) { + return rand32(0, max, ThreadLocalPRNG()); + } - return std::uniform_int_distribution(0, max - 1)(rng); + /** + * Returns a random uint32_t in [0, max) given a specific RNG. + * If max == 0, returns 0. + */ + template > + static uint32_t rand32(uint32_t max, RNG&& rng) { + return rand32(0, max, rng); } /** * Returns a random uint32_t in [min, max). If min == max, returns 0. */ - template - static uint32_t rand32(uint32_t min, - uint32_t max, - ValidRNG rng = RNG()) { + static uint32_t rand32(uint32_t min, uint32_t max) { + return rand32(min, max, ThreadLocalPRNG()); + } + + /** + * Returns a random uint32_t in [min, max) given a specific RNG. + * If min == max, returns 0. + */ + template > + static uint32_t rand32(uint32_t min, uint32_t max, RNG&& rng) { if (min == max) { return 0; } - return std::uniform_int_distribution(min, max - 1)(rng); } /** * Returns a random uint64_t */ - template - static uint64_t rand64(ValidRNG rng = RNG()) { - return ((uint64_t) rng() << 32) | rng(); + static uint64_t rand64() { + return rand64(ThreadLocalPRNG()); + } + + /** + * Returns a random uint64_t + */ + template > + static uint64_t rand64(RNG&& rng) { + return ((uint64_t)rng() << 32) | rng(); } /** * Returns a random uint64_t in [0, max). If max == 0, returns 0. */ - template - static uint64_t rand64(uint64_t max, ValidRNG rng = RNG()) { - if (max == 0) { - return 0; - } + static uint64_t rand64(uint64_t max) { + return rand64(0, max, ThreadLocalPRNG()); + } - return std::uniform_int_distribution(0, max - 1)(rng); + /** + * Returns a random uint64_t in [0, max). If max == 0, returns 0. + */ + template > + static uint64_t rand64(uint64_t max, RNG&& rng) { + return rand64(0, max, rng); + } + + /** + * Returns a random uint64_t in [min, max). If min == max, returns 0. + */ + static uint64_t rand64(uint64_t min, uint64_t max) { + return rand64(min, max, ThreadLocalPRNG()); } /** * Returns a random uint64_t in [min, max). If min == max, returns 0. */ - template - static uint64_t rand64(uint64_t min, - uint64_t max, - ValidRNG rng = RNG()) { + template > + static uint64_t rand64(uint64_t min, uint64_t max, RNG&& rng) { if (min == max) { return 0; } - return std::uniform_int_distribution(min, max - 1)(rng); } /** * Returns true 1/n of the time. If n == 0, always returns false */ - template - static bool oneIn(uint32_t n, ValidRNG rng = RNG()) { + static bool oneIn(uint32_t n) { + return oneIn(n, ThreadLocalPRNG()); + } + + /** + * Returns true 1/n of the time. If n == 0, always returns false + */ + template > + static bool oneIn(uint32_t n, RNG&& rng) { if (n == 0) { return false; } + return rand32(0, n, rng) == 0; + } - return rand32(n, rng) == 0; + /** + * Returns a double in [0, 1) + */ + static double randDouble01() { + return randDouble01(ThreadLocalPRNG()); } /** * Returns a double in [0, 1) */ - template - static double randDouble01(ValidRNG rng = RNG()) { - return std::generate_canonical::digits> - (rng); + template > + static double randDouble01(RNG&& rng) { + return std::generate_canonical::digits>( + rng); + } + + /** + * Returns a double in [min, max), if min == max, returns 0. + */ + static double randDouble(double min, double max) { + return randDouble(min, max, ThreadLocalPRNG()); } /** * Returns a double in [min, max), if min == max, returns 0. */ - template - static double randDouble(double min, double max, ValidRNG rng = RNG()) { + template > + static double randDouble(double min, double max, RNG&& rng) { if (std::fabs(max - min) < std::numeric_limits::epsilon()) { return 0; } @@ -245,5 +294,3 @@ inline uint32_t randomNumberSeed() { } #include - -#endif