+ // Default generator type.
+#if FOLLY_HAVE_EXTRANDOM_SFMT19937
+ typedef __gnu_cxx::sfmt19937 DefaultGenerator;
+#else
+ typedef std::mt19937 DefaultGenerator;
+#endif
+
+ /**
+ * Get secure random bytes. (On Linux and OSX, this means /dev/urandom).
+ */
+ static void secureRandom(void* data, size_t len);
+
+ /**
+ * Shortcut to get a secure random value of integral type.
+ */
+ template <class T>
+ static typename std::enable_if<
+ std::is_integral<T>::value && !std::is_same<T,bool>::value,
+ T>::type
+ secureRandom() {
+ T val;
+ secureRandom(&val, sizeof(val));
+ return val;
+ }
+
+ /**
+ * (Re-)Seed an existing RNG with a good seed.
+ *
+ * Note that you should usually use ThreadLocalPRNG unless you need
+ * reproducibility (such as during a test), in which case you'd want
+ * to create a RNG with a good seed in production, and seed it yourself
+ * in test.
+ */
+ template <class RNG = DefaultGenerator, class /* EnableIf */ = ValidRNG<RNG>>
+ static void seed(RNG& rng);
+
+ /**
+ * Create a new RNG, seeded with a good seed.
+ *
+ * Note that you should usually use ThreadLocalPRNG unless you need
+ * reproducibility (such as during a test), in which case you'd want
+ * to create a RNG with a good seed in production, and seed it yourself
+ * in test.
+ */
+ template <class RNG = DefaultGenerator, class /* EnableIf */ = ValidRNG<RNG>>
+ static RNG create();