summaryrefslogtreecommitdiff
path: root/absl/random
diff options
context:
space:
mode:
Diffstat (limited to 'absl/random')
-rw-r--r--absl/random/BUILD.bazel5
-rw-r--r--absl/random/CMakeLists.txt7
-rw-r--r--absl/random/beta_distribution_test.cc40
-rw-r--r--absl/random/exponential_distribution_test.cc32
-rw-r--r--absl/random/gaussian_distribution_test.cc38
-rw-r--r--absl/random/internal/BUILD.bazel27
-rw-r--r--absl/random/internal/explicit_seed_seq.h3
-rw-r--r--absl/random/internal/fastmath.h23
-rw-r--r--absl/random/internal/fastmath_test.cc13
-rw-r--r--absl/random/internal/generate_real.h4
-rw-r--r--absl/random/internal/generate_real_test.cc9
-rw-r--r--absl/random/internal/iostream_state_saver_test.cc5
-rw-r--r--absl/random/internal/mock_helpers.h19
-rw-r--r--absl/random/internal/mock_overload_set.h19
-rw-r--r--absl/random/internal/pcg_engine.h7
-rw-r--r--absl/random/internal/randen.cc2
-rw-r--r--absl/random/internal/randen.h2
-rw-r--r--absl/random/internal/randen_detect.cc4
-rw-r--r--absl/random/internal/randen_engine.h8
-rw-r--r--absl/random/internal/randen_hwaes.h2
-rw-r--r--absl/random/internal/randen_slow.h2
-rw-r--r--absl/random/internal/randen_slow_test.cc3
-rw-r--r--absl/random/internal/randen_traits.h2
-rw-r--r--absl/random/internal/wide_multiply.h2
-rw-r--r--absl/random/internal/wide_multiply_test.cc1
-rw-r--r--absl/random/log_uniform_int_distribution.h7
-rw-r--r--absl/random/mocking_bit_gen.h104
-rw-r--r--absl/random/mocking_bit_gen_test.cc45
-rw-r--r--absl/random/uniform_int_distribution.h2
-rw-r--r--absl/random/uniform_real_distribution_test.cc16
30 files changed, 239 insertions, 214 deletions
diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel
index 81e150e6..66ffcbc7 100644
--- a/absl/random/BUILD.bazel
+++ b/absl/random/BUILD.bazel
@@ -69,6 +69,7 @@ cc_library(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
+ "//absl/numeric:bits",
"//absl/random/internal:distribution_caller",
"//absl/random/internal:fast_uniform_bits",
"//absl/random/internal:fastmath",
@@ -187,6 +188,7 @@ cc_test(
":distributions",
":random",
"//absl/base:raw_logging_internal",
+ "//absl/numeric:representation",
"//absl/random/internal:distribution_test_util",
"//absl/random/internal:pcg_engine",
"//absl/random/internal:sequence_urbg",
@@ -307,6 +309,7 @@ cc_test(
":random",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
+ "//absl/numeric:representation",
"//absl/random/internal:distribution_test_util",
"//absl/random/internal:pcg_engine",
"//absl/random/internal:sequence_urbg",
@@ -330,6 +333,7 @@ cc_test(
":random",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
+ "//absl/numeric:representation",
"//absl/random/internal:distribution_test_util",
"//absl/random/internal:sequence_urbg",
"//absl/strings",
@@ -376,6 +380,7 @@ cc_test(
":distributions",
":random",
"//absl/base:raw_logging_internal",
+ "//absl/numeric:representation",
"//absl/random/internal:distribution_test_util",
"//absl/random/internal:pcg_engine",
"//absl/random/internal:sequence_urbg",
diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt
index 7d7bec83..3009a034 100644
--- a/absl/random/CMakeLists.txt
+++ b/absl/random/CMakeLists.txt
@@ -259,6 +259,7 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::numeric_representation
absl::random_distributions
absl::random_random
absl::random_internal_distribution_test_util
@@ -381,6 +382,7 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::core_headers
+ absl::numeric_representation
absl::random_distributions
absl::random_internal_distribution_test_util
absl::random_internal_pcg_engine
@@ -404,6 +406,7 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::core_headers
+ absl::numeric_representation
absl::random_distributions
absl::random_internal_distribution_test_util
absl::random_internal_sequence_urbg
@@ -446,6 +449,7 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::numeric_representation
absl::random_distributions
absl::random_internal_distribution_test_util
absl::random_internal_pcg_engine
@@ -611,6 +615,7 @@ absl_cc_library(
${ABSL_DEFAULT_LINKOPTS}
DEPS
absl::config
+ absl::endian
TESTONLY
)
@@ -758,6 +763,7 @@ absl_cc_library(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::endian
absl::random_internal_iostream_state_saver
absl::random_internal_randen
absl::raw_logging_internal
@@ -1119,6 +1125,7 @@ absl_cc_test(
LINKOPTS
${ABSL_DEFAULT_LINKOPTS}
DEPS
+ absl::endian
absl::random_internal_randen_slow
gtest_main
)
diff --git a/absl/random/beta_distribution_test.cc b/absl/random/beta_distribution_test.cc
index 277e4dc6..44cdfdd0 100644
--- a/absl/random/beta_distribution_test.cc
+++ b/absl/random/beta_distribution_test.cc
@@ -21,12 +21,14 @@
#include <random>
#include <sstream>
#include <string>
+#include <type_traits>
#include <unordered_map>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/numeric/internal/representation.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/distribution_test_util.h"
#include "absl/random/internal/pcg_engine.h"
@@ -42,7 +44,15 @@ namespace {
template <typename IntType>
class BetaDistributionInterfaceTest : public ::testing::Test {};
-using RealTypes = ::testing::Types<float, double, long double>;
+// double-double arithmetic is not supported well by either GCC or Clang; see
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
+// https://bugs.llvm.org/show_bug.cgi?id=49131, and
+// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
+// with double doubles until compiler support is better.
+using RealTypes =
+ std::conditional<absl::numeric_internal::IsDoubleDouble(),
+ ::testing::Types<float, double>,
+ ::testing::Types<float, double, long double>>::type;
TYPED_TEST_CASE(BetaDistributionInterfaceTest, RealTypes);
TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
@@ -53,9 +63,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
const TypeParam kLargeA =
std::exp(std::log((std::numeric_limits<TypeParam>::max)()) -
std::log(std::log((std::numeric_limits<TypeParam>::max)())));
- const TypeParam kLargeAPPC = std::exp(
- std::log((std::numeric_limits<TypeParam>::max)()) -
- std::log(std::log((std::numeric_limits<TypeParam>::max)())) - 10.0f);
using param_type = typename absl::beta_distribution<TypeParam>::param_type;
constexpr int kCount = 1000;
@@ -76,9 +83,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
kLargeA, //
std::nextafter(kLargeA, TypeParam(0)), //
std::nextafter(kLargeA, std::numeric_limits<TypeParam>::max()),
- kLargeAPPC, //
- std::nextafter(kLargeAPPC, TypeParam(0)),
- std::nextafter(kLargeAPPC, std::numeric_limits<TypeParam>::max()),
// Boundary cases.
std::numeric_limits<TypeParam>::max(),
std::numeric_limits<TypeParam>::epsilon(),
@@ -125,28 +129,6 @@ TYPED_TEST(BetaDistributionInterfaceTest, SerializeTest) {
ss >> after;
-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
- defined(__ppc__) || defined(__PPC__)
- if (std::is_same<TypeParam, long double>::value) {
- // Roundtripping floating point values requires sufficient precision
- // to reconstruct the exact value. It turns out that long double
- // has some errors doing this on ppc.
- if (alpha <= std::numeric_limits<double>::max() &&
- alpha >= std::numeric_limits<double>::lowest()) {
- EXPECT_EQ(static_cast<double>(before.alpha()),
- static_cast<double>(after.alpha()))
- << ss.str();
- }
- if (beta <= std::numeric_limits<double>::max() &&
- beta >= std::numeric_limits<double>::lowest()) {
- EXPECT_EQ(static_cast<double>(before.beta()),
- static_cast<double>(after.beta()))
- << ss.str();
- }
- continue;
- }
-#endif
-
EXPECT_EQ(before.alpha(), after.alpha());
EXPECT_EQ(before.beta(), after.beta());
EXPECT_EQ(before, after) //
diff --git a/absl/random/exponential_distribution_test.cc b/absl/random/exponential_distribution_test.cc
index 8e9e69b6..af11d61c 100644
--- a/absl/random/exponential_distribution_test.cc
+++ b/absl/random/exponential_distribution_test.cc
@@ -30,6 +30,7 @@
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
+#include "absl/numeric/internal/representation.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/distribution_test_util.h"
#include "absl/random/internal/pcg_engine.h"
@@ -47,11 +48,15 @@ using absl::random_internal::kChiSquared;
template <typename RealType>
class ExponentialDistributionTypedTest : public ::testing::Test {};
-#if defined(__EMSCRIPTEN__)
-using RealTypes = ::testing::Types<float, double>;
-#else
-using RealTypes = ::testing::Types<float, double, long double>;
-#endif // defined(__EMSCRIPTEN__)
+// double-double arithmetic is not supported well by either GCC or Clang; see
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
+// https://bugs.llvm.org/show_bug.cgi?id=49131, and
+// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
+// with double doubles until compiler support is better.
+using RealTypes =
+ std::conditional<absl::numeric_internal::IsDoubleDouble(),
+ ::testing::Types<float, double>,
+ ::testing::Types<float, double, long double>>::type;
TYPED_TEST_CASE(ExponentialDistributionTypedTest, RealTypes);
TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) {
@@ -130,23 +135,6 @@ TYPED_TEST(ExponentialDistributionTypedTest, SerializeTest) {
ss >> after;
-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
- defined(__ppc__) || defined(__PPC__)
- if (std::is_same<TypeParam, long double>::value) {
- // Roundtripping floating point values requires sufficient precision to
- // reconstruct the exact value. It turns out that long double has some
- // errors doing this on ppc, particularly for values
- // near {1.0 +/- epsilon}.
- if (lambda <= std::numeric_limits<double>::max() &&
- lambda >= std::numeric_limits<double>::lowest()) {
- EXPECT_EQ(static_cast<double>(before.lambda()),
- static_cast<double>(after.lambda()))
- << ss.str();
- }
- continue;
- }
-#endif
-
EXPECT_EQ(before.lambda(), after.lambda()) //
<< ss.str() << " " //
<< (ss.good() ? "good " : "") //
diff --git a/absl/random/gaussian_distribution_test.cc b/absl/random/gaussian_distribution_test.cc
index 02ac578a..c0bac2b0 100644
--- a/absl/random/gaussian_distribution_test.cc
+++ b/absl/random/gaussian_distribution_test.cc
@@ -21,12 +21,14 @@
#include <iterator>
#include <random>
#include <string>
+#include <type_traits>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
+#include "absl/numeric/internal/representation.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/distribution_test_util.h"
#include "absl/random/internal/sequence_urbg.h"
@@ -43,7 +45,15 @@ using absl::random_internal::kChiSquared;
template <typename RealType>
class GaussianDistributionInterfaceTest : public ::testing::Test {};
-using RealTypes = ::testing::Types<float, double, long double>;
+// double-double arithmetic is not supported well by either GCC or Clang; see
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
+// https://bugs.llvm.org/show_bug.cgi?id=49131, and
+// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
+// with double doubles until compiler support is better.
+using RealTypes =
+ std::conditional<absl::numeric_internal::IsDoubleDouble(),
+ ::testing::Types<float, double>,
+ ::testing::Types<float, double, long double>>::type;
TYPED_TEST_CASE(GaussianDistributionInterfaceTest, RealTypes);
TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
@@ -129,32 +139,6 @@ TYPED_TEST(GaussianDistributionInterfaceTest, SerializeTest) {
ss >> after;
-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
- defined(__ppc__) || defined(__PPC__) || defined(__EMSCRIPTEN__)
- if (std::is_same<TypeParam, long double>::value) {
- // Roundtripping floating point values requires sufficient precision
- // to reconstruct the exact value. It turns out that long double
- // has some errors doing this on ppc, particularly for values
- // near {1.0 +/- epsilon}.
- //
- // Emscripten is even worse, implementing long double as a 128-bit
- // type, but shipping with a strtold() that doesn't support that.
- if (mean <= std::numeric_limits<double>::max() &&
- mean >= std::numeric_limits<double>::lowest()) {
- EXPECT_EQ(static_cast<double>(before.mean()),
- static_cast<double>(after.mean()))
- << ss.str();
- }
- if (stddev <= std::numeric_limits<double>::max() &&
- stddev >= std::numeric_limits<double>::lowest()) {
- EXPECT_EQ(static_cast<double>(before.stddev()),
- static_cast<double>(after.stddev()))
- << ss.str();
- }
- continue;
- }
-#endif
-
EXPECT_EQ(before.mean(), after.mean());
EXPECT_EQ(before.stddev(), after.stddev()) //
<< ss.str() << " " //
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel
index 8485e28b..612b1505 100644
--- a/absl/random/internal/BUILD.bazel
+++ b/absl/random/internal/BUILD.bazel
@@ -75,7 +75,8 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS + select({
- "//absl:windows": ["-DEFAULTLIB:bcrypt.lib"],
+ "//absl:msvc_compiler": ["-DEFAULTLIB:bcrypt.lib"],
+ "//absl:clang-cl_compiler": ["-DEFAULTLIB:bcrypt.lib"],
"//conditions:default": [],
}),
deps = [
@@ -98,7 +99,8 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = select({
- "//absl:windows": [],
+ "//absl:msvc_compiler": [],
+ "//absl:clang-cl_compiler": [],
"//absl:wasm": [],
"//conditions:default": ["-pthread"],
}) + ABSL_DEFAULT_LINKOPTS,
@@ -124,7 +126,10 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = ["//absl/base:config"],
+ deps = [
+ "//absl/base:config",
+ "//absl/base:endian",
+ ],
)
cc_library(
@@ -175,8 +180,8 @@ cc_library(
deps = [
":fastmath",
":traits",
- "//absl/base:bits",
"//absl/meta:type_traits",
+ "//absl/numeric:bits",
],
)
@@ -187,7 +192,7 @@ cc_library(
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
- deps = ["//absl/base:bits"],
+ deps = ["//absl/numeric:bits"],
)
cc_library(
@@ -197,8 +202,8 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":traits",
- "//absl/base:bits",
"//absl/base:config",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
],
)
@@ -229,6 +234,7 @@ cc_library(
":iostream_state_saver",
"//absl/base:config",
"//absl/meta:type_traits",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
],
)
@@ -241,6 +247,7 @@ cc_library(
deps = [
":iostream_state_saver",
":randen",
+ "//absl/base:endian",
"//absl/meta:type_traits",
],
)
@@ -320,7 +327,8 @@ cc_library(
"randen_hwaes.h",
],
copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({
- "//absl:windows": [],
+ "//absl:msvc_compiler": [],
+ "//absl:clang-cl_compiler": [],
"//conditions:default": ["-Wno-pass-failed"],
}),
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -400,8 +408,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":generate_real",
- "//absl/base:bits",
"//absl/flags:flag",
+ "//absl/numeric:bits",
"@com_google_googletest//:gtest_main",
],
)
@@ -605,6 +613,7 @@ cc_test(
deps = [
":platform",
":randen_slow",
+ "//absl/base:endian",
"@com_google_googletest//:gtest_main",
],
)
@@ -634,7 +643,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":wide_multiply",
- "//absl/base:bits",
+ "//absl/numeric:bits",
"//absl/numeric:int128",
"@com_google_googletest//:gtest_main",
],
diff --git a/absl/random/internal/explicit_seed_seq.h b/absl/random/internal/explicit_seed_seq.h
index 6a743eaf..e3aa31a1 100644
--- a/absl/random/internal/explicit_seed_seq.h
+++ b/absl/random/internal/explicit_seed_seq.h
@@ -23,6 +23,7 @@
#include <vector>
#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -73,7 +74,7 @@ class ExplicitSeedSeq {
template <typename OutIterator>
void generate(OutIterator begin, OutIterator end) {
for (size_t index = 0; begin != end; begin++) {
- *begin = state_.empty() ? 0 : state_[index++];
+ *begin = state_.empty() ? 0 : little_endian::FromHost32(state_[index++]);
if (index >= state_.size()) {
index = 0;
}
diff --git a/absl/random/internal/fastmath.h b/absl/random/internal/fastmath.h
index 6baeb5a7..963b7690 100644
--- a/absl/random/internal/fastmath.h
+++ b/absl/random/internal/fastmath.h
@@ -22,27 +22,22 @@
#include <cmath>
#include <cstdint>
-#include "absl/base/internal/bits.h"
+#include "absl/numeric/bits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// Returns the position of the first bit set.
-inline int LeadingSetBit(uint64_t n) {
- return 64 - base_internal::CountLeadingZeros64(n);
-}
-
// Compute log2(n) using integer operations.
// While std::log2 is more accurate than std::log(n) / std::log(2), for
// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2,
// for instance--std::log2 rounds up rather than down, which introduces
// definite skew in the results.
inline int IntLog2Floor(uint64_t n) {
- return (n <= 1) ? 0 : (63 - base_internal::CountLeadingZeros64(n));
+ return (n <= 1) ? 0 : (63 - countl_zero(n));
}
inline int IntLog2Ceil(uint64_t n) {
- return (n <= 1) ? 0 : (64 - base_internal::CountLeadingZeros64(n - 1));
+ return (n <= 1) ? 0 : (64 - countl_zero(n - 1));
}
inline double StirlingLogFactorial(double n) {
@@ -55,18 +50,6 @@ inline double StirlingLogFactorial(double n) {
(1.0 / 360.0) * ninv * ninv * ninv;
}
-// Rotate value right.
-//
-// We only implement the uint32_t / uint64_t versions because
-// 1) those are the only ones we use, and
-// 2) those are the only ones where clang detects the rotate idiom correctly.
-inline constexpr uint32_t rotr(uint32_t value, uint8_t bits) {
- return (value >> (bits & 31)) | (value << ((-bits) & 31));
-}
-inline constexpr uint64_t rotr(uint64_t value, uint8_t bits) {
- return (value >> (bits & 63)) | (value << ((-bits) & 63));
-}
-
} // namespace random_internal
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/absl/random/internal/fastmath_test.cc b/absl/random/internal/fastmath_test.cc
index 65859c25..0d6f9dc1 100644
--- a/absl/random/internal/fastmath_test.cc
+++ b/absl/random/internal/fastmath_test.cc
@@ -27,19 +27,6 @@
namespace {
-TEST(DistributionImplTest, LeadingSetBit) {
- using absl::random_internal::LeadingSetBit;
- constexpr uint64_t kZero = 0;
- EXPECT_EQ(0, LeadingSetBit(kZero));
- EXPECT_EQ(64, LeadingSetBit(~kZero));
-
- for (int index = 0; index < 64; index++) {
- uint64_t x = static_cast<uint64_t>(1) << index;
- EXPECT_EQ(index + 1, LeadingSetBit(x)) << index;
- EXPECT_EQ(index + 1, LeadingSetBit(x + x - 1)) << index;
- }
-}
-
TEST(FastMathTest, IntLog2FloorTest) {
using absl::random_internal::IntLog2Floor;
constexpr uint64_t kZero = 0;
diff --git a/absl/random/internal/generate_real.h b/absl/random/internal/generate_real.h
index 20f6d208..4f62873d 100644
--- a/absl/random/internal/generate_real.h
+++ b/absl/random/internal/generate_real.h
@@ -23,8 +23,8 @@
#include <limits>
#include <type_traits>
-#include "absl/base/internal/bits.h"
#include "absl/meta/type_traits.h"
+#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/traits.h"
@@ -120,7 +120,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
// Number of leading zeros is mapped to the exponent: 2^-clz
// bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
- int clz = base_internal::CountLeadingZeros64(bits);
+ int clz = countl_zero(bits);
bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits.
exp -= clz; // set the exponent.
bits >>= (63 - kExp);
diff --git a/absl/random/internal/generate_real_test.cc b/absl/random/internal/generate_real_test.cc
index aa02f0c2..b099dbf3 100644
--- a/absl/random/internal/generate_real_test.cc
+++ b/absl/random/internal/generate_real_test.cc
@@ -20,8 +20,8 @@
#include <string>
#include "gtest/gtest.h"
-#include "absl/base/internal/bits.h"
#include "absl/flags/flag.h"
+#include "absl/numeric/bits.h"
ABSL_FLAG(int64_t, absl_random_test_trials, 50000,
"Number of trials for the probability tests.");
@@ -413,14 +413,13 @@ TEST(GenerateRealTest, U64ToDoubleSignedTest) {
}
TEST(GenerateRealTest, ExhaustiveFloat) {
- using absl::base_internal::CountLeadingZeros64;
auto ToFloat = [](uint64_t a) {
return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
};
// Rely on RandU64ToFloat generating values from greatest to least when
- // supplied with uint64_t values from greatest (0xfff...) to least (0x0). Thus,
- // this algorithm stores the previous value, and if the new value is at
+ // supplied with uint64_t values from greatest (0xfff...) to least (0x0).
+ // Thus, this algorithm stores the previous value, and if the new value is at
// greater than or equal to the previous value, then there is a collision in
// the generation algorithm.
//
@@ -464,7 +463,7 @@ TEST(GenerateRealTest, ExhaustiveFloat) {
// Adjust decrement and check value based on how many leading 0
// bits are set in the current value.
- const int clz = CountLeadingZeros64(x);
+ const int clz = absl::countl_zero(x);
if (clz < kDig) {
dec <<= (kDig - clz);
chk = (~uint64_t(0)) >> (clz + 1);
diff --git a/absl/random/internal/iostream_state_saver_test.cc b/absl/random/internal/iostream_state_saver_test.cc
index 7bb8ad95..6e66266c 100644
--- a/absl/random/internal/iostream_state_saver_test.cc
+++ b/absl/random/internal/iostream_state_saver_test.cc
@@ -14,6 +14,9 @@
#include "absl/random/internal/iostream_state_saver.h"
+#include <errno.h>
+#include <stdio.h>
+
#include <sstream>
#include <string>
@@ -272,7 +275,6 @@ TEST(IOStreamStateSaver, RoundTripDoubles) {
}
}
-#if !defined(__EMSCRIPTEN__)
TEST(IOStreamStateSaver, RoundTripLongDoubles) {
// Technically, C++ only guarantees that long double is at least as large as a
// double. Practically it varies from 64-bits to 128-bits.
@@ -350,7 +352,6 @@ TEST(IOStreamStateSaver, RoundTripLongDoubles) {
}
}
}
-#endif // !defined(__EMSCRIPTEN__)
TEST(StrToDTest, DoubleMin) {
const char kV[] = "2.22507385850720138e-308";
diff --git a/absl/random/internal/mock_helpers.h b/absl/random/internal/mock_helpers.h
index 9af27ab3..9d6ab21e 100644
--- a/absl/random/internal/mock_helpers.h
+++ b/absl/random/internal/mock_helpers.h
@@ -80,6 +80,13 @@ class MockHelpers {
}
public:
+ // InvokeMock is private; this provides access for some specialized use cases.
+ template <typename URBG>
+ static inline bool PrivateInvokeMock(URBG* urbg, IdType type,
+ void* args_tuple, void* result) {
+ return urbg->InvokeMock(type, args_tuple, result);
+ }
+
// Invoke a mock for the KeyT (may or may not be a signature).
//
// KeyT is used to generate a typeid-based lookup key for the mock.
@@ -109,14 +116,14 @@ class MockHelpers {
// The mocked function signature will be composed from KeyT as:
// result_type(args...)
template <typename KeyT, typename MockURBG>
- static auto MockFor(MockURBG& m) -> decltype(
- std::declval<MockURBG>()
- .template RegisterMock<typename KeySignature<KeyT>::result_type,
- typename KeySignature<KeyT>::arg_tuple_type>(
- std::declval<IdType>())) {
+ static auto MockFor(MockURBG& m)
+ -> decltype(m.template RegisterMock<
+ typename KeySignature<KeyT>::result_type,
+ typename KeySignature<KeyT>::arg_tuple_type>(
+ m, std::declval<IdType>())) {
return m.template RegisterMock<typename KeySignature<KeyT>::result_type,
typename KeySignature<KeyT>::arg_tuple_type>(
- ::absl::base_internal::FastTypeId<KeyT>());
+ m, ::absl::base_internal::FastTypeId<KeyT>());
}
};
diff --git a/absl/random/internal/mock_overload_set.h b/absl/random/internal/mock_overload_set.h
index dccc6cee..0d9c6c12 100644
--- a/absl/random/internal/mock_overload_set.h
+++ b/absl/random/internal/mock_overload_set.h
@@ -19,7 +19,6 @@
#include <type_traits>
#include "gmock/gmock.h"
-#include "gtest/gtest.h"
#include "absl/random/internal/mock_helpers.h"
#include "absl/random/mocking_bit_gen.h"
@@ -45,10 +44,12 @@ struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> {
"Overload signature must have return type matching the "
"distribution result_type.");
using KeyT = Ret(DistrT, std::tuple<Args...>);
- auto gmock_Call(
- absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
- const ::testing::Matcher<Args>&... matchers)
+
+ template <typename MockURBG>
+ auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers)
-> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) {
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...);
}
};
@@ -59,12 +60,14 @@ struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> {
"Overload signature must have return type matching the "
"distribution result_type.");
using KeyT = Ret(DistrT, std::tuple<Arg, Args...>);
- auto gmock_Call(
- const ::testing::Matcher<Arg>& matcher,
- absl::MockingBitGen& gen, // NOLINT(google-runtime-references)
- const ::testing::Matcher<Args>&... matchers)
+
+ template <typename MockURBG>
+ auto gmock_Call(const ::testing::Matcher<Arg>& matcher, MockURBG& gen,
+ const ::testing::Matcher<Args>&... matchers)
-> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher,
matchers...)) {
+ static_assert(std::is_base_of<MockingBitGen, MockURBG>::value,
+ "Mocking requires an absl::MockingBitGen");
return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...);
}
};
diff --git a/absl/random/internal/pcg_engine.h b/absl/random/internal/pcg_engine.h
index 53c23fe1..8efaf2e0 100644
--- a/absl/random/internal/pcg_engine.h
+++ b/absl/random/internal/pcg_engine.h
@@ -19,6 +19,7 @@
#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
+#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/iostream_state_saver.h"
@@ -261,7 +262,7 @@ struct pcg_xsl_rr_128_64 {
uint64_t rotate = h >> 58u;
uint64_t s = Uint128Low64(state) ^ h;
#endif
- return random_internal::rotr(s, rotate);
+ return rotr(s, rotate);
}
};
@@ -281,8 +282,8 @@ struct pcg_xsh_rr_64_32 {
using state_type = uint64_t;
using result_type = uint32_t;
inline uint32_t operator()(uint64_t state) {
- return random_internal::rotr(
- static_cast<uint32_t>(((state >> 18) ^ state) >> 27), state >> 59);
+ return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
+ state >> 59);
}
};
diff --git a/absl/random/internal/randen.cc b/absl/random/internal/randen.cc
index 78a1e00c..c1bc0444 100644
--- a/absl/random/internal/randen.cc
+++ b/absl/random/internal/randen.cc
@@ -17,7 +17,7 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/random/internal/randen_detect.h"
-// RANDen = RANDom generator or beetroots in Swiss German.
+// RANDen = RANDom generator or beetroots in Swiss High German.
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
//
diff --git a/absl/random/internal/randen.h b/absl/random/internal/randen.h
index c2834aaf..9a3840b8 100644
--- a/absl/random/internal/randen.h
+++ b/absl/random/internal/randen.h
@@ -26,7 +26,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// RANDen = RANDom generator or beetroots in Swiss High German.
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
//
diff --git a/absl/random/internal/randen_detect.cc b/absl/random/internal/randen_detect.cc
index d63230c2..bbe7b965 100644
--- a/absl/random/internal/randen_detect.cc
+++ b/absl/random/internal/randen_detect.cc
@@ -1,13 +1,13 @@
// Copyright 2017 The Abseil Authors.
//
-// Licensed under the Apache License, Version 2.0 (the"License");
+// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an"AS IS" BASIS,
+// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
diff --git a/absl/random/internal/randen_engine.h b/absl/random/internal/randen_engine.h
index 6b337313..92bb8905 100644
--- a/absl/random/internal/randen_engine.h
+++ b/absl/random/internal/randen_engine.h
@@ -23,6 +23,7 @@
#include <limits>
#include <type_traits>
+#include "absl/base/internal/endian.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/iostream_state_saver.h"
#include "absl/random/internal/randen.h"
@@ -76,7 +77,7 @@ class alignas(16) randen_engine {
impl_.Generate(state_);
}
- return state_[next_++];
+ return little_endian::ToHost(state_[next_++]);
}
template <class SeedSequence>
@@ -181,7 +182,8 @@ class alignas(16) randen_engine {
// In the case that `elem` is `uint8_t`, it must be cast to something
// larger so that it prints as an integer rather than a character. For
// simplicity, apply the cast all circumstances.
- os << static_cast<numeric_type>(elem) << os.fill();
+ os << static_cast<numeric_type>(little_endian::FromHost(elem))
+ << os.fill();
}
os << engine.next_;
return os;
@@ -200,7 +202,7 @@ class alignas(16) randen_engine {
// necessary to read a wider type and then cast it to uint8_t.
numeric_type value;
is >> value;
- elem = static_cast<result_type>(value);
+ elem = little_endian::ToHost(static_cast<result_type>(value));
}
is >> next;
if (is.fail()) {
diff --git a/absl/random/internal/randen_hwaes.h b/absl/random/internal/randen_hwaes.h
index bce36b52..71a7f69f 100644
--- a/absl/random/internal/randen_hwaes.h
+++ b/absl/random/internal/randen_hwaes.h
@@ -26,7 +26,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// RANDen = RANDom generator or beetroots in Swiss High German.
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
//
diff --git a/absl/random/internal/randen_slow.h b/absl/random/internal/randen_slow.h
index b6f137eb..532c3a89 100644
--- a/absl/random/internal/randen_slow.h
+++ b/absl/random/internal/randen_slow.h
@@ -23,7 +23,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// RANDen = RANDom generator or beetroots in Swiss High German.
// RandenSlow implements the basic state manipulation methods for
// architectures lacking AES hardware acceleration intrinsics.
class RandenSlow {
diff --git a/absl/random/internal/randen_slow_test.cc b/absl/random/internal/randen_slow_test.cc
index 4a535837..4861ffa4 100644
--- a/absl/random/internal/randen_slow_test.cc
+++ b/absl/random/internal/randen_slow_test.cc
@@ -17,6 +17,7 @@
#include <cstring>
#include "gtest/gtest.h"
+#include "absl/base/internal/endian.h"
#include "absl/random/internal/randen_traits.h"
namespace {
@@ -56,7 +57,7 @@ TEST(RandenSlowTest, Default) {
uint64_t* id = d.state;
for (const auto& elem : kGolden) {
- EXPECT_EQ(elem, *id++);
+ EXPECT_EQ(absl::little_endian::FromHost64(elem), *id++);
}
}
diff --git a/absl/random/internal/randen_traits.h b/absl/random/internal/randen_traits.h
index 53caa936..120022c9 100644
--- a/absl/random/internal/randen_traits.h
+++ b/absl/random/internal/randen_traits.h
@@ -28,7 +28,7 @@ namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
-// RANDen = RANDom generator or beetroots in Swiss German.
+// RANDen = RANDom generator or beetroots in Swiss High German.
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
//
diff --git a/absl/random/internal/wide_multiply.h b/absl/random/internal/wide_multiply.h
index 0afcbe08..b6e6c4b6 100644
--- a/absl/random/internal/wide_multiply.h
+++ b/absl/random/internal/wide_multiply.h
@@ -26,7 +26,7 @@
#endif
#include "absl/base/config.h"
-#include "absl/base/internal/bits.h"
+#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/random/internal/traits.h"
diff --git a/absl/random/internal/wide_multiply_test.cc b/absl/random/internal/wide_multiply_test.cc
index ca8ce923..e276cb51 100644
--- a/absl/random/internal/wide_multiply_test.cc
+++ b/absl/random/internal/wide_multiply_test.cc
@@ -15,7 +15,6 @@
#include "absl/random/internal/wide_multiply.h"
#include "gtest/gtest.h"
-#include "absl/base/internal/bits.h"
#include "absl/numeric/int128.h"
using absl::random_internal::MultiplyU64ToU128;
diff --git a/absl/random/log_uniform_int_distribution.h b/absl/random/log_uniform_int_distribution.h
index 960816e2..43e10116 100644
--- a/absl/random/log_uniform_int_distribution.h
+++ b/absl/random/log_uniform_int_distribution.h
@@ -23,6 +23,7 @@
#include <ostream>
#include <type_traits>
+#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/generate_real.h"
#include "absl/random/internal/iostream_state_saver.h"
@@ -68,8 +69,10 @@ class log_uniform_int_distribution {
if (base_ == 2) {
// Determine where the first set bit is on range(), giving a log2(range)
// value which can be used to construct bounds.
- log_range_ = (std::min)(random_internal::LeadingSetBit(range()),
- std::numeric_limits<unsigned_type>::digits);
+ log_range_ =
+ (std::min)(bit_width(range()),
+ static_cast<unsigned_type>(
+ std::numeric_limits<unsigned_type>::digits));
} else {
// NOTE: Computing the logN(x) introduces error from 2 sources:
// 1. Conversion of int to double loses precision for values >=
diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h
index 6d2f2c83..7b2b80eb 100644
--- a/absl/random/mocking_bit_gen.h
+++ b/absl/random/mocking_bit_gen.h
@@ -104,10 +104,7 @@ class BitGenRef;
class MockingBitGen {
public:
MockingBitGen() = default;
-
- ~MockingBitGen() {
- for (const auto& del : deleters_) del();
- }
+ ~MockingBitGen() = default;
// URBG interface
using result_type = absl::BitGen::result_type;
@@ -117,14 +114,6 @@ class MockingBitGen {
result_type operator()() { return gen_(); }
private:
- using match_impl_fn = void (*)(void* mock_fn, void* t_erased_arg_tuple,
- void* t_erased_result);
-
- struct MockData {
- void* mock_fn = nullptr;
- match_impl_fn match_impl = nullptr;
- };
-
// GetMockFnType returns the testing::MockFunction for a result and tuple.
// This method only exists for type deduction and is otherwise unimplemented.
template <typename ResultT, typename... Args>
@@ -136,17 +125,46 @@ class MockingBitGen {
// NOTE: MockFnCaller is essentially equivalent to the lambda:
// [fn](auto... args) { return fn->Call(std::move(args)...)}
// however that fails to build on some supported platforms.
- template <typename ResultT, typename MockFnType, typename Tuple>
+ template <typename MockFnType, typename ResultT, typename Tuple>
struct MockFnCaller;
+
// specialization for std::tuple.
- template <typename ResultT, typename MockFnType, typename... Args>
- struct MockFnCaller<ResultT, MockFnType, std::tuple<Args...>> {
+ template <typename MockFnType, typename ResultT, typename... Args>
+ struct MockFnCaller<MockFnType, ResultT, std::tuple<Args...>> {
MockFnType* fn;
inline ResultT operator()(Args... args) {
return fn->Call(std::move(args)...);
}
};
+ // FunctionHolder owns a particular ::testing::MockFunction associated with
+ // a mocked type signature, and implement the type-erased Apply call, which
+ // applies type-erased arguments to the mock.
+ class FunctionHolder {
+ public:
+ virtual ~FunctionHolder() = default;
+
+ // Call is a dispatch function which converts the
+ // generic type-erased parameters into a specific mock invocation call.
+ virtual void Apply(/*ArgTupleT*/ void* args_tuple,
+ /*ResultT*/ void* result) = 0;
+ };
+
+ template <typename MockFnType, typename ResultT, typename ArgTupleT>
+ class FunctionHolderImpl final : public FunctionHolder {
+ public:
+ void Apply(void* args_tuple, void* result) override {
+ // Requires tuple_args to point to a ArgTupleT, which is a
+ // std::tuple<Args...> used to invoke the mock function. Requires result
+ // to point to a ResultT, which is the result of the call.
+ *static_cast<ResultT*>(result) =
+ absl::apply(MockFnCaller<MockFnType, ResultT, ArgTupleT>{&mock_fn_},
+ *static_cast<ArgTupleT*>(args_tuple));
+ }
+
+ MockFnType mock_fn_;
+ };
+
// MockingBitGen::RegisterMock
//
// RegisterMock<ResultT, ArgTupleT>(FastTypeIdType) is the main extension
@@ -157,37 +175,31 @@ class MockingBitGen {
//
// The returned MockFunction<...> type can be used to setup additional
// distribution parameters of the expectation.
- template <typename ResultT, typename ArgTupleT>
- auto RegisterMock(base_internal::FastTypeIdType type)
+ template <typename ResultT, typename ArgTupleT, typename SelfT>
+ auto RegisterMock(SelfT&, base_internal::FastTypeIdType type)
-> decltype(GetMockFnType(std::declval<ResultT>(),
std::declval<ArgTupleT>()))& {
- using MockFnType = decltype(
- GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>()));
+ using MockFnType = decltype(GetMockFnType(std::declval<ResultT>(),
+ std::declval<ArgTupleT>()));
+
+ using WrappedFnType = absl::conditional_t<
+ std::is_same<SelfT, ::testing::NiceMock<absl::MockingBitGen>>::value,
+ ::testing::NiceMock<MockFnType>,
+ absl::conditional_t<
+ std::is_same<SelfT,
+ ::testing::NaggyMock<absl::MockingBitGen>>::value,
+ ::testing::NaggyMock<MockFnType>,
+ absl::conditional_t<
+ std::is_same<SelfT,
+ ::testing::StrictMock<absl::MockingBitGen>>::value,
+ ::testing::StrictMock<MockFnType>, MockFnType>>>;
+
+ using ImplT = FunctionHolderImpl<WrappedFnType, ResultT, ArgTupleT>;
auto& mock = mocks_[type];
- if (!mock.mock_fn) {
- auto* mock_fn = new MockFnType;
- mock.mock_fn = mock_fn;
- mock.match_impl = &MatchImpl<ResultT, ArgTupleT>;
- deleters_.emplace_back([mock_fn] { delete mock_fn; });
+ if (!mock) {
+ mock = absl::make_unique<ImplT>();
}
- return *static_cast<MockFnType*>(mock.mock_fn);
- }
-
- // MockingBitGen::MatchImpl<> is a dispatch function which converts the
- // generic type-erased parameters into a specific mock invocation call.
- // Requires tuple_args to point to a ArgTupleT, which is a std::tuple<Args...>
- // used to invoke the mock function.
- // Requires result to point to a ResultT, which is the result of the call.
- template <typename ResultT, typename ArgTupleT>
- static void MatchImpl(/*MockFnType<ResultT, Args...>*/ void* mock_fn,
- /*ArgTupleT*/ void* args_tuple,
- /*ResultT*/ void* result) {
- using MockFnType = decltype(
- GetMockFnType(std::declval<ResultT>(), std::declval<ArgTupleT>()));
- *static_cast<ResultT*>(result) = absl::apply(
- MockFnCaller<ResultT, MockFnType, ArgTupleT>{
- static_cast<MockFnType*>(mock_fn)},
- *static_cast<ArgTupleT*>(args_tuple));
+ return static_cast<ImplT*>(mock.get())->mock_fn_;
}
// MockingBitGen::InvokeMock
@@ -206,13 +218,13 @@ class MockingBitGen {
// Trigger a mock, if there exists one that matches `param`.
auto it = mocks_.find(type);
if (it == mocks_.end()) return false;
- auto* mock_data = static_cast<MockData*>(&it->second);
- mock_data->match_impl(mock_data->mock_fn, args_tuple, result);
+ it->second->Apply(args_tuple, result);
return true;
}
- absl::flat_hash_map<base_internal::FastTypeIdType, MockData> mocks_;
- std::vector<std::function<void()>> deleters_;
+ absl::flat_hash_map<base_internal::FastTypeIdType,
+ std::unique_ptr<FunctionHolder>>
+ mocks_;
absl::BitGen gen_;
template <typename>
diff --git a/absl/random/mocking_bit_gen_test.cc b/absl/random/mocking_bit_gen_test.cc
index f0ffc9ac..f63b6e42 100644
--- a/absl/random/mocking_bit_gen_test.cc
+++ b/absl/random/mocking_bit_gen_test.cc
@@ -26,6 +26,8 @@
#include "absl/random/random.h"
namespace {
+
+using ::testing::_;
using ::testing::Ne;
using ::testing::Return;
@@ -344,4 +346,47 @@ TEST(MockingBitGen, InSequenceSucceedsInOrder) {
EXPECT_EQ(absl::Poisson<int>(gen, 2.0), 4);
}
+TEST(MockingBitGen, NiceMock) {
+ ::testing::NiceMock<absl::MockingBitGen> gen;
+ ON_CALL(absl::MockUniform<int>(), Call(gen, _, _)).WillByDefault(Return(145));
+
+ ON_CALL(absl::MockPoisson<int>(), Call(gen, _)).WillByDefault(Return(3));
+
+ EXPECT_EQ(absl::Uniform(gen, 1, 1000), 145);
+ EXPECT_EQ(absl::Uniform(gen, 10, 1000), 145);
+ EXPECT_EQ(absl::Uniform(gen, 100, 1000), 145);
+}
+
+TEST(MockingBitGen, NaggyMock) {
+ // This is difficult to test, as only the output matters, so just verify
+ // that ON_CALL can be installed. Anything else requires log inspection.
+ ::testing::NaggyMock<absl::MockingBitGen> gen;
+
+ ON_CALL(absl::MockUniform<int>(), Call(gen, _, _)).WillByDefault(Return(145));
+ ON_CALL(absl::MockPoisson<int>(), Call(gen, _)).WillByDefault(Return(3));
+
+ EXPECT_EQ(absl::Uniform(gen, 1, 1000), 145);
+}
+
+TEST(MockingBitGen, StrictMock_NotEnough) {
+ EXPECT_NONFATAL_FAILURE(
+ []() {
+ ::testing::StrictMock<absl::MockingBitGen> gen;
+ EXPECT_CALL(absl::MockUniform<int>(), Call(gen, _, _))
+ .WillOnce(Return(145));
+ }(),
+ "unsatisfied and active");
+}
+
+TEST(MockingBitGen, StrictMock_TooMany) {
+ ::testing::StrictMock<absl::MockingBitGen> gen;
+
+ EXPECT_CALL(absl::MockUniform<int>(), Call(gen, _, _)).WillOnce(Return(145));
+ EXPECT_EQ(absl::Uniform(gen, 1, 1000), 145);
+
+ EXPECT_NONFATAL_FAILURE(
+ [&]() { EXPECT_EQ(absl::Uniform(gen, 10, 1000), 0); }(),
+ "over-saturated and active");
+}
+
} // namespace
diff --git a/absl/random/uniform_int_distribution.h b/absl/random/uniform_int_distribution.h
index da66564a..c1f54cce 100644
--- a/absl/random/uniform_int_distribution.h
+++ b/absl/random/uniform_int_distribution.h
@@ -196,7 +196,7 @@ typename random_internal::make_unsigned_bits<IntType>::type
uniform_int_distribution<IntType>::Generate(
URBG& g, // NOLINT(runtime/references)
typename random_internal::make_unsigned_bits<IntType>::type R) {
- random_internal::FastUniformBits<unsigned_type> fast_bits;
+ random_internal::FastUniformBits<unsigned_type> fast_bits;
unsigned_type bits = fast_bits(g);
const unsigned_type Lim = R + 1;
if ((R & Lim) == 0) {
diff --git a/absl/random/uniform_real_distribution_test.cc b/absl/random/uniform_real_distribution_test.cc
index be107cdd..18bcd3bc 100644
--- a/absl/random/uniform_real_distribution_test.cc
+++ b/absl/random/uniform_real_distribution_test.cc
@@ -20,11 +20,13 @@
#include <random>
#include <sstream>
#include <string>
+#include <type_traits>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/numeric/internal/representation.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/distribution_test_util.h"
#include "absl/random/internal/pcg_engine.h"
@@ -55,11 +57,15 @@ namespace {
template <typename RealType>
class UniformRealDistributionTest : public ::testing::Test {};
-#if defined(__EMSCRIPTEN__)
-using RealTypes = ::testing::Types<float, double>;
-#else
-using RealTypes = ::testing::Types<float, double, long double>;
-#endif // defined(__EMSCRIPTEN__)
+// double-double arithmetic is not supported well by either GCC or Clang; see
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99048,
+// https://bugs.llvm.org/show_bug.cgi?id=49131, and
+// https://bugs.llvm.org/show_bug.cgi?id=49132. Don't bother running these tests
+// with double doubles until compiler support is better.
+using RealTypes =
+ std::conditional<absl::numeric_internal::IsDoubleDouble(),
+ ::testing::Types<float, double>,
+ ::testing::Types<float, double, long double>>::type;
TYPED_TEST_SUITE(UniformRealDistributionTest, RealTypes);