about summary refs log tree commit diff
path: root/absl/strings
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2020-04-20T14·20-0700
committerDerek Mauro <dmauro@google.com>2020-04-20T16·56-0400
commitdf60c82df43e33274550e758c7a93fa49f88e0fe (patch)
tree0ae04d074d0a845ff1fd588b8d44067ff0fcd460 /absl/strings
parentb35973e3e35cb1eccb086d6a549c253c49579474 (diff)
Export of internal Abseil changes
--
b885a238ec13effcc407e250583e293052bd7984 by Greg Falcon <gfalcon@google.com>:

Remove the dependency of //absl/hash on //absl/strings:cord.

The `AbslHashValue` definition should reside in cord.h, but the implementation currently needs internal details from the hash library.  This CL changes the way that Cord gains access to those internals.  Note that PiecewiseCombiner remains an internal namespace API, and we still reserve the right to make changes to it.

The cord_benchmark shows no statistically significant changes in hash<Cord> performance with this change.

PiperOrigin-RevId: 307393448

--
ca449f230ee719d069d9217ba28a07bf5b3bd8b1 by Derek Mauro <dmauro@google.com>:

Move the extension to use absl::Format() with absl::Cord as a sink to cord.h

PiperOrigin-RevId: 307077162
GitOrigin-RevId: b885a238ec13effcc407e250583e293052bd7984
Change-Id: If24a90782c786fa0b4343bc7d72d053b66c153ea
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/BUILD.bazel2
-rw-r--r--absl/strings/CMakeLists.txt2
-rw-r--r--absl/strings/cord.h31
-rw-r--r--absl/strings/cord_test.cc9
-rw-r--r--absl/strings/internal/str_format/extension_test.cc9
-rw-r--r--absl/strings/internal/str_format/output.h9
6 files changed, 36 insertions, 26 deletions
diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel
index 4ee5a2ca7d2d..8aecbe59bbab 100644
--- a/absl/strings/BUILD.bazel
+++ b/absl/strings/BUILD.bazel
@@ -310,6 +310,7 @@ cc_test(
     deps = [
         ":cord",
         ":cord_test_helpers",
+        ":str_format",
         ":strings",
         "//absl/base",
         "//absl/base:config",
@@ -667,7 +668,6 @@ cc_test(
     copts = ABSL_TEST_COPTS,
     visibility = ["//visibility:private"],
     deps = [
-        ":cord",
         ":str_format",
         ":str_format_internal",
         ":strings",
diff --git a/absl/strings/CMakeLists.txt b/absl/strings/CMakeLists.txt
index 10213022a7bb..b6705ed0c106 100644
--- a/absl/strings/CMakeLists.txt
+++ b/absl/strings/CMakeLists.txt
@@ -425,7 +425,6 @@ absl_cc_test(
   DEPS
     absl::str_format
     absl::str_format_internal
-    absl::cord
     absl::strings
     gmock_main
 )
@@ -581,6 +580,7 @@ absl_cc_test(
     ${ABSL_TEST_COPTS}
   DEPS
     absl::cord
+    absl::str_format
     absl::strings
     absl::base
     absl::config
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index 2d92f6d69e19..9d99b2afd7e0 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -90,10 +90,6 @@ class CordTestPeer;
 template <typename Releaser>
 Cord MakeCordFromExternal(absl::string_view, Releaser&&);
 void CopyCordToString(const Cord& src, std::string* dst);
-namespace hash_internal {
-template <typename H>
-H HashFragmentedCord(H, const Cord&);
-}
 
 // Cord
 //
@@ -615,10 +611,22 @@ class Cord {
   // If the cord was already flat, the contents are not modified.
   absl::string_view Flatten();
 
+  // Support absl::Cord as a sink object for absl::Format().
+  friend void AbslFormatFlush(absl::Cord* cord, absl::string_view part) {
+    cord->Append(part);
+  }
+
+  template <typename H>
+  friend H AbslHashValue(H hash_state, const absl::Cord& c) {
+    absl::optional<absl::string_view> maybe_flat = c.TryFlat();
+    if (maybe_flat.has_value()) {
+      return H::combine(std::move(hash_state), *maybe_flat);
+    }
+    return c.HashFragmented(std::move(hash_state));
+  }
+
  private:
   friend class CordTestPeer;
-  template <typename H>
-  friend H absl::hash_internal::HashFragmentedCord(H, const Cord&);
   friend bool operator==(const Cord& lhs, const Cord& rhs);
   friend bool operator==(const Cord& lhs, absl::string_view rhs);
 
@@ -763,6 +771,17 @@ class Cord {
   // Helper for Append()
   template <typename C>
   void AppendImpl(C&& src);
+
+  // Helper for AbslHashValue()
+  template <typename H>
+  H HashFragmented(H hash_state) const {
+    typename H::AbslInternalPiecewiseCombiner combiner;
+    ForEachChunk([&combiner, &hash_state](absl::string_view chunk) {
+      hash_state = combiner.add_buffer(std::move(hash_state), chunk.data(),
+                                       chunk.size());
+    });
+    return H::combine(combiner.finalize(std::move(hash_state)), size());
+  }
 };
 
 ABSL_NAMESPACE_END
diff --git a/absl/strings/cord_test.cc b/absl/strings/cord_test.cc
index 49178498feae..336cedde20d0 100644
--- a/absl/strings/cord_test.cc
+++ b/absl/strings/cord_test.cc
@@ -22,6 +22,7 @@
 #include "absl/container/fixed_array.h"
 #include "absl/strings/cord_test_helpers.h"
 #include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
 #include "absl/strings/string_view.h"
 
 typedef std::mt19937_64 RandomEngine;
@@ -1582,6 +1583,14 @@ TEST(Cord, SmallBufferAssignFromOwnData) {
   }
 }
 
+TEST(Cord, Format) {
+  absl::Cord c;
+  absl::Format(&c, "There were %04d little %s.", 3, "pigs");
+  EXPECT_EQ(c, "There were 0003 little pigs.");
+  absl::Format(&c, "And %-3llx bad wolf!", 1);
+  EXPECT_EQ(c, "There were 0003 little pigs.And 1   bad wolf!");
+}
+
 TEST(CordDeathTest, Hardening) {
   absl::Cord cord("hello");
   // These statement should abort the program in all builds modes.
diff --git a/absl/strings/internal/str_format/extension_test.cc b/absl/strings/internal/str_format/extension_test.cc
index dc5576b6337e..561eaa36b845 100644
--- a/absl/strings/internal/str_format/extension_test.cc
+++ b/absl/strings/internal/str_format/extension_test.cc
@@ -19,7 +19,6 @@
 #include <random>
 #include <string>
 
-#include "absl/strings/cord.h"
 #include "gtest/gtest.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/string_view.h"
@@ -82,14 +81,6 @@ TEST(FormatExtensionTest, SinkAppendChars) {
   }
 }
 
-TEST(FormatExtensionTest, CordSink) {
-  absl::Cord c;
-  absl::Format(&c, "There were %04d little %s.", 3, "pigs");
-  EXPECT_EQ(c, "There were 0003 little pigs.");
-  absl::Format(&c, "And %-3llx bad wolf!", 1);
-  EXPECT_EQ(c, "There were 0003 little pigs.And 1   bad wolf!");
-}
-
 TEST(FormatExtensionTest, CustomSink) {
   my_namespace::UserDefinedType sink;
   absl::Format(&sink, "There were %04d little %s.", 3, "pigs");
diff --git a/absl/strings/internal/str_format/output.h b/absl/strings/internal/str_format/output.h
index c3168d208590..8030dae00f4f 100644
--- a/absl/strings/internal/str_format/output.h
+++ b/absl/strings/internal/str_format/output.h
@@ -30,9 +30,6 @@
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
-
-class Cord;
-
 namespace str_format_internal {
 
 // RawSink implementation that writes into a char* buffer.
@@ -77,12 +74,6 @@ inline void AbslFormatFlush(std::ostream* out, string_view s) {
   out->write(s.data(), s.size());
 }
 
-template <class AbslCord, typename = typename std::enable_if<
-                              std::is_same<AbslCord, absl::Cord>::value>::type>
-inline void AbslFormatFlush(AbslCord* out, string_view s) {
-  out->Append(s);
-}
-
 inline void AbslFormatFlush(FILERawSink* sink, string_view v) {
   sink->Write(v);
 }