Commit 6645f314 by Abseil Team Committed by Copybara-Service

Add `absl::AppendCordToString`

PiperOrigin-RevId: 626039936
Change-Id: I6e791363bab06d66029a8565c42d158a2fe176f0
parent 4eb6f626
......@@ -1062,6 +1062,15 @@ void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst) {
}
}
void AppendCordToString(const Cord& src, absl::Nonnull<std::string*> dst) {
const size_t cur_dst_size = dst->size();
const size_t new_dst_size = cur_dst_size + src.size();
absl::strings_internal::STLStringResizeUninitializedAmortized(dst,
new_dst_size);
char* append_ptr = &(*dst)[cur_dst_size];
src.CopyToArrayImpl(append_ptr);
}
void Cord::CopyToArraySlowPath(absl::Nonnull<char*> dst) const {
assert(contents_.is_tree());
absl::string_view fragment;
......
......@@ -105,6 +105,7 @@ class CordTestPeer;
template <typename Releaser>
Cord MakeCordFromExternal(absl::string_view, Releaser&&);
void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst);
void AppendCordToString(const Cord& src, absl::Nonnull<std::string*> dst);
// Cord memory accounting modes
enum class CordMemoryAccounting {
......@@ -421,6 +422,18 @@ class Cord {
friend void CopyCordToString(const Cord& src,
absl::Nonnull<std::string*> dst);
// AppendCordToString()
//
// Appends the contents of a `src` Cord to a `*dst` string.
//
// This function optimizes the case of appending to a non-empty destination
// string. If `*dst` already has capacity to store the contents of the cord,
// this function does not invalidate pointers previously returned by
// `dst->data()`. If `*dst` is a new object, prefer to simply use the
// conversion operator to `std::string`.
friend void AppendCordToString(const Cord& src,
absl::Nonnull<std::string*> dst);
class CharIterator;
//----------------------------------------------------------------------------
......@@ -1066,6 +1079,8 @@ class Cord {
const;
CharIterator FindImpl(CharIterator it, absl::string_view needle) const;
void CopyToArrayImpl(absl::Nonnull<char*> dst) const;
};
ABSL_NAMESPACE_END
......@@ -1450,6 +1465,14 @@ inline bool Cord::StartsWith(absl::string_view rhs) const {
return EqualsImpl(rhs, rhs_size);
}
inline void Cord::CopyToArrayImpl(absl::Nonnull<char*> dst) const {
if (!contents_.is_tree()) {
if (!empty()) contents_.CopyToArray(dst);
} else {
CopyToArraySlowPath(dst);
}
}
inline void Cord::ChunkIterator::InitTree(
absl::Nonnull<cord_internal::CordRep*> tree) {
tree = cord_internal::SkipCrcNode(tree);
......
......@@ -703,6 +703,38 @@ TEST_P(CordTest, CopyToString) {
"copying ", "to ", "a ", "string."})));
}
static void VerifyAppendCordToString(const absl::Cord& cord) {
std::string initially_empty;
absl::AppendCordToString(cord, &initially_empty);
EXPECT_EQ(initially_empty, cord);
const absl::string_view kInitialContents = "initial contents.";
std::string expected_after_append =
absl::StrCat(kInitialContents, std::string(cord));
std::string no_reserve(kInitialContents);
absl::AppendCordToString(cord, &no_reserve);
EXPECT_EQ(no_reserve, expected_after_append);
std::string has_reserved_capacity(kInitialContents);
has_reserved_capacity.reserve(has_reserved_capacity.size() + cord.size());
const char* address_before_copy = has_reserved_capacity.data();
absl::AppendCordToString(cord, &has_reserved_capacity);
EXPECT_EQ(has_reserved_capacity, expected_after_append);
EXPECT_EQ(has_reserved_capacity.data(), address_before_copy)
<< "AppendCordToString allocated new string storage; "
"has_reserved_capacity = \""
<< has_reserved_capacity << "\"";
}
TEST_P(CordTest, AppendToString) {
VerifyAppendCordToString(absl::Cord()); // empty cords cannot carry CRCs
VerifyAppendCordToString(MaybeHardened(absl::Cord("small cord")));
VerifyAppendCordToString(MaybeHardened(
absl::MakeFragmentedCord({"fragmented ", "cord ", "to ", "test ",
"appending ", "to ", "a ", "string."})));
}
TEST_P(CordTest, AppendEmptyBuffer) {
absl::Cord cord;
cord.Append(absl::CordBuffer());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment