summaryrefslogtreecommitdiff
path: root/absl/strings/internal/cord_rep_ring.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/internal/cord_rep_ring.cc')
-rw-r--r--absl/strings/internal/cord_rep_ring.cc118
1 files changed, 2 insertions, 116 deletions
diff --git a/absl/strings/internal/cord_rep_ring.cc b/absl/strings/internal/cord_rep_ring.cc
index f78c94e1..20a6fc2b 100644
--- a/absl/strings/internal/cord_rep_ring.cc
+++ b/absl/strings/internal/cord_rep_ring.cc
@@ -26,6 +26,7 @@
#include "absl/base/macros.h"
#include "absl/container/inlined_vector.h"
#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cord_rep_consume.h"
#include "absl/strings/internal/cord_rep_flat.h"
namespace absl {
@@ -49,14 +50,6 @@ inline void CheckCapacity(size_t n, size_t extra) {
}
}
-// Removes a reference from `rep` only.
-// Asserts that the refcount after decrement is not zero.
-inline bool UnrefNeverOne(CordRep* rep) {
- bool result = rep->refcount.Decrement();
- assert(result);
- return result;
-}
-
// Creates a flat from the provided string data, allocating up to `extra`
// capacity in the returned flat depending on kMaxFlatLength limitations.
// Requires `len` to be less or equal to `kMaxFlatLength`
@@ -68,40 +61,6 @@ CordRepFlat* CreateFlat(const char* s, size_t n, size_t extra = 0) { // NOLINT
return rep;
}
-// Unrefs the provided `substring`, and returns `substring->child`
-// Adds or assumes a reference on `substring->child`
-CordRep* ClipSubstring(CordRepSubstring* substring) {
- CordRep* child = substring->child;
- if (substring->refcount.IsOne()) {
- delete substring;
- } else {
- CordRep::Ref(child);
- if (ABSL_PREDICT_FALSE(!substring->refcount.Decrement())) {
- UnrefNeverOne(child);
- delete substring;
- }
- }
- return child;
-}
-
-// Unrefs the provided `concat`, and returns `{concat->left, concat->right}`
-// Adds or assumes a reference on `concat->left` and `concat->right`.
-std::pair<CordRep*, CordRep*> ClipConcat(CordRepConcat* concat) {
- auto result = std::make_pair(concat->left, concat->right);
- if (concat->refcount.IsOne()) {
- delete concat;
- } else {
- CordRep::Ref(result.first);
- CordRep::Ref(result.second);
- if (ABSL_PREDICT_FALSE(!concat->refcount.Decrement())) {
- UnrefNeverOne(result.first);
- UnrefNeverOne(result.second);
- delete concat;
- }
- }
- return result;
-}
-
// Unrefs the entries in `[head, tail)`.
// Requires all entries to be a FLAT or EXTERNAL node.
void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) {
@@ -117,79 +76,6 @@ void UnrefEntries(const CordRepRing* rep, index_type head, index_type tail) {
});
}
-template <typename F>
-void Consume(Direction direction, CordRep* rep, F&& fn) {
- size_t offset = 0;
- size_t length = rep->length;
- struct Entry {
- CordRep* rep;
- size_t offset;
- size_t length;
- };
- absl::InlinedVector<Entry, 40> stack;
-
- for (;;) {
- if (rep->tag >= FLAT || rep->tag == EXTERNAL || rep->tag == RING) {
- fn(rep, offset, length);
- if (stack.empty()) return;
-
- rep = stack.back().rep;
- offset = stack.back().offset;
- length = stack.back().length;
- stack.pop_back();
- } else if (rep->tag == SUBSTRING) {
- offset += rep->substring()->start;
- rep = ClipSubstring(rep->substring());
- } else if (rep->tag == CONCAT) {
- auto res = ClipConcat(rep->concat());
- CordRep* left = res.first;
- CordRep* right = res.second;
-
- if (left->length <= offset) {
- // Don't need left node
- offset -= left->length;
- CordRep::Unref(left);
- rep = right;
- continue;
- }
-
- size_t length_left = left->length - offset;
- if (length_left >= length) {
- // Don't need right node
- CordRep::Unref(right);
- rep = left;
- continue;
- }
-
- // Need both nodes
- size_t length_right = length - length_left;
- if (direction == Direction::kReversed) {
- stack.push_back({left, offset, length_left});
- rep = right;
- offset = 0;
- length = length_right;
- } else {
- stack.push_back({right, 0, length_right});
- rep = left;
- length = length_left;
- }
- } else {
- assert("Valid tag" == nullptr);
- return;
- }
- }
-}
-
-template <typename F>
-void Consume(CordRep* rep, F&& fn) {
- return Consume(Direction::kForward, rep, std::forward<F>(fn));
-}
-
-template <typename F>
-void RConsume(CordRep* rep, F&& fn) {
- return Consume(Direction::kReversed, rep, std::forward<F>(fn));
-}
-
} // namespace
std::ostream& operator<<(std::ostream& s, const CordRepRing& rep) {
@@ -581,7 +467,7 @@ CordRepRing* CordRepRing::Append(CordRepRing* rep, CordRep* child) {
}
CordRepRing* CordRepRing::PrependSlow(CordRepRing* rep, CordRep* child) {
- RConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
+ ReverseConsume(child, [&](CordRep* child_arg, size_t offset, size_t len) {
if (IsFlatOrExternal(child_arg)) {
rep = PrependLeaf(rep, child_arg, offset, len);
} else {