High-level text containers.
Ropes are a high-level representation of text that offers much better performance than strings for common operations, and generally reduce memory allocations and copies, while only entailing a small degradation of less common operations.
More precisely, where a string is represented as a memory buffer, a rope is a tree structure whose leaves are slices of immutable strings. Therefore, concatenation, appending, prepending, substrings, etc. are operations that require only trivial tree manipulation, generally without having to copy memory. In addition, the tree structure of ropes makes them suitable as a form of index to speed-up access to Unicode characters by index in long chunks of text.
The following operations are algorithmically faster in ropes:
access to a character by index is logarithmic (linear in strings);
rope
- The type of ropes.append_char
- Add one char to the end of the ropeappend_rope
- Concatenate two ropesappend_str
- Add one string to the end of the ropebal
- Balance a rope.byte_len
- The number of bytes in the ropechar_at
- The character at position pos
char_len
- The number of character in the ropecmp
- Compare two ropes by Unicode lexicographical order.concat
- Concatenate many ropes.empty
- Create an empty ropeeq
- Returns true
if both ropes have the same content (regardless of their structure), false
otherwisege
- # Argumentsgt
- # Argumentsheight
- Returns the height of the rope.iter_chars
- Loop through a rope, char by char, until the end.le
- # Argumentsloop_chars
- Loop through a rope, char by charloop_leaves
- Loop through a rope, string by stringlt
- # Argumentsof_str
- Adopt a string as a rope.of_substr
- As of_str
but for a substring.prepend_char
- Add one char to the beginning of the ropeprepend_str
- Add one string to the beginning of the ropesub_bytes
- Extract a subrope from a rope.sub_chars
- Extract a subrope from a rope.rope::iterator
rope
type rope = node::root
The type of ropes.
append_char
fn append_char(rope: rope, char: char) -> rope
Add one char to the end of the rope
append_rope
fn append_rope(left: rope, right: rope) -> rope
Concatenate two ropes
append_str
fn append_str(rope: rope, str: @str) -> rope
Add one string to the end of the rope
bal
fn bal(rope: rope) -> rope
Balance a rope.
A copy of the rope in which small nodes have been grouped in memory, and with a reduced height.
If you perform numerous rope concatenations, it is generally a good idea to rebalance your rope at some point, before using it for other purposes.
byte_len
pure fn byte_len(rope: rope) -> uint
The number of bytes in the rope
Constant time.
char_at
fn char_at(rope: rope, pos: uint) -> char
The character at position pos
The function will fail if pos
is not a valid position in the rope.
This function executes in a time proportional to the height of the rope + the (bounded) length of the largest leaf.
char_len
pure fn char_len(rope: rope) -> uint
The number of character in the rope
Constant time.
cmp
fn cmp(left: rope, right: rope) -> int
Compare two ropes by Unicode lexicographical order.
This function compares only the contents of the rope, not their structure.
A negative value if left < right
, 0 if eq(left, right) or a positive value if left > right
concat
fn concat(v: ~[rope]) -> rope
Concatenate many ropes.
If the ropes are balanced initially and have the same height, the resulting rope remains balanced. However, this function does not take any further measure to ensure that the result is balanced.
empty
fn empty() -> rope
Create an empty rope
eq
fn eq(left: rope, right: rope) -> bool
Returns true
if both ropes have the same content (regardless of their structure), false
otherwise
ge
fn ge(left: rope, right: rope) -> bool
true
if left >= right
in lexicographical order (regardless of their structure), false
otherwise
gt
fn gt(left: rope, right: rope) -> bool
true
if left > right
in lexicographical order (regardless of their structure), false
otherwise
height
fn height(rope: rope) -> uint
Returns the height of the rope.
The height of the rope is a bound on the number of operations which must be performed during a character access before finding the leaf in which a character is contained.
Constant time.
iter_chars
fn iter_chars(rope: rope, it: fn(char))
Loop through a rope, char by char, until the end.
le
fn le(left: rope, right: rope) -> bool
true
if left <= right
in lexicographical order (regardless of their structure), false
otherwise
loop_chars
fn loop_chars(rope: rope, it: fn(char) -> bool) -> bool
Loop through a rope, char by char
While other mechanisms are available, this is generally the best manner of looping through the contents of a rope char by char. If you prefer a loop that iterates through the contents string by string (e.g. to print the contents of the rope or output it to the system), however, you should rather use traverse_components
.
true
to continue, false
to stop.true
If execution proceeded correctly, false
if it was interrupted, that is if it
returned false
at any point.
loop_leaves
fn loop_leaves(rope: rope, it: fn(node::leaf) -> bool) -> bool
Loop through a rope, string by string
While other mechanisms are available, this is generally the best manner of looping through the contents of a rope string by string, which may be useful e.g. to print strings as you see them (without having to copy their contents into a new string), to send them to then network, to write them to a file, etc.. If you prefer a loop that iterates through the contents char by char (e.g. to search for a char), however, you should rather use traverse
.
true
to continue, false
to stoptrue
If execution proceeded correctly, false
if it was interrupted, that is if it
returned false
at any point.
lt
fn lt(left: rope, right: rope) -> bool
true
if left < right
in lexicographical order (regardless of their structure), false
otherwise
of_str
fn of_str(str: @str) -> rope
Adopt a string as a rope.
A rope representing the same string as str
. Depending of the length of str
, this rope may be empty, flat or complex.
of_substr
fn of_substr(str: @str, byte_offset: uint, byte_len: uint) -> rope
As of_str
but for a substring.
str
at which the rope starts.str
to use.A rope representing the same string as str::substr(str, byte_offset, byte_len)
. Depending on byte_len
, this rope may be empty, flat or complex.
This operation does not copy the substring.
byte_offset
or byte_len
do not match str
.prepend_char
fn prepend_char(rope: rope, char: char) -> rope
Add one char to the beginning of the rope
prepend_str
fn prepend_str(rope: rope, str: @str) -> rope
Add one string to the beginning of the rope
sub_bytes
fn sub_bytes(rope: rope, byte_offset: uint, byte_len: uint) -> rope
Extract a subrope from a rope.
sub_chars
fn sub_chars(rope: rope, char_offset: uint, char_len: uint) -> rope
Extract a subrope from a rope.