Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/rope/rope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,27 @@ impl Rope {
is_grapheme_boundary(self.chunks(), self.byte_len(), byte_offset)
}

/// Returns true if this rope and `other` point to precisely the same
/// in-memory data.
///
/// This happens when one of the ropes is a clone of the other and
/// neither have been modified since then. Because clones initially
/// share all the same data, it can be useful to check if they still
/// point to precisely the same memory as a way of determining
/// whether they are both still unmodified.
///
/// Note: this is distinct from checking for equality: two ropes can
/// have the same *contents* (equal) but be stored in different
/// memory locations (not instances). Importantly, two clones that
/// post-cloning are modified identically will *not* be instances
/// anymore, even though they will have equal contents.
///
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent w/ all the other public methods we should add an # Examples section to show in code how this works.

/// Runs in O(1) time.
Copy link
Collaborator

@noib3 noib3 Jul 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This time complexity can be removed since none of the other methods mention theirs.

#[inline]
pub fn is_instance(&self, other: &Self) -> bool {
self.tree.is_instance(&other.tree)
}

/// Returns the line at `line_index`, without its line terminator.
///
/// If you want to include the line break consider taking a
Expand Down
6 changes: 6 additions & 0 deletions src/tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ impl<const ARITY: usize, L: Leaf> Tree<ARITY, L> {
Self { root: Arc::new(Node::Internal(root)) }
}

/// Returns `true` if the two roots point to the same allocation.
#[inline]
pub fn is_instance(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.root, &other.root)
}

/// Returns the leaf containing the `measure`-th unit of the `M`-metric,
/// plus the `M`-measure of all the leaves before it.
#[inline]
Expand Down
18 changes: 18 additions & 0 deletions tests/rope_indexing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ fn rope_is_char_boundary() {
}
}

#[cfg_attr(miri, ignore)]
#[test]
fn rope_is_instance() {
let r = Rope::from("Hello there!");
let mut c1 = r.clone();
let c2 = c1.clone();

assert!(r.is_instance(&c1));
assert!(r.is_instance(&c2));
assert!(c1.is_instance(&c2));

c1.insert(0, "Oh! ");

assert!(!r.is_instance(&c1));
assert!(r.is_instance(&c2));
assert!(!c1.is_instance(&c2));
}

/// ```
/// Root
/// ├───┐
Expand Down