|
Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
|
Immutable, structurally-shared rope over a sequence of Char.
More...
#include <tpl_rope.H>
Classes | |
| struct | Node |
Public Types | |
| using | View = std::basic_string_view< Char > |
| View type accepted by the constructor and compared against. | |
Public Member Functions | |
| Rope () noexcept=default | |
| Construct the empty rope. | |
| Rope (const View v) | |
Construct a rope holding a copy of v's characters. | |
| Rope (const Rope &other)=default | |
| Copy constructor: O(1), shares the entire tree (immutable, so sharing is always safe). | |
| Rope & | operator= (const Rope &other)=default |
| Copy assignment operator: O(1), shares the entire tree. | |
| Rope (Rope &&other) noexcept=default | |
| Move constructor. | |
| Rope & | operator= (Rope &&other) noexcept=default |
| Move assignment operator. | |
| ~Rope ()=default | |
| Destructor: releases this rope's reference to its tree; nodes are only actually freed once no rope shares them anymore. | |
| size_t | size () const noexcept |
| Return the number of characters in this rope. | |
| bool | is_empty () const noexcept |
| Check whether this rope holds no characters. | |
| Char | at (const size_t pos) const |
Return the character at pos. | |
| Rope | concat (const Rope &other) const |
Return a new rope that is *this followed by other. | |
| Rope | substr (const size_t pos, const size_t len) const |
Return a new rope holding [pos, pos+len) of *this. | |
| Rope | insert (const size_t pos, const Rope &other) const |
Return a new rope with other inserted at pos. | |
| Rope | erase (const size_t pos, const size_t len) const |
Return a new rope with [pos, pos+len) removed. | |
| Array< Char > | flatten () const |
| Return every character of this rope as an independent Array. | |
| std::basic_string< Char > | to_string () const |
Return every character of this rope as a std::basic_string. | |
| bool | operator== (const Rope &other) const |
Equality: true iff both ropes have the same length and the same characters in the same order (structural/identity sharing is irrelevant to this comparison). | |
| bool | verify () const noexcept |
| Check this rope's internal structural invariants. | |
Private Types | |
| using | NodePtr = std::shared_ptr< const Node > |
Private Member Functions | |
| Rope (NodePtr root) noexcept | |
Static Private Member Functions | |
| static NodePtr | make_leaf (SmallVector< Char, LeafSize > data) |
| static NodePtr | make_internal_node (NodePtr left, NodePtr right) |
Raw construction of an internal node from two already-built, non-null subtrees: no rebalancing, just length/depth bookkeeping. | |
| static NodePtr | make_internal (NodePtr left, NodePtr right) |
Wrap two non-null subtrees in a new internal node, then rebalance if the result is deeper than is_balanced() allows. | |
| static NodePtr | try_absorb_right (const NodePtr &node, const SmallVector< Char, LeafSize > &extra) |
Try to merge extra into the rightmost leaf of node, sharing every other node unchanged. | |
| static NodePtr | try_absorb_left (const NodePtr &node, const SmallVector< Char, LeafSize > &extra) |
Mirror of try_absorb_right: merge extra into the leftmost leaf of node, for the "prepend one small piece at a time" pattern. | |
| static NodePtr | concat_nodes (NodePtr left, NodePtr right) |
| Concatenate two (possibly null/empty) subtrees. | |
| static bool | is_balanced (const Node *node) noexcept |
Generous upper bound on the depth a subtree of the given length should have if reasonably balanced – see the file-level "Rebalancing" note for why this (rather than the classical Fibonacci-threshold test) was chosen for this first version. | |
| static void | collect_leaves (const NodePtr &node, Array< NodePtr > &out) |
| static void | collect_leaf_pointers (const Node *node, Array< const Node * > &out) |
Read-only counterpart of collect_leaves: collects raw, non-owning const Node * instead of NodePtr (shared_ptr<const Node>). | |
| static NodePtr | build_balanced_from_leaves (const Array< NodePtr > &leaves, const size_t lo, const size_t hi) |
| static NodePtr | maybe_rebalance (NodePtr node) |
| static NodePtr | build_from_view (const View v) |
| Build a balanced tree of leaves directly from a flat view, splitting at the midpoint recursively. | |
| static const Char & | char_at (const Node *node, size_t pos) noexcept |
| static NodePtr | slice (const NodePtr &node, size_t pos, size_t len) |
Extract [pos, pos+len) from node (whose own length is assumed to be >= pos+len) as a new, independently-rooted subtree. | |
| static void | flatten_into (const Node *node, Array< Char > &out) |
| static void | string_append_into (const Node *node, std::basic_string< Char > &out) |
Like flatten_into, but appends directly into a std::basic_string (one bulk append per leaf) instead of an Array<Char>, so to_string() does not need a separate Array<Char> -> string copy pass. | |
| static bool | verify_rec (const Node *node) noexcept |
Recursive structural-invariant check backing the public verify(). | |
Private Attributes | |
| NodePtr | root_ |
Immutable, structurally-shared rope over a sequence of Char.
See the file-level documentation in tpl_rope.H for the full design rationale, structure, and rebalancing contract.
| Char | Character type stored (default char). Treated as an opaque fixed-width code unit; no Unicode awareness. Must be a trivial, standard-layout type: View is std::basic_string_view<Char>, which the standard library itself requires this of (see <string_view>'s own static_assert). One consequence: Char's copy can never throw (a trivial copy constructor cannot run user code), so Rope's only real exception source is allocation failure (std::bad_alloc), not anything Char-related. |
| LeafSize | Maximum number of characters per leaf node (default 256). Larger values mean fewer, bigger leaves (cheaper to build, costlier to slice at a boundary inside one); smaller values mean more structural sharing granularity at the cost of more nodes. |
Definition at line 175 of file tpl_rope.H.
Definition at line 213 of file tpl_rope.H.
| using Aleph::Rope< Char, LeafSize >::View = std::basic_string_view<Char> |
View type accepted by the constructor and compared against.
Definition at line 181 of file tpl_rope.H.
|
inlineexplicitprivatenoexcept |
Definition at line 616 of file tpl_rope.H.
|
defaultnoexcept |
Construct the empty rope.
| Nothing. |
Referenced by Aleph::Rope< Char, LeafSize >::concat(), and Aleph::Rope< Char, LeafSize >::substr().
Construct a rope holding a copy of v's characters.
| [in] | v | Characters to copy in. |
| std::bad_alloc. |
Definition at line 628 of file tpl_rope.H.
Copy constructor: O(1), shares the entire tree (immutable, so sharing is always safe).
| [in] | other | Rope to copy. |
| Nothing. |
|
default |
Destructor: releases this rope's reference to its tree; nodes are only actually freed once no rope shares them anymore.
|
inline |
Return the character at pos.
| [in] | pos | Zero-based index. |
pos. pos < size(). | std::out_of_range | if pos >= size(). |
Definition at line 683 of file tpl_rope.H.
References ah_out_of_range_error_if, Aleph::Rope< Char, LeafSize >::char_at(), Aleph::Rope< Char, LeafSize >::root_, and Aleph::Rope< Char, LeafSize >::size().
Referenced by TEST().
|
inlinestaticprivate |
Definition at line 414 of file tpl_rope.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::build_balanced_from_leaves(), and Aleph::Rope< Char, LeafSize >::make_internal_node().
Referenced by Aleph::Rope< Char, LeafSize >::build_balanced_from_leaves(), and Aleph::Rope< Char, LeafSize >::maybe_rebalance().
Build a balanced tree of leaves directly from a flat view, splitting at the midpoint recursively.
Used by the constructor: since it never produces an unbalanced intermediate node, no maybe_rebalance() call is needed here.
Definition at line 462 of file tpl_rope.H.
References Aleph::SmallVector< T, N >::append_range(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::build_from_view(), Aleph::Rope< Char, LeafSize >::make_internal_node(), and Aleph::Rope< Char, LeafSize >::make_leaf().
Referenced by Aleph::Rope< Char, LeafSize >::build_from_view().
|
inlinestaticprivatenoexcept |
Definition at line 481 of file tpl_rope.H.
References Aleph::blossom_maximum_cardinality_matching().
Referenced by Aleph::Rope< Char, LeafSize >::at().
|
inlinestaticprivate |
Read-only counterpart of collect_leaves: collects raw, non-owning const Node * instead of NodePtr (shared_ptr<const Node>).
operator== is the only caller – it only ever reads leaf character data during the comparison, never needs to extend any node's lifetime beyond it (the two ropes' own root_/other.root_ already keep every visited node alive for the whole call), so collecting owning shared_ptrs there would pay for an atomic refcount increment and decrement per leaf for no benefit – real traffic for a rope with many leaves. maybe_rebalance still uses the owning collect_leaves above, since it genuinely needs the NodePtrs themselves as the rebuilt tree's new owning children.
Definition at line 403 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::collect_leaf_pointers(), Aleph::Rope< Char, LeafSize >::Node::is_leaf(), Aleph::Rope< Char, LeafSize >::Node::left, out, and Aleph::Rope< Char, LeafSize >::Node::right.
Referenced by Aleph::Rope< Char, LeafSize >::collect_leaf_pointers(), and Aleph::Rope< Char, LeafSize >::operator==().
|
inlinestaticprivate |
Definition at line 381 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::collect_leaves(), and out.
Referenced by Aleph::Rope< Char, LeafSize >::collect_leaves(), and Aleph::Rope< Char, LeafSize >::maybe_rebalance().
Return a new rope that is *this followed by other.
| [in] | other | Rope to append. |
*this nor other is modified. | std::bad_alloc. | |
| std::overflow_error | if size() + other.size() would exceed std::numeric_limits<size_t>::max(). Not just a theoretical concern: structural sharing makes this reachable with very little real memory, e.g. r = r.concat(r) doubles size() each call at O(1) real cost, so ~64 such calls reach the limit. Checked before the addition, never wraps silently. |
O(depth) spine walk plus an O(LeafSize) copy of the leaf being grown, so a larger LeafSize makes each such concat proportionally more expensive, not cheaper – plus the (amortized, occasional) cost of rebalancing; see the file-level "Rebalancing" and "Leaf
absorption" notes. Definition at line 708 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::Rope(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::concat_nodes(), and Aleph::Rope< Char, LeafSize >::root_.
Referenced by Aleph::Rope< Char, LeafSize >::erase(), Aleph::Rope< Char, LeafSize >::insert(), TEST(), TEST(), and TEST().
|
inlinestaticprivate |
Concatenate two (possibly null/empty) subtrees.
Definition at line 343 of file tpl_rope.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::make_internal(), Aleph::Rope< Char, LeafSize >::try_absorb_left(), and Aleph::Rope< Char, LeafSize >::try_absorb_right().
Referenced by Aleph::Rope< Char, LeafSize >::concat(), and Aleph::Rope< Char, LeafSize >::slice().
Return a new rope with [pos, pos+len) removed.
| [in] | pos | Start index. |
| [in] | len | Number of characters to remove. |
substr(0, pos) + substr(pos+len, size()-pos-len). | std::out_of_range | if pos + len > size(). |
len == 0: the current rope is returned by sharing its root. Otherwise this is two substr calls plus one concat: see each method's own @note for their individual costs – typically O(log size()) overall, subject to the same rebalance-triggered worst case substr documents. Same strong exception-safety argument as insert(): a failure partway through leaves *this untouched. Definition at line 775 of file tpl_rope.H.
References ah_out_of_range_error_if, Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::concat(), Aleph::Rope< Char, LeafSize >::size(), and Aleph::Rope< Char, LeafSize >::substr().
Referenced by TEST().
|
inline |
Return every character of this rope as an independent Array.
Array<Char> holding a copy of all characters, in order. | std::bad_alloc | or std::overflow_error (from Array::reserve() when size() is extremely large). |
Char, unlike to_string(). Definition at line 790 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::flatten_into(), Aleph::Array< T >::reserve(), Aleph::Rope< Char, LeafSize >::root_, and Aleph::Rope< Char, LeafSize >::size().
Referenced by TEST().
|
inlinestaticprivate |
Definition at line 558 of file tpl_rope.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::flatten_into(), Aleph::Rope< Char, LeafSize >::Node::is_leaf(), Aleph::Rope< Char, LeafSize >::Node::leaf_data, Aleph::Rope< Char, LeafSize >::Node::left, out, and Aleph::Rope< Char, LeafSize >::Node::right.
Referenced by Aleph::Rope< Char, LeafSize >::flatten(), and Aleph::Rope< Char, LeafSize >::flatten_into().
|
inline |
Return a new rope with other inserted at pos.
| [in] | pos | Insertion index. |
| [in] | other | Rope to insert. |
substr(0, pos) + other + substr(pos, size() - pos). pos <= size(). | std::out_of_range | if pos > size(). |
other is empty: the current rope is returned by sharing its root. Otherwise this is two substr calls plus two concat calls: see each method's own @note for their individual costs – typically O(log size()) overall, subject to the same rebalance-triggered worst case substr documents. If this throws (std::bad_alloc from any component call), *this and other are left completely unchanged: every intermediate result here is a new, independent Rope value, so a failure partway through never touches the receiver or the argument. Definition at line 753 of file tpl_rope.H.
References ah_out_of_range_error_if, Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::concat(), Aleph::Rope< Char, LeafSize >::size(), and Aleph::Rope< Char, LeafSize >::substr().
|
inlinestaticprivatenoexcept |
Generous upper bound on the depth a subtree of the given length should have if reasonably balanced – see the file-level "Rebalancing" note for why this (rather than the classical Fibonacci-threshold test) was chosen for this first version.
Definition at line 372 of file tpl_rope.H.
Referenced by Aleph::Rope< Char, LeafSize >::maybe_rebalance().
|
inlinenoexcept |
Check whether this rope holds no characters.
true if size() == 0. | Nothing. |
Definition at line 670 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::root_.
|
inlinestaticprivate |
Wrap two non-null subtrees in a new internal node, then rebalance if the result is deeper than is_balanced() allows.
Never called with a null left/right – callers (concat_nodes) handle the "one
side is the empty rope" case by returning the other side directly.
Definition at line 257 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::make_internal_node(), and Aleph::Rope< Char, LeafSize >::maybe_rebalance().
Referenced by Aleph::Rope< Char, LeafSize >::concat_nodes().
|
inlinestaticprivate |
Raw construction of an internal node from two already-built, non-null subtrees: no rebalancing, just length/depth bookkeeping.
Shared by every call site that assembles an internal node from scratch (make_internal, build_balanced_from_leaves, build_from_view) so the bookkeeping can't drift between them.
Definition at line 232 of file tpl_rope.H.
References ah_overflow_error_if.
Referenced by Aleph::Rope< Char, LeafSize >::build_balanced_from_leaves(), Aleph::Rope< Char, LeafSize >::build_from_view(), and Aleph::Rope< Char, LeafSize >::make_internal().
|
inlinestaticprivate |
Definition at line 217 of file tpl_rope.H.
References Aleph::SmallVector< T, N >::size().
Referenced by Aleph::Rope< Char, LeafSize >::build_from_view(), Aleph::Rope< Char, LeafSize >::slice(), Aleph::Rope< Char, LeafSize >::try_absorb_left(), and Aleph::Rope< Char, LeafSize >::try_absorb_right().
Definition at line 425 of file tpl_rope.H.
References Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::build_balanced_from_leaves(), Aleph::Rope< Char, LeafSize >::collect_leaves(), Aleph::Rope< Char, LeafSize >::is_balanced(), and FunctionalMethods< Container, T >::length().
Referenced by Aleph::Rope< Char, LeafSize >::make_internal().
|
default |
Copy assignment operator: O(1), shares the entire tree.
| [in] | other | Rope to copy. |
*this, now sharing other's tree. | Nothing. |
|
defaultnoexcept |
Move assignment operator.
| [in] | other | Rope to move from; left empty afterwards. |
*this, now holding other's former tree. | Nothing. |
|
inline |
Equality: true iff both ropes have the same length and the same characters in the same order (structural/identity sharing is irrelevant to this comparison).
| [in] | other | Rope to compare against. |
true if the two ropes hold identical character sequences. | std::bad_alloc | or std::overflow_error (from reserving temporary leaf arrays), and anything Char::operator== may throw. |
O(number of
leaves) extra space) and then walks both leaf sequences in lock-step, comparing each pair of overlapping ranges directly – never re-descending from the root the way per-index at() calls would. A leaf pair that is the very same shared node (structural sharing, aligned leaf boundaries) is skipped without touching its characters at all. Definition at line 840 of file tpl_rope.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::collect_leaf_pointers(), Aleph::Rope< Char, LeafSize >::Node::leaf_data, Aleph::Rope< Char, LeafSize >::Node::length, Aleph::Array< T >::reserve(), Aleph::Rope< Char, LeafSize >::root_, and Aleph::Rope< Char, LeafSize >::size().
|
inlinenoexcept |
Return the number of characters in this rope.
| Nothing. |
Definition at line 661 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::root_.
Referenced by Aleph::Rope< Char, LeafSize >::at(), Aleph::Rope< Char, LeafSize >::erase(), Aleph::Rope< Char, LeafSize >::flatten(), Aleph::Rope< Char, LeafSize >::insert(), Aleph::Rope< Char, LeafSize >::operator==(), Aleph::Rope< Char, LeafSize >::substr(), TEST(), and Aleph::Rope< Char, LeafSize >::to_string().
|
inlinestaticprivate |
Extract [pos, pos+len) from node (whose own length is assumed to be >= pos+len) as a new, independently-rooted subtree.
Whole children are returned by shared_ptr copy (O(1), no data touched); only children straddling the [pos, pos+len) boundary are recursed into.
Definition at line 505 of file tpl_rope.H.
References Aleph::and, Aleph::SmallVector< T, N >::append_range(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::concat_nodes(), Aleph::Rope< Char, LeafSize >::make_leaf(), and Aleph::Rope< Char, LeafSize >::slice().
Referenced by Aleph::Rope< Char, LeafSize >::slice(), and Aleph::Rope< Char, LeafSize >::substr().
|
inlinestaticprivate |
Like flatten_into, but appends directly into a std::basic_string (one bulk append per leaf) instead of an Array<Char>, so to_string() does not need a separate Array<Char> -> string copy pass.
Definition at line 576 of file tpl_rope.H.
References out, and Aleph::Rope< Char, LeafSize >::string_append_into().
Referenced by Aleph::Rope< Char, LeafSize >::string_append_into(), and Aleph::Rope< Char, LeafSize >::to_string().
Return a new rope holding [pos, pos+len) of *this.
| [in] | pos | Start index. |
| [in] | len | Number of characters to extract. |
concat_nodes, which – like any other concat – can trigger a rebalance if the rejoined result exceeds the depth threshold; when that happens the affected rejoin costs up to O(number of leaves in
the extracted range) instead of O(1), so the true worst case is closer to O(len / LeafSize) than O(log size()). Still far cheaper than copying the whole rope, but not a hard O(log n) guarantee for every possible range. Definition at line 730 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::Rope(), ah_out_of_range_error_if, Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::root_, Aleph::Rope< Char, LeafSize >::size(), and Aleph::Rope< Char, LeafSize >::slice().
Referenced by Aleph::Rope< Char, LeafSize >::erase(), and Aleph::Rope< Char, LeafSize >::insert().
|
inline |
Return every character of this rope as a std::basic_string.
std::basic_string<Char> holding a copy of all characters. | std::bad_alloc. | |
| std::length_error | if size() exceeds std::basic_string<Char>::max_size(). Unlike a std::string built the ordinary way, a Rope can reach a size() far beyond what any real string could hold while using very little actual memory (structural sharing – see the overflow guard in make_internal_node), so this is reachable in practice, not just a theoretical bound. |
Char has a std::char_traits specialization (char, wchar_t, char8_t, char16_t, char32_t); use flatten() for other Char types. Definition at line 813 of file tpl_rope.H.
References ah_length_error_if, Aleph::Rope< Char, LeafSize >::root_, Aleph::Rope< Char, LeafSize >::size(), and Aleph::Rope< Char, LeafSize >::string_append_into().
Referenced by TEST(), TEST(), TEST(), TEST(), TEST(), and TEST().
|
inlinestaticprivate |
Mirror of try_absorb_right: merge extra into the leftmost leaf of node, for the "prepend one small piece at a time" pattern.
The same depth-preservation argument applies, symmetrically on left.
Definition at line 313 of file tpl_rope.H.
References ah_overflow_error_if, Aleph::SmallVector< T, N >::append_range(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::make_leaf(), and Aleph::Rope< Char, LeafSize >::try_absorb_left().
Referenced by Aleph::Rope< Char, LeafSize >::concat_nodes(), and Aleph::Rope< Char, LeafSize >::try_absorb_left().
|
inlinestaticprivate |
Try to merge extra into the rightmost leaf of node, sharing every other node unchanged.
Returns an empty NodePtr if node is null or its rightmost leaf has no spare room for extra (the caller then falls back to a normal concat). This never changes any node's depth: by induction on the recursion, node->right is replaced by a new_right of the exact same depth (base case: leaf -> leaf, depth 0; inductive case: new_right's own recursive call already preserved its depth) while node->left is shared verbatim – so 1 + max(depth(left), depth(new_right)) equals node->depth exactly, regardless of which side held the max (see concat_nodes for why this means absorption never needs maybe_rebalance).
Definition at line 273 of file tpl_rope.H.
References ah_overflow_error_if, Aleph::SmallVector< T, N >::append_range(), Aleph::blossom_maximum_cardinality_matching(), Aleph::Rope< Char, LeafSize >::make_leaf(), and Aleph::Rope< Char, LeafSize >::try_absorb_right().
Referenced by Aleph::Rope< Char, LeafSize >::concat_nodes(), and Aleph::Rope< Char, LeafSize >::try_absorb_right().
|
inlinenoexcept |
Check this rope's internal structural invariants.
Debug/test helper, not part of the regular contract – mirrors the verify()/check_invariants() self-checks other Aleph-w tree types expose (tpl_radix_tree.H, tpl_patricia_trie.H, tpl_rb_tree.H, tpl_avl.H). Content-only tests (comparing to_string() against a reference) cannot detect a violation of these invariants, since none of them are individually observable through the public API; calling verify() after mutating operations in a test gives that coverage directly.
true if every leaf's length matches its stored data and is in [1, LeafSize]; every internal node has two non-null children; every internal node's length equals the sum of its children's; and every internal node's depth equals 1 + max(child depths). | Nothing. |
r = r.concat(r)) it walks every root-to-leaf path rather than every distinct node – up to O(2^depth) instead of O(depth) for that specific construction pattern. Not a concern for ordinary usage (sharing between otherwise-independent ropes, the common case) – only for a rope that shares itself with itself many levels deep. Definition at line 927 of file tpl_rope.H.
References Aleph::Rope< Char, LeafSize >::root_, and Aleph::Rope< Char, LeafSize >::verify_rec().
|
inlinestaticprivatenoexcept |
Recursive structural-invariant check backing the public verify().
Checks, at every node: a leaf has a non-null leaf_data whose length matches its stored data and is in [1, LeafSize] (leaves are never empty – no code path ever builds one); an internal node holds no leaf_data (see the Node::leaf_data comment: only leaves ever pay for a buffer) and has two non-null children, length equal to the sum of its children's, and depth equal to 1 + max(child depths).
Definition at line 598 of file tpl_rope.H.
References Aleph::and, Aleph::blossom_maximum_cardinality_matching(), and Aleph::Rope< Char, LeafSize >::verify_rec().
Referenced by Aleph::Rope< Char, LeafSize >::verify(), and Aleph::Rope< Char, LeafSize >::verify_rec().
|
private |
Definition at line 215 of file tpl_rope.H.
Referenced by Aleph::Rope< Char, LeafSize >::at(), Aleph::Rope< Char, LeafSize >::concat(), Aleph::Rope< Char, LeafSize >::flatten(), Aleph::Rope< Char, LeafSize >::is_empty(), Aleph::Rope< Char, LeafSize >::operator==(), Aleph::Rope< Char, LeafSize >::size(), Aleph::Rope< Char, LeafSize >::substr(), Aleph::Rope< Char, LeafSize >::to_string(), and Aleph::Rope< Char, LeafSize >::verify().