aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/abseil-cpp/absl/strings/cord.cc
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-01-25 20:29:07 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-01-25 20:51:18 +0300
commit24abb4e0b50dd362e8cf30a682d5212252936b09 (patch)
treec5356c59cfe5480daca33b63b1742680a48586e8 /contrib/restricted/abseil-cpp/absl/strings/cord.cc
parentb65dd88d2d36688300317c22b9c14ed9dcdeb37d (diff)
downloadydb-24abb4e0b50dd362e8cf30a682d5212252936b09.tar.gz
Update contrib/restricted/abseil-cpp to 20240116.0
Diffstat (limited to 'contrib/restricted/abseil-cpp/absl/strings/cord.cc')
-rw-r--r--contrib/restricted/abseil-cpp/absl/strings/cord.cc335
1 files changed, 266 insertions, 69 deletions
diff --git a/contrib/restricted/abseil-cpp/absl/strings/cord.cc b/contrib/restricted/abseil-cpp/absl/strings/cord.cc
index 14976aef58..f67326fdef 100644
--- a/contrib/restricted/abseil-cpp/absl/strings/cord.cc
+++ b/contrib/restricted/abseil-cpp/absl/strings/cord.cc
@@ -15,27 +15,33 @@
#include "absl/strings/cord.h"
#include <algorithm>
-#include <atomic>
+#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
+#include <cstring>
#include <iomanip>
#include <ios>
#include <iostream>
#include <limits>
+#include <memory>
#include <ostream>
#include <sstream>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
+#include <string>
+#include <utility>
-#include "absl/base/casts.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
-#include "absl/base/port.h"
-#include "absl/container/fixed_array.h"
+#include "absl/base/optimization.h"
+#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
+#include "absl/crc/crc32c.h"
#include "absl/crc/internal/crc_cord_state.h"
+#include "absl/functional/function_ref.h"
#include "absl/strings/cord_buffer.h"
#include "absl/strings/escaping.h"
#include "absl/strings/internal/cord_data_edge.h"
@@ -43,13 +49,14 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_crc.h"
#include "absl/strings/internal/cord_rep_flat.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/match.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -68,29 +75,21 @@ using ::absl::cord_internal::kMinFlatLength;
using ::absl::cord_internal::kInlinedVectorSize;
using ::absl::cord_internal::kMaxBytesToCopy;
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent = 0);
-static bool VerifyNode(CordRep* root, CordRep* start_node,
- bool full_validation);
-
-static inline CordRep* VerifyTree(CordRep* node) {
- // Verification is expensive, so only do it in debug mode.
- // Even in debug mode we normally do only light validation.
- // If you are debugging Cord itself, you should define the
- // macro EXTRA_CORD_VALIDATION, e.g. by adding
- // --copt=-DEXTRA_CORD_VALIDATION to the blaze line.
-#ifdef EXTRA_CORD_VALIDATION
- assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/true));
-#else // EXTRA_CORD_VALIDATION
- assert(node == nullptr || VerifyNode(node, node, /*full_validation=*/false));
-#endif // EXTRA_CORD_VALIDATION
- static_cast<void>(&VerifyNode);
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent = 0);
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node);
+static inline absl::Nullable<CordRep*> VerifyTree(
+ absl::Nullable<CordRep*> node) {
+ assert(node == nullptr || VerifyNode(node, node));
+ static_cast<void>(&VerifyNode);
return node;
}
-static CordRepFlat* CreateFlat(const char* data, size_t length,
- size_t alloc_hint) {
+static absl::Nonnull<CordRepFlat*> CreateFlat(absl::Nonnull<const char*> data,
+ size_t length,
+ size_t alloc_hint) {
CordRepFlat* flat = CordRepFlat::New(length + alloc_hint);
flat->length = length;
memcpy(flat->Data(), data, length);
@@ -99,7 +98,8 @@ static CordRepFlat* CreateFlat(const char* data, size_t length,
// Creates a new flat or Btree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nonnull<CordRep*> NewBtree(absl::Nonnull<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length <= kMaxFlatLength) {
return CreateFlat(data, length, alloc_hint);
}
@@ -112,14 +112,16 @@ static CordRep* NewBtree(const char* data, size_t length, size_t alloc_hint) {
// Create a new tree out of the specified array.
// The returned node has a refcount of 1.
-static CordRep* NewTree(const char* data, size_t length, size_t alloc_hint) {
+static absl::Nullable<CordRep*> NewTree(absl::Nullable<const char*> data,
+ size_t length, size_t alloc_hint) {
if (length == 0) return nullptr;
return NewBtree(data, length, alloc_hint);
}
namespace cord_internal {
-void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
+void InitializeCordRepExternal(absl::string_view data,
+ absl::Nonnull<CordRepExternal*> rep) {
assert(!data.empty());
rep->length = data.size();
rep->tag = EXTERNAL;
@@ -133,7 +135,7 @@ void InitializeCordRepExternal(absl::string_view data, CordRepExternal* rep) {
// and not wasteful, we move the string into an external cord rep, preserving
// the already allocated string contents.
// Requires the provided string length to be larger than `kMaxInline`.
-static CordRep* CordRepFromString(std::string&& src) {
+static absl::Nonnull<CordRep*> CordRepFromString(std::string&& src) {
assert(src.length() > cord_internal::kMaxInline);
if (
// String is short: copy data to avoid external block overhead.
@@ -165,12 +167,13 @@ static CordRep* CordRepFromString(std::string&& src) {
constexpr unsigned char Cord::InlineRep::kMaxInline;
#endif
-inline void Cord::InlineRep::set_data(const char* data, size_t n) {
+inline void Cord::InlineRep::set_data(absl::Nonnull<const char*> data,
+ size_t n) {
static_assert(kMaxInline == 15, "set_data is hard-coded for a length of 15");
data_.set_inline_data(data, n);
}
-inline char* Cord::InlineRep::set_data(size_t n) {
+inline absl::Nonnull<char*> Cord::InlineRep::set_data(size_t n) {
assert(n <= kMaxInline);
ResetToEmpty();
set_inline_size(n);
@@ -194,13 +197,13 @@ inline void Cord::InlineRep::remove_prefix(size_t n) {
// Returns `rep` converted into a CordRepBtree.
// Directly returns `rep` if `rep` is already a CordRepBtree.
-static CordRepBtree* ForceBtree(CordRep* rep) {
+static absl::Nonnull<CordRepBtree*> ForceBtree(CordRep* rep) {
return rep->IsBtree()
? rep->btree()
: CordRepBtree::Create(cord_internal::RemoveCrcNode(rep));
}
-void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
+void Cord::InlineRep::AppendTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -210,14 +213,16 @@ void Cord::InlineRep::AppendTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::AppendTreeToTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTreeToTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
tree = CordRepBtree::Append(ForceBtree(data_.as_tree()), tree);
SetTree(tree, scope);
}
-void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::AppendTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -228,7 +233,7 @@ void Cord::InlineRep::AppendTree(CordRep* tree, MethodIdentifier method) {
}
}
-void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
+void Cord::InlineRep::PrependTreeToInlined(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(!is_tree());
if (!data_.is_empty()) {
@@ -238,7 +243,7 @@ void Cord::InlineRep::PrependTreeToInlined(CordRep* tree,
EmplaceTree(tree, method);
}
-void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
+void Cord::InlineRep::PrependTreeToTree(absl::Nonnull<CordRep*> tree,
MethodIdentifier method) {
assert(is_tree());
const CordzUpdateScope scope(data_.cordz_info(), method);
@@ -246,7 +251,8 @@ void Cord::InlineRep::PrependTreeToTree(CordRep* tree,
SetTree(tree, scope);
}
-void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
+void Cord::InlineRep::PrependTree(absl::Nonnull<CordRep*> tree,
+ MethodIdentifier method) {
assert(tree != nullptr);
assert(tree->length != 0);
assert(!tree->IsCrc());
@@ -261,8 +267,9 @@ void Cord::InlineRep::PrependTree(CordRep* tree, MethodIdentifier method) {
// suitable leaf is found, the function will update the length field for all
// nodes to account for the size increase. The append region address will be
// written to region and the actual size increase will be written to size.
-static inline bool PrepareAppendRegion(CordRep* root, char** region,
- size_t* size, size_t max_length) {
+static inline bool PrepareAppendRegion(
+ absl::Nonnull<CordRep*> root, absl::Nonnull<absl::Nullable<char*>*> region,
+ absl::Nonnull<size_t*> size, size_t max_length) {
if (root->IsBtree() && root->refcount.IsOne()) {
Span<char> span = root->btree()->GetAppendBuffer(max_length);
if (!span.empty()) {
@@ -465,11 +472,11 @@ void Cord::InlineRep::AppendArray(absl::string_view src,
CommitTree(root, rep, scope, method);
}
-inline CordRep* Cord::TakeRep() const& {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() const& {
return CordRep::Ref(contents_.tree());
}
-inline CordRep* Cord::TakeRep() && {
+inline absl::Nonnull<CordRep*> Cord::TakeRep() && {
CordRep* rep = contents_.tree();
contents_.clear();
return rep;
@@ -527,7 +534,7 @@ inline void Cord::AppendImpl(C&& src) {
contents_.AppendTree(rep, CordzUpdateTracker::kAppendCord);
}
-static CordRep::ExtractResult ExtractAppendBuffer(CordRep* rep,
+static CordRep::ExtractResult ExtractAppendBuffer(absl::Nonnull<CordRep*> rep,
size_t min_capacity) {
switch (rep->tag) {
case cord_internal::BTREE:
@@ -573,13 +580,9 @@ CordBuffer Cord::GetAppendBufferSlowPath(size_t block_size, size_t capacity,
return CreateAppendBuffer(contents_.data_, block_size, capacity);
}
-void Cord::Append(const Cord& src) {
- AppendImpl(src);
-}
+void Cord::Append(const Cord& src) { AppendImpl(src); }
-void Cord::Append(Cord&& src) {
- AppendImpl(std::move(src));
-}
+void Cord::Append(Cord&& src) { AppendImpl(std::move(src)); }
template <typename T, Cord::EnableIfString<T>>
void Cord::Append(T&& src) {
@@ -778,8 +781,9 @@ int ClampResult(int memcmp_res) {
return static_cast<int>(memcmp_res > 0) - static_cast<int>(memcmp_res < 0);
}
-int CompareChunks(absl::string_view* lhs, absl::string_view* rhs,
- size_t* size_to_compare) {
+int CompareChunks(absl::Nonnull<absl::string_view*> lhs,
+ absl::Nonnull<absl::string_view*> rhs,
+ absl::Nonnull<size_t*> size_to_compare) {
size_t compared_size = std::min(lhs->size(), rhs->size());
assert(*size_to_compare >= compared_size);
*size_to_compare -= compared_size;
@@ -877,7 +881,8 @@ void Cord::SetExpectedChecksum(uint32_t crc) {
SetCrcCordState(std::move(state));
}
-const crc_internal::CrcCordState* Cord::MaybeGetCrcCordState() const {
+absl::Nullable<const crc_internal::CrcCordState*> Cord::MaybeGetCrcCordState()
+ const {
if (!contents_.is_tree() || !contents_.tree()->IsCrc()) {
return nullptr;
}
@@ -894,7 +899,8 @@ absl::optional<uint32_t> Cord::ExpectedChecksum() const {
inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -924,7 +930,8 @@ inline int Cord::CompareSlowPath(absl::string_view rhs, size_t compared_size,
inline int Cord::CompareSlowPath(const Cord& rhs, size_t compared_size,
size_t size_to_compare) const {
- auto advance = [](Cord::ChunkIterator* it, absl::string_view* chunk) {
+ auto advance = [](absl::Nonnull<Cord::ChunkIterator*> it,
+ absl::Nonnull<absl::string_view*> chunk) {
if (!chunk->empty()) return true;
++*it;
if (it->bytes_remaining_ == 0) return false;
@@ -1046,7 +1053,7 @@ Cord::operator std::string() const {
return s;
}
-void CopyCordToString(const Cord& src, std::string* dst) {
+void CopyCordToString(const Cord& src, absl::Nonnull<std::string*> dst) {
if (!src.contents_.is_tree()) {
src.contents_.CopyTo(dst);
} else {
@@ -1055,7 +1062,7 @@ void CopyCordToString(const Cord& src, std::string* dst) {
}
}
-void Cord::CopyToArraySlowPath(char* dst) const {
+void Cord::CopyToArraySlowPath(absl::Nonnull<char*> dst) const {
assert(contents_.is_tree());
absl::string_view fragment;
if (GetFlatAux(contents_.tree(), &fragment)) {
@@ -1165,6 +1172,194 @@ char Cord::operator[](size_t i) const {
}
}
+namespace {
+
+// Tests whether the sequence of chunks beginning at `position` starts with
+// `needle`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle.size()`.
+bool IsSubstringInCordAt(absl::Cord::CharIterator position,
+ absl::string_view needle) {
+ auto haystack_chunk = absl::Cord::ChunkRemaining(position);
+ while (true) {
+ // Precondition is that `absl::Cord::ChunkRemaining(position)` is not
+ // empty. This assert will trigger if that is not true.
+ assert(!haystack_chunk.empty());
+ auto min_length = std::min(haystack_chunk.size(), needle.size());
+ if (!absl::ConsumePrefix(&needle, haystack_chunk.substr(0, min_length))) {
+ return false;
+ }
+ if (needle.empty()) {
+ return true;
+ }
+ absl::Cord::Advance(&position, min_length);
+ haystack_chunk = absl::Cord::ChunkRemaining(position);
+ }
+}
+
+} // namespace
+
+// A few options how this could be implemented:
+// (a) Flatten the Cord and find, i.e.
+// haystack.Flatten().find(needle)
+// For large 'haystack' (where Cord makes sense to be used), this copies
+// the whole 'haystack' and can be slow.
+// (b) Use std::search, i.e.
+// std::search(haystack.char_begin(), haystack.char_end(),
+// needle.begin(), needle.end())
+// This avoids the copy, but compares one byte at a time, and branches a
+// lot every time it has to advance. It is also not possible to use
+// std::search as is, because CharIterator is only an input iterator, not a
+// forward iterator.
+// (c) Use string_view::find in each fragment, and specifically handle fragment
+// boundaries.
+//
+// This currently implements option (b).
+absl::Cord::CharIterator absl::Cord::FindImpl(CharIterator it,
+ absl::string_view needle) const {
+ // Ensure preconditions are met by callers first.
+
+ // Needle must not be empty.
+ assert(!needle.empty());
+ // Haystack must be at least as large as needle.
+ assert(it.chunk_iterator_.bytes_remaining_ >= needle.size());
+
+ // Cord is a sequence of chunks. To find `needle` we go chunk by chunk looking
+ // for the first char of needle, up until we have advanced `N` defined as
+ // `haystack.size() - needle.size()`. If we find the first char of needle at
+ // `P` and `P` is less than `N`, we then call `IsSubstringInCordAt` to
+ // see if this is the needle. If not, we advance to `P + 1` and try again.
+ while (it.chunk_iterator_.bytes_remaining_ >= needle.size()) {
+ auto haystack_chunk = Cord::ChunkRemaining(it);
+ assert(!haystack_chunk.empty());
+ // Look for the first char of `needle` in the current chunk.
+ auto idx = haystack_chunk.find(needle.front());
+ if (idx == absl::string_view::npos) {
+ // No potential match in this chunk, advance past it.
+ Cord::Advance(&it, haystack_chunk.size());
+ continue;
+ }
+ // We found the start of a potential match in the chunk. Advance the
+ // iterator and haystack chunk to the match the position.
+ Cord::Advance(&it, idx);
+ // Check if there is enough haystack remaining to actually have a match.
+ if (it.chunk_iterator_.bytes_remaining_ < needle.size()) {
+ break;
+ }
+ // Check if this is `needle`.
+ if (IsSubstringInCordAt(it, needle)) {
+ return it;
+ }
+ // No match, increment the iterator for the next attempt.
+ Cord::Advance(&it, 1);
+ }
+ // If we got here, we did not find `needle`.
+ return char_end();
+}
+
+absl::Cord::CharIterator absl::Cord::Find(absl::string_view needle) const {
+ if (needle.empty()) {
+ return char_begin();
+ }
+ if (needle.size() > size()) {
+ return char_end();
+ }
+ if (needle.size() == size()) {
+ return *this == needle ? char_begin() : char_end();
+ }
+ return FindImpl(char_begin(), needle);
+}
+
+namespace {
+
+// Tests whether the sequence of chunks beginning at `haystack` starts with the
+// sequence of chunks beginning at `needle_begin` and extending to `needle_end`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle_end - needle_begin` and `advance`.
+bool IsSubcordInCordAt(absl::Cord::CharIterator haystack,
+ absl::Cord::CharIterator needle_begin,
+ absl::Cord::CharIterator needle_end) {
+ while (needle_begin != needle_end) {
+ auto haystack_chunk = absl::Cord::ChunkRemaining(haystack);
+ assert(!haystack_chunk.empty());
+ auto needle_chunk = absl::Cord::ChunkRemaining(needle_begin);
+ auto min_length = std::min(haystack_chunk.size(), needle_chunk.size());
+ if (haystack_chunk.substr(0, min_length) !=
+ needle_chunk.substr(0, min_length)) {
+ return false;
+ }
+ absl::Cord::Advance(&haystack, min_length);
+ absl::Cord::Advance(&needle_begin, min_length);
+ }
+ return true;
+}
+
+// Tests whether the sequence of chunks beginning at `position` starts with the
+// cord `needle`.
+//
+// REQUIRES: remaining `absl::Cord` starting at `position` is greater than or
+// equal to `needle.size()`.
+bool IsSubcordInCordAt(absl::Cord::CharIterator position,
+ const absl::Cord& needle) {
+ return IsSubcordInCordAt(position, needle.char_begin(), needle.char_end());
+}
+
+} // namespace
+
+absl::Cord::CharIterator absl::Cord::Find(const absl::Cord& needle) const {
+ if (needle.empty()) {
+ return char_begin();
+ }
+ const auto needle_size = needle.size();
+ if (needle_size > size()) {
+ return char_end();
+ }
+ if (needle_size == size()) {
+ return *this == needle ? char_begin() : char_end();
+ }
+ const auto needle_chunk = Cord::ChunkRemaining(needle.char_begin());
+ auto haystack_it = char_begin();
+ while (true) {
+ haystack_it = FindImpl(haystack_it, needle_chunk);
+ if (haystack_it == char_end() ||
+ haystack_it.chunk_iterator_.bytes_remaining_ < needle_size) {
+ break;
+ }
+ // We found the first chunk of `needle` at `haystack_it` but not the entire
+ // subcord. Advance past the first chunk and check for the remainder.
+ auto haystack_advanced_it = haystack_it;
+ auto needle_it = needle.char_begin();
+ Cord::Advance(&haystack_advanced_it, needle_chunk.size());
+ Cord::Advance(&needle_it, needle_chunk.size());
+ if (IsSubcordInCordAt(haystack_advanced_it, needle_it, needle.char_end())) {
+ return haystack_it;
+ }
+ Cord::Advance(&haystack_it, 1);
+ if (haystack_it.chunk_iterator_.bytes_remaining_ < needle_size) {
+ break;
+ }
+ if (haystack_it.chunk_iterator_.bytes_remaining_ == needle_size) {
+ // Special case, if there is exactly `needle_size` bytes remaining, the
+ // subcord is either at `haystack_it` or not at all.
+ if (IsSubcordInCordAt(haystack_it, needle)) {
+ return haystack_it;
+ }
+ break;
+ }
+ }
+ return char_end();
+}
+
+bool Cord::Contains(absl::string_view rhs) const {
+ return rhs.empty() || Find(rhs) != char_end();
+}
+
+bool Cord::Contains(const absl::Cord& rhs) const {
+ return rhs.empty() || Find(rhs) != char_end();
+}
+
absl::string_view Cord::FlattenSlowPath() {
assert(contents_.is_tree());
size_t total_size = size();
@@ -1193,7 +1388,8 @@ absl::string_view Cord::FlattenSlowPath() {
return absl::string_view(new_buffer, total_size);
}
-/* static */ bool Cord::GetFlatAux(CordRep* rep, absl::string_view* fragment) {
+/* static */ bool Cord::GetFlatAux(absl::Nonnull<CordRep*> rep,
+ absl::Nonnull<absl::string_view*> fragment) {
assert(rep != nullptr);
if (rep->length == 0) {
*fragment = absl::string_view();
@@ -1227,7 +1423,7 @@ absl::string_view Cord::FlattenSlowPath() {
}
/* static */ void Cord::ForEachChunkAux(
- absl::cord_internal::CordRep* rep,
+ absl::Nonnull<absl::cord_internal::CordRep*> rep,
absl::FunctionRef<void(absl::string_view)> callback) {
assert(rep != nullptr);
if (rep->length == 0) return;
@@ -1252,8 +1448,8 @@ absl::string_view Cord::FlattenSlowPath() {
}
}
-static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
- int indent) {
+static void DumpNode(absl::Nonnull<CordRep*> rep, bool include_data,
+ absl::Nonnull<std::ostream*> os, int indent) {
const int kIndentStep = 1;
absl::InlinedVector<CordRep*, kInlinedVectorSize> stack;
absl::InlinedVector<int, kInlinedVectorSize> indents;
@@ -1289,7 +1485,7 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
*os << absl::CEscape(std::string(rep->flat()->Data(), rep->length));
*os << "]\n";
} else {
- CordRepBtree::Dump(rep, /*label=*/ "", include_data, *os);
+ CordRepBtree::Dump(rep, /*label=*/"", include_data, *os);
}
}
if (leaf) {
@@ -1303,16 +1499,17 @@ static void DumpNode(CordRep* rep, bool include_data, std::ostream* os,
ABSL_INTERNAL_CHECK(indents.empty(), "");
}
-static std::string ReportError(CordRep* root, CordRep* node) {
+static std::string ReportError(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> node) {
std::ostringstream buf;
buf << "Error at node " << node << " in:";
DumpNode(root, true, &buf);
return buf.str();
}
-static bool VerifyNode(CordRep* root, CordRep* start_node,
- bool /* full_validation */) {
- absl::InlinedVector<CordRep*, 2> worklist;
+static bool VerifyNode(absl::Nonnull<CordRep*> root,
+ absl::Nonnull<CordRep*> start_node) {
+ absl::InlinedVector<absl::Nonnull<CordRep*>, 2> worklist;
worklist.push_back(start_node);
do {
CordRep* node = worklist.back();