diff --git a/absl/strings/BUILD.bazel b/absl/strings/BUILD.bazel index dd2cf05ae81..81b8d89379b 100644 --- a/absl/strings/BUILD.bazel +++ b/absl/strings/BUILD.bazel @@ -441,15 +441,13 @@ cc_library( "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", + "//absl/base:nullability", "//absl/base:raw_logging_internal", - "//absl/base:throw_delegate", "//absl/container:compressed_tuple", "//absl/container:container_memory", "//absl/container:inlined_vector", - "//absl/container:layout", "//absl/crc:crc_cord_state", "//absl/functional:function_ref", - "//absl/meta:type_traits", "//absl/types:span", ], ) @@ -580,14 +578,11 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":cord_internal", - ":cordz_functions", ":cordz_info", - ":cordz_statistics", ":cordz_update_scope", ":cordz_update_tracker", ":internal", ":strings", - "//absl/base", "//absl/base:config", "//absl/base:core_headers", "//absl/base:endian", diff --git a/absl/strings/cord.h b/absl/strings/cord.h index 1d8fcd3738c..1f8aafb5875 100644 --- a/absl/strings/cord.h +++ b/absl/strings/cord.h @@ -61,6 +61,7 @@ #define ABSL_STRINGS_CORD_H_ #include +#include #include #include #include @@ -68,16 +69,14 @@ #include #include #include +#include #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/endian.h" -#include "absl/base/internal/per_thread_tls.h" #include "absl/base/macros.h" #include "absl/base/nullability.h" #include "absl/base/optimization.h" -#include "absl/base/port.h" -#include "absl/container/inlined_vector.h" #include "absl/crc/internal/crc_cord_state.h" #include "absl/functional/function_ref.h" #include "absl/meta/type_traits.h" @@ -88,12 +87,10 @@ #include "absl/strings/internal/cord_rep_btree.h" #include "absl/strings/internal/cord_rep_btree_reader.h" #include "absl/strings/internal/cord_rep_crc.h" -#include "absl/strings/internal/cordz_functions.h" +#include "absl/strings/internal/cord_rep_flat.h" #include "absl/strings/internal/cordz_info.h" -#include "absl/strings/internal/cordz_statistics.h" #include "absl/strings/internal/cordz_update_scope.h" #include "absl/strings/internal/cordz_update_tracker.h" -#include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/string_constant.h" #include "absl/strings/string_view.h" #include "absl/types/compare.h" @@ -978,15 +975,9 @@ class Cord { bool IsSame(const InlineRep& other) const { return data_ == other.data_; } + // Copies the inline contents into `dst`. Assumes the cord is not empty. void CopyTo(absl::Nonnull dst) const { - // memcpy is much faster when operating on a known size. On most supported - // platforms, the small string optimization is large enough that resizing - // to 15 bytes does not cause a memory allocation. - absl::strings_internal::STLStringResizeUninitialized(dst, kMaxInline); - data_.copy_max_inline_to(&(*dst)[0]); - // erase is faster than resize because the logic for memory allocation is - // not needed. - dst->erase(inline_size()); + data_.CopyInlineToString(dst); } // Copies the inline contents into `dst`. Assumes the cord is not empty. diff --git a/absl/strings/internal/cord_internal.h b/absl/strings/internal/cord_internal.h index d33b09e6ef9..b68ec2bbc5f 100644 --- a/absl/strings/internal/cord_internal.h +++ b/absl/strings/internal/cord_internal.h @@ -19,16 +19,18 @@ #include #include #include -#include +#include +#include #include "absl/base/attributes.h" #include "absl/base/config.h" #include "absl/base/internal/endian.h" #include "absl/base/internal/invoke.h" +#include "absl/base/macros.h" +#include "absl/base/nullability.h" #include "absl/base/optimization.h" #include "absl/container/internal/compressed_tuple.h" #include "absl/container/internal/container_memory.h" -#include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" // We can only add poisoning if we can detect consteval executions. @@ -635,6 +637,19 @@ class InlineData { poison(); } + void CopyInlineToString(absl::Nonnull dst) const { + assert(!is_tree()); + // As Cord can store only 15 bytes it is smaller than std::string's + // small string optimization buffer size. Therefore we will always trigger + // the fast assign short path. + // + // Copying with a size equal to the maximum allows more efficient, wider + // stores to be used and no branching. + dst->assign(rep_.SanitizerSafeCopy().as_chars(), kMaxInline); + // After the copy we then change the size and put in a 0 byte. + dst->erase(inline_size()); + } + void copy_max_inline_to(char* dst) const { assert(!is_tree()); memcpy(dst, rep_.SanitizerSafeCopy().as_chars(), kMaxInline);