about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--absl/container/flat_hash_map_test.cc35
-rw-r--r--absl/container/internal/compressed_tuple_test.cc4
-rw-r--r--absl/hash/hash_test.cc5
-rw-r--r--absl/hash/internal/hash.h6
-rw-r--r--absl/random/BUILD.bazel1
-rw-r--r--absl/random/CMakeLists.txt2
-rw-r--r--absl/random/bit_gen_ref.h5
-rw-r--r--absl/random/distribution_format_traits.h278
-rw-r--r--absl/random/distributions.h41
-rw-r--r--absl/random/internal/BUILD.bazel1
-rw-r--r--absl/random/internal/distribution_caller.h18
-rw-r--r--absl/random/internal/mocking_bit_gen_base.h42
-rw-r--r--absl/random/mocking_bit_gen.cc1
-rw-r--r--absl/random/mocking_bit_gen.h6
-rw-r--r--absl/random/mocking_bit_gen_test.cc6
-rw-r--r--absl/strings/BUILD.bazel1
-rw-r--r--absl/strings/CMakeLists.txt1
-rw-r--r--absl/strings/numbers_test.cc1
-rwxr-xr-xci/cmake_install_test.sh2
-rwxr-xr-xci/linux_gcc-latest_libstdcxx_bazel.sh2
-rwxr-xr-xci/linux_gcc-latest_libstdcxx_cmake.sh2
-rwxr-xr-xci/macos_xcode_bazel.sh2
22 files changed, 386 insertions, 76 deletions
diff --git a/absl/container/flat_hash_map_test.cc b/absl/container/flat_hash_map_test.cc
index fd9c5604b1..728b693a07 100644
--- a/absl/container/flat_hash_map_test.cc
+++ b/absl/container/flat_hash_map_test.cc
@@ -253,41 +253,6 @@ TEST(FlatHashMap, EraseIf) {
   }
 }
 
-#if (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) && \
-    !defined(__EMSCRIPTEN__)
-TEST(FlatHashMap, Any) {
-  absl::flat_hash_map<int, absl::any> m;
-  m.emplace(1, 7);
-  auto it = m.find(1);
-  ASSERT_NE(it, m.end());
-  EXPECT_EQ(7, absl::any_cast<int>(it->second));
-
-  m.emplace(std::piecewise_construct, std::make_tuple(2), std::make_tuple(8));
-  it = m.find(2);
-  ASSERT_NE(it, m.end());
-  EXPECT_EQ(8, absl::any_cast<int>(it->second));
-
-  m.emplace(std::piecewise_construct, std::make_tuple(3),
-            std::make_tuple(absl::any(9)));
-  it = m.find(3);
-  ASSERT_NE(it, m.end());
-  EXPECT_EQ(9, absl::any_cast<int>(it->second));
-
-  struct H {
-    size_t operator()(const absl::any&) const { return 0; }
-  };
-  struct E {
-    bool operator()(const absl::any&, const absl::any&) const { return true; }
-  };
-  absl::flat_hash_map<absl::any, int, H, E> m2;
-  m2.emplace(1, 7);
-  auto it2 = m2.find(1);
-  ASSERT_NE(it2, m2.end());
-  EXPECT_EQ(7, it2->second);
-}
-#endif  // (defined(ABSL_USES_STD_ANY) || !defined(_LIBCPP_VERSION)) &&
-        // !defined(__EMSCRIPTEN__)
-
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/internal/compressed_tuple_test.cc b/absl/container/internal/compressed_tuple_test.cc
index 76bc92130e..1dae12db81 100644
--- a/absl/container/internal/compressed_tuple_test.cc
+++ b/absl/container/internal/compressed_tuple_test.cc
@@ -333,10 +333,6 @@ TEST(CompressedTupleTest, AnyElements) {
 
   a = 0.5f;
   EXPECT_EQ(absl::any_cast<float>(x.get<1>()), 0.5);
-
-  // Ensure copy construction work in the face of a type with a universal
-  // implicit constructor;
-  CompressedTuple<absl::any> c{}, d(c);  // NOLINT
 }
 
 TEST(CompressedTupleTest, Constexpr) {
diff --git a/absl/hash/hash_test.cc b/absl/hash/hash_test.cc
index 7a9d57f72b..f02a537ae8 100644
--- a/absl/hash/hash_test.cc
+++ b/absl/hash/hash_test.cc
@@ -460,7 +460,7 @@ struct DummyFooBar {
     const char* bar = "bar";
     h = H::combine_contiguous(std::move(h), foo, 3);
     h = H::combine_contiguous(std::move(h), bar, 3);
-    return std::move(h);
+    return h;
   }
 };
 
@@ -595,7 +595,10 @@ TEST(IsHashableTest, PoisonHash) {
   EXPECT_FALSE(absl::is_copy_assignable<absl::Hash<X>>::value);
   EXPECT_FALSE(absl::is_move_assignable<absl::Hash<X>>::value);
   EXPECT_FALSE(IsHashCallable<X>::value);
+#if !defined(__GNUC__) || __GNUC__ < 9
+  // This doesn't compile on GCC 9.
   EXPECT_FALSE(IsAggregateInitializable<absl::Hash<X>>::value);
+#endif
 }
 #endif  // ABSL_META_INTERNAL_STD_HASH_SFINAE_FRIENDLY_
 
diff --git a/absl/hash/internal/hash.h b/absl/hash/internal/hash.h
index 2564978a82..8639181f13 100644
--- a/absl/hash/internal/hash.h
+++ b/absl/hash/internal/hash.h
@@ -57,7 +57,7 @@ class PiecewiseCombiner;
 
 // Internal detail: Large buffers are hashed in smaller chunks.  This function
 // returns the size of these chunks.
-constexpr int PiecewiseChunkSize() { return 1024; }
+constexpr size_t PiecewiseChunkSize() { return 1024; }
 
 // HashStateBase
 //
@@ -951,7 +951,7 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data,
     // This partial chunk does not fill our existing buffer
     memcpy(buf_ + position_, data, size);
     position_ += size;
-    return std::move(state);
+    return state;
   }
 
   // Complete the buffer and hash it
@@ -970,7 +970,7 @@ H PiecewiseCombiner::add_buffer(H state, const unsigned char* data,
   // Fill the buffer with the remainder
   memcpy(buf_, data, size);
   position_ = size;
-  return std::move(state);
+  return state;
 }
 
 // HashStateBase::PiecewiseCombiner::finalize()
diff --git a/absl/random/BUILD.bazel b/absl/random/BUILD.bazel
index 43ed9840a0..2585b39742 100644
--- a/absl/random/BUILD.bazel
+++ b/absl/random/BUILD.bazel
@@ -53,6 +53,7 @@ cc_library(
         "bernoulli_distribution.h",
         "beta_distribution.h",
         "discrete_distribution.h",
+        "distribution_format_traits.h",
         "distributions.h",
         "exponential_distribution.h",
         "gaussian_distribution.h",
diff --git a/absl/random/CMakeLists.txt b/absl/random/CMakeLists.txt
index 53f1aa5c77..46dbc3efbc 100644
--- a/absl/random/CMakeLists.txt
+++ b/absl/random/CMakeLists.txt
@@ -78,6 +78,7 @@ absl_cc_library(
     ${ABSL_DEFAULT_LINKOPTS}
   DEPS
     absl::random_random
+    absl::strings
 )
 
 # Internal-only target, do not depend on directly.
@@ -167,6 +168,7 @@ absl_cc_library(
     "bernoulli_distribution.h"
     "beta_distribution.h"
     "discrete_distribution.h"
+    "distribution_format_traits.h"
     "distributions.h"
     "exponential_distribution.h"
     "gaussian_distribution.h"
diff --git a/absl/random/bit_gen_ref.h b/absl/random/bit_gen_ref.h
index 59591a479d..e8771162e5 100644
--- a/absl/random/bit_gen_ref.h
+++ b/absl/random/bit_gen_ref.h
@@ -132,7 +132,7 @@ namespace random_internal {
 
 template <>
 struct DistributionCaller<absl::BitGenRef> {
-  template <typename DistrT, typename... Args>
+  template <typename DistrT, typename FormatT, typename... Args>
   static typename DistrT::result_type Call(absl::BitGenRef* gen_ref,
                                            Args&&... args) {
     auto* mock_ptr = gen_ref->mocked_gen_ptr_;
@@ -140,7 +140,8 @@ struct DistributionCaller<absl::BitGenRef> {
       DistrT dist(std::forward<Args>(args)...);
       return dist(*gen_ref);
     } else {
-      return mock_ptr->template Call<DistrT>(std::forward<Args>(args)...);
+      return mock_ptr->template Call<DistrT, FormatT>(
+          std::forward<Args>(args)...);
     }
   }
 };
diff --git a/absl/random/distribution_format_traits.h b/absl/random/distribution_format_traits.h
new file mode 100644
index 0000000000..22b358cc8c
--- /dev/null
+++ b/absl/random/distribution_format_traits.h
@@ -0,0 +1,278 @@
+//
+// Copyright 2018 The Abseil Authors.
+//
+// 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,
+// 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.
+//
+#ifndef ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_
+#define ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_
+
+#include <string>
+#include <tuple>
+#include <typeinfo>
+
+#include "absl/meta/type_traits.h"
+#include "absl/random/bernoulli_distribution.h"
+#include "absl/random/beta_distribution.h"
+#include "absl/random/exponential_distribution.h"
+#include "absl/random/gaussian_distribution.h"
+#include "absl/random/log_uniform_int_distribution.h"
+#include "absl/random/poisson_distribution.h"
+#include "absl/random/uniform_int_distribution.h"
+#include "absl/random/uniform_real_distribution.h"
+#include "absl/random/zipf_distribution.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_join.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+
+struct IntervalClosedClosedTag;
+struct IntervalClosedOpenTag;
+struct IntervalOpenClosedTag;
+struct IntervalOpenOpenTag;
+
+namespace random_internal {
+
+// ScalarTypeName defines a preferred hierarchy of preferred type names for
+// scalars, and is evaluated at compile time for the specific type
+// specialization.
+template <typename T>
+constexpr const char* ScalarTypeName() {
+  static_assert(std::is_integral<T>() || std::is_floating_point<T>(), "");
+  // clang-format off
+    return
+        std::is_same<T, float>::value ? "float" :
+        std::is_same<T, double>::value ? "double" :
+        std::is_same<T, long double>::value ? "long double" :
+        std::is_same<T, bool>::value ? "bool" :
+        std::is_signed<T>::value && sizeof(T) == 1 ? "int8_t" :
+        std::is_signed<T>::value && sizeof(T) == 2 ? "int16_t" :
+        std::is_signed<T>::value && sizeof(T) == 4 ? "int32_t" :
+        std::is_signed<T>::value && sizeof(T) == 8 ? "int64_t" :
+        std::is_unsigned<T>::value && sizeof(T) == 1 ? "uint8_t" :
+        std::is_unsigned<T>::value && sizeof(T) == 2 ? "uint16_t" :
+        std::is_unsigned<T>::value && sizeof(T) == 4 ? "uint32_t" :
+        std::is_unsigned<T>::value && sizeof(T) == 8 ? "uint64_t" :
+            "undefined";
+  // clang-format on
+
+  // NOTE: It would be nice to use typeid(T).name(), but that's an
+  // implementation-defined attribute which does not necessarily
+  // correspond to a name. We could potentially demangle it
+  // using, e.g. abi::__cxa_demangle.
+}
+
+// Distribution traits used by DistributionCaller and internal implementation
+// details of the mocking framework.
+/*
+struct DistributionFormatTraits {
+   // Returns the parameterized name of the distribution function.
+   static constexpr const char* FunctionName()
+   // Format DistrT parameters.
+   static std::string FormatArgs(DistrT& dist);
+   // Format DistrT::result_type results.
+   static std::string FormatResults(DistrT& dist);
+};
+*/
+template <typename DistrT>
+struct DistributionFormatTraits;
+
+template <typename R>
+struct DistributionFormatTraits<absl::uniform_int_distribution<R>> {
+  using distribution_t = absl::uniform_int_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Uniform"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat("absl::IntervalClosedClosed, ", (d.min)(), ", ",
+                        (d.max)());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::uniform_real_distribution<R>> {
+  using distribution_t = absl::uniform_real_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Uniform"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat((d.min)(), ", ", (d.max)());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::exponential_distribution<R>> {
+  using distribution_t = absl::exponential_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Exponential"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat(d.lambda());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::poisson_distribution<R>> {
+  using distribution_t = absl::poisson_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Poisson"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat(d.mean());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <>
+struct DistributionFormatTraits<absl::bernoulli_distribution> {
+  using distribution_t = absl::bernoulli_distribution;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Bernoulli"; }
+
+  static constexpr const char* FunctionName() { return Name(); }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat(d.p());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::beta_distribution<R>> {
+  using distribution_t = absl::beta_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Beta"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat(d.alpha(), ", ", d.beta());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::zipf_distribution<R>> {
+  using distribution_t = absl::zipf_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Zipf"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat(d.k(), ", ", d.v(), ", ", d.q());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::gaussian_distribution<R>> {
+  using distribution_t = absl::gaussian_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "Gaussian"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrJoin(std::make_tuple(d.mean(), d.stddev()), ", ");
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename R>
+struct DistributionFormatTraits<absl::log_uniform_int_distribution<R>> {
+  using distribution_t = absl::log_uniform_int_distribution<R>;
+  using result_t = typename distribution_t::result_type;
+
+  static constexpr const char* Name() { return "LogUniform"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<R>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrJoin(std::make_tuple((d.min)(), (d.max)(), d.base()), ", ");
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+template <typename NumType>
+struct UniformDistributionWrapper;
+
+template <typename NumType>
+struct DistributionFormatTraits<UniformDistributionWrapper<NumType>> {
+  using distribution_t = UniformDistributionWrapper<NumType>;
+  using result_t = NumType;
+
+  static constexpr const char* Name() { return "Uniform"; }
+
+  static std::string FunctionName() {
+    return absl::StrCat(Name(), "<", ScalarTypeName<NumType>(), ">");
+  }
+  static std::string FormatArgs(const distribution_t& d) {
+    return absl::StrCat((d.min)(), ", ", (d.max)());
+  }
+  static std::string FormatResults(absl::Span<const result_t> results) {
+    return absl::StrJoin(results, ", ");
+  }
+};
+
+}  // namespace random_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_RANDOM_DISTRIBUTION_FORMAT_TRAITS_H_
diff --git a/absl/random/distributions.h b/absl/random/distributions.h
index 7abdfa8f20..c1fb665015 100644
--- a/absl/random/distributions.h
+++ b/absl/random/distributions.h
@@ -55,6 +55,7 @@
 #include "absl/base/internal/inline_variable.h"
 #include "absl/random/bernoulli_distribution.h"
 #include "absl/random/beta_distribution.h"
+#include "absl/random/distribution_format_traits.h"
 #include "absl/random/exponential_distribution.h"
 #include "absl/random/gaussian_distribution.h"
 #include "absl/random/internal/distributions.h"  // IWYU pragma: export
@@ -125,13 +126,14 @@ Uniform(TagType tag,
         R lo, R hi) {
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = random_internal::UniformDistributionWrapper<R>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   auto a = random_internal::uniform_lower_bound(tag, lo, hi);
   auto b = random_internal::uniform_upper_bound(tag, lo, hi);
   if (a > b) return a;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, tag, lo, hi);
+      distribution_t, format_t>(&urbg, tag, lo, hi);
 }
 
 // absl::Uniform<T>(bitgen, lo, hi)
@@ -144,6 +146,7 @@ Uniform(URBG&& urbg,  // NOLINT(runtime/references)
         R lo, R hi) {
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = random_internal::UniformDistributionWrapper<R>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   constexpr auto tag = absl::IntervalClosedOpen;
   auto a = random_internal::uniform_lower_bound(tag, lo, hi);
@@ -151,7 +154,7 @@ Uniform(URBG&& urbg,  // NOLINT(runtime/references)
   if (a > b) return a;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, lo, hi);
+      distribution_t, format_t>(&urbg, lo, hi);
 }
 
 // absl::Uniform(tag, bitgen, lo, hi)
@@ -169,14 +172,15 @@ Uniform(TagType tag,
   using gen_t = absl::decay_t<URBG>;
   using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
   using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
   auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
   if (a > b) return a;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, tag, static_cast<return_t>(lo),
-                      static_cast<return_t>(hi));
+      distribution_t, format_t>(&urbg, tag, static_cast<return_t>(lo),
+                                static_cast<return_t>(hi));
 }
 
 // absl::Uniform(bitgen, lo, hi)
@@ -192,6 +196,7 @@ Uniform(URBG&& urbg,  // NOLINT(runtime/references)
   using gen_t = absl::decay_t<URBG>;
   using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
   using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   constexpr auto tag = absl::IntervalClosedOpen;
   auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
@@ -199,8 +204,8 @@ Uniform(URBG&& urbg,  // NOLINT(runtime/references)
   if (a > b) return a;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, static_cast<return_t>(lo),
-                      static_cast<return_t>(hi));
+      distribution_t, format_t>(&urbg, static_cast<return_t>(lo),
+                                static_cast<return_t>(hi));
 }
 
 // absl::Uniform<unsigned T>(bitgen)
@@ -212,9 +217,10 @@ typename absl::enable_if_t<!std::is_signed<R>::value, R>  //
 Uniform(URBG&& urbg) {  // NOLINT(runtime/references)
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = random_internal::UniformDistributionWrapper<R>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg);
+      distribution_t, format_t>(&urbg);
 }
 
 // -----------------------------------------------------------------------------
@@ -242,9 +248,10 @@ bool Bernoulli(URBG&& urbg,  // NOLINT(runtime/references)
                double p) {
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = absl::bernoulli_distribution;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, p);
+      distribution_t, format_t>(&urbg, p);
 }
 
 // -----------------------------------------------------------------------------
@@ -274,9 +281,10 @@ RealType Beta(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::beta_distribution<RealType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, alpha, beta);
+      distribution_t, format_t>(&urbg, alpha, beta);
 }
 
 // -----------------------------------------------------------------------------
@@ -306,9 +314,10 @@ RealType Exponential(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::exponential_distribution<RealType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, lambda);
+      distribution_t, format_t>(&urbg, lambda);
 }
 
 // -----------------------------------------------------------------------------
@@ -337,9 +346,10 @@ RealType Gaussian(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::gaussian_distribution<RealType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, mean, stddev);
+      distribution_t, format_t>(&urbg, mean, stddev);
 }
 
 // -----------------------------------------------------------------------------
@@ -379,9 +389,10 @@ IntType LogUniform(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::log_uniform_int_distribution<IntType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, lo, hi, base);
+      distribution_t, format_t>(&urbg, lo, hi, base);
 }
 
 // -----------------------------------------------------------------------------
@@ -409,9 +420,10 @@ IntType Poisson(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::poisson_distribution<IntType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, mean);
+      distribution_t, format_t>(&urbg, mean);
 }
 
 // -----------------------------------------------------------------------------
@@ -441,9 +453,10 @@ IntType Zipf(URBG&& urbg,  // NOLINT(runtime/references)
 
   using gen_t = absl::decay_t<URBG>;
   using distribution_t = typename absl::zipf_distribution<IntType>;
+  using format_t = random_internal::DistributionFormatTraits<distribution_t>;
 
   return random_internal::DistributionCaller<gen_t>::template Call<
-      distribution_t>(&urbg, hi, q, v);
+      distribution_t, format_t>(&urbg, hi, q, v);
 }
 
 ABSL_NAMESPACE_END
diff --git a/absl/random/internal/BUILD.bazel b/absl/random/internal/BUILD.bazel
index 8839078f5f..d7ad4efec9 100644
--- a/absl/random/internal/BUILD.bazel
+++ b/absl/random/internal/BUILD.bazel
@@ -509,6 +509,7 @@ cc_library(
     linkopts = ABSL_DEFAULT_LINKOPTS,
     deps = [
         "//absl/random",
+        "//absl/strings",
     ],
 )
 
diff --git a/absl/random/internal/distribution_caller.h b/absl/random/internal/distribution_caller.h
index ae2680ddd4..02603cf843 100644
--- a/absl/random/internal/distribution_caller.h
+++ b/absl/random/internal/distribution_caller.h
@@ -31,8 +31,22 @@ namespace random_internal {
 template <typename URBG>
 struct DistributionCaller {
   // Call the provided distribution type. The parameters are expected
-  // to be explicitly specified.  DistrT is the distribution type.
-  template <typename DistrT, typename... Args>
+  // to be explicitly specified.
+  // DistrT is the distribution type.
+  // FormatT is the formatter type:
+  //
+  // struct FormatT {
+  //   using result_type = distribution_t::result_type;
+  //   static std::string FormatCall(
+  //       const distribution_t& distr,
+  //       absl::Span<const result_type>);
+  //
+  //   static std::string FormatExpectation(
+  //       absl::string_view match_args,
+  //       absl::Span<const result_t> results);
+  // }
+  //
+  template <typename DistrT, typename FormatT, typename... Args>
   static typename DistrT::result_type Call(URBG* urbg, Args&&... args) {
     DistrT dist(std::forward<Args>(args)...);
     return dist(*urbg);
diff --git a/absl/random/internal/mocking_bit_gen_base.h b/absl/random/internal/mocking_bit_gen_base.h
index acd6387204..eeeae9d295 100644
--- a/absl/random/internal/mocking_bit_gen_base.h
+++ b/absl/random/internal/mocking_bit_gen_base.h
@@ -16,14 +16,39 @@
 #ifndef ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
 #define ABSL_RANDOM_INTERNAL_MOCKING_BIT_GEN_BASE_H_
 
+#include <atomic>
+#include <deque>
+#include <string>
 #include <typeinfo>
 
 #include "absl/random/random.h"
+#include "absl/strings/str_cat.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace random_internal {
 
+// MockingBitGenExpectationFormatter is invoked to format unsatisfied mocks
+// and remaining results into a description string.
+template <typename DistrT, typename FormatT>
+struct MockingBitGenExpectationFormatter {
+  std::string operator()(absl::string_view args) {
+    return absl::StrCat(FormatT::FunctionName(), "(", args, ")");
+  }
+};
+
+// MockingBitGenCallFormatter is invoked to format each distribution call
+// into a description string for the mock log.
+template <typename DistrT, typename FormatT>
+struct MockingBitGenCallFormatter {
+  std::string operator()(const DistrT& dist,
+                         const typename DistrT::result_type& result) {
+    return absl::StrCat(
+        FormatT::FunctionName(), "(", FormatT::FormatArgs(dist), ") => {",
+        FormatT::FormatResults(absl::MakeSpan(&result, 1)), "}");
+  }
+};
+
 class MockingBitGenBase {
   template <typename>
   friend struct DistributionCaller;
@@ -36,9 +61,14 @@ class MockingBitGenBase {
   static constexpr result_type(max)() { return (generator_type::max)(); }
   result_type operator()() { return gen_(); }
 
+  MockingBitGenBase() : gen_(), observed_call_log_() {}
   virtual ~MockingBitGenBase() = default;
 
  protected:
+  const std::deque<std::string>& observed_call_log() {
+    return observed_call_log_;
+  }
+
   // CallImpl is the type-erased virtual dispatch.
   // The type of dist is always distribution<T>,
   // The type of result is always distribution<T>::result_type.
@@ -51,9 +81,10 @@ class MockingBitGenBase {
   }
 
   // Call the generating distribution function.
-  // Invoked by DistributionCaller<>::Call<DistT>.
+  // Invoked by DistributionCaller<>::Call<DistT, FormatT>.
   // DistT is the distribution type.
-  template <typename DistrT, typename... Args>
+  // FormatT is the distribution formatter traits type.
+  template <typename DistrT, typename FormatT, typename... Args>
   typename DistrT::result_type Call(Args&&... args) {
     using distr_result_type = typename DistrT::result_type;
     using ArgTupleT = std::tuple<absl::decay_t<Args>...>;
@@ -68,11 +99,18 @@ class MockingBitGenBase {
     if (!found_match) {
       result = dist(gen_);
     }
+
+    // TODO(asoffer): Forwarding the args through means we no longer need to
+    // extract them from the from the distribution in formatter traits. We can
+    // just StrJoin them.
+    observed_call_log_.push_back(
+        MockingBitGenCallFormatter<DistrT, FormatT>{}(dist, result));
     return result;
   }
 
  private:
   generator_type gen_;
+  std::deque<std::string> observed_call_log_;
 };  // namespace random_internal
 
 }  // namespace random_internal
diff --git a/absl/random/mocking_bit_gen.cc b/absl/random/mocking_bit_gen.cc
index 0220911545..6bb1e414ae 100644
--- a/absl/random/mocking_bit_gen.cc
+++ b/absl/random/mocking_bit_gen.cc
@@ -20,6 +20,7 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 MockingBitGen::~MockingBitGen() {
+
   for (const auto& del : deleters_) {
     del();
   }
diff --git a/absl/random/mocking_bit_gen.h b/absl/random/mocking_bit_gen.h
index 246c5b1e03..36cef91113 100644
--- a/absl/random/mocking_bit_gen.h
+++ b/absl/random/mocking_bit_gen.h
@@ -109,7 +109,7 @@ class MockingBitGen : public absl::random_internal::MockingBitGenBase {
 
   // MockingBitGen::Register
   //
-  // Register<DistrT, ArgTupleT> is the main extension point for
+  // Register<DistrT, FormatT, ArgTupleT> is the main extension point for
   // extending the MockingBitGen framework. It provides a mechanism to install a
   // mock expectation for the distribution `distr_t` onto the MockingBitGen
   // context.
@@ -182,10 +182,10 @@ namespace random_internal {
 
 template <>
 struct DistributionCaller<absl::MockingBitGen> {
-  template <typename DistrT, typename... Args>
+  template <typename DistrT, typename FormatT, typename... Args>
   static typename DistrT::result_type Call(absl::MockingBitGen* gen,
                                            Args&&... args) {
-    return gen->template Call<DistrT>(std::forward<Args>(args)...);
+    return gen->template Call<DistrT, FormatT>(std::forward<Args>(args)...);
   }
 };
 
diff --git a/absl/random/mocking_bit_gen_test.cc b/absl/random/mocking_bit_gen_test.cc
index dcf74fd6db..f0ffc9ac92 100644
--- a/absl/random/mocking_bit_gen_test.cc
+++ b/absl/random/mocking_bit_gen_test.cc
@@ -66,10 +66,10 @@ TEST(BasicMocking, AllDistributionsAreOverridable) {
       .WillOnce(Return(0.001));
   EXPECT_EQ(absl::Gaussian<double>(gen, 0.0, 1.0), 0.001);
 
-  EXPECT_NE(absl::LogUniform<int>(gen, 0, 1000000, 2), 2040);
+  EXPECT_NE(absl::LogUniform<int>(gen, 0, 1000000, 2), 500000);
   EXPECT_CALL(absl::MockLogUniform<int>(), Call(gen, 0, 1000000, 2))
-      .WillOnce(Return(2040));
-  EXPECT_EQ(absl::LogUniform<int>(gen, 0, 1000000, 2), 2040);
+      .WillOnce(Return(500000));
+  EXPECT_EQ(absl::LogUniform<int>(gen, 0, 1000000, 2), 500000);
 }
 
 TEST(BasicMocking, OnDistribution) {
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index b5547f71d7..8d0a6b6d4e 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -412,7 +412,6 @@ cc_test(
     copts = ABSL_TEST_COPTS,
     visibility = ["//visibility:private"],
     deps = [
-        ":internal",
         ":pow10_helper",
         ":strings",
         "//absl/base:config",
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index 5366fb6589..98101573ac 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -275,7 +275,6 @@ absl_cc_test(
     ${ABSL_TEST_COPTS}
   DEPS
     absl::strings
-    absl::strings_internal
     absl::core_headers
     absl::pow10_helper
     absl::config
diff --git a/absl/strings/numbers_test.cc b/absl/strings/numbers_test.cc
index f66d9c36b0..68229b15a4 100644
--- a/absl/strings/numbers_test.cc
+++ b/absl/strings/numbers_test.cc
@@ -40,7 +40,6 @@
 #include "absl/random/distributions.h"
 #include "absl/random/random.h"
 #include "absl/strings/internal/numbers_test_common.h"
-#include "absl/strings/internal/ostringstream.h"
 #include "absl/strings/internal/pow10_helper.h"
 #include "absl/strings/str_cat.h"
 
diff --git a/ci/cmake_install_test.sh b/ci/cmake_install_test.sh
index e85474c20a..55fb4f120b 100755
--- a/ci/cmake_install_test.sh
+++ b/ci/cmake_install_test.sh
@@ -28,5 +28,5 @@ time docker run \
     --rm \
     -e CFLAGS="-Werror" \
     -e CXXFLAGS="-Werror" \
-    gcr.io/google.com/absl-177019/linux_gcc-latest:20200102 \
+    gcr.io/google.com/absl-177019/linux_gcc-latest:20200106 \
     /bin/bash CMake/install_test_project/test.sh $@
diff --git a/ci/linux_gcc-latest_libstdcxx_bazel.sh b/ci/linux_gcc-latest_libstdcxx_bazel.sh
index 70d24d79d6..2d41d511b1 100755
--- a/ci/linux_gcc-latest_libstdcxx_bazel.sh
+++ b/ci/linux_gcc-latest_libstdcxx_bazel.sh
@@ -36,7 +36,7 @@ if [ -z ${EXCEPTIONS_MODE:-} ]; then
   EXCEPTIONS_MODE="-fno-exceptions -fexceptions"
 fi
 
-readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200102"
+readonly DOCKER_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-latest:20200106"
 
 # USE_BAZEL_CACHE=1 only works on Kokoro.
 # Without access to the credentials this won't work.
diff --git a/ci/linux_gcc-latest_libstdcxx_cmake.sh b/ci/linux_gcc-latest_libstdcxx_cmake.sh
index 7effa0c09f..38ad99f7ef 100755
--- a/ci/linux_gcc-latest_libstdcxx_cmake.sh
+++ b/ci/linux_gcc-latest_libstdcxx_cmake.sh
@@ -47,7 +47,7 @@ for std in ${ABSL_CMAKE_CXX_STANDARDS}; do
       --rm \
       -e CFLAGS="-Werror" \
       -e CXXFLAGS="-Werror" \
-      gcr.io/google.com/absl-177019/linux_gcc-latest:20200102 \
+      gcr.io/google.com/absl-177019/linux_gcc-latest:20200106 \
       /bin/bash -c "
         cd /buildfs && \
         cmake /abseil-cpp \
diff --git a/ci/macos_xcode_bazel.sh b/ci/macos_xcode_bazel.sh
index 3e13b1538c..3cf1be4add 100755
--- a/ci/macos_xcode_bazel.sh
+++ b/ci/macos_xcode_bazel.sh
@@ -24,7 +24,7 @@ if [ -z ${ABSEIL_ROOT:-} ]; then
 fi
 
 # If we are running on Kokoro, check for a versioned Bazel binary.
-KOKORO_GFILE_BAZEL_BIN="bazel-0.28.1-darwin-x86_64"
+KOKORO_GFILE_BAZEL_BIN="bazel-2.0.0-darwin-x86_64"
 if [ ${KOKORO_GFILE_DIR:-} ] && [ -f ${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN} ]; then
   BAZEL_BIN="${KOKORO_GFILE_DIR}/${KOKORO_GFILE_BAZEL_BIN}"
   chmod +x ${BAZEL_BIN}