# Root node, entry point of a Rope.
private var root: RopeNode
+ # Cached version of self as a flat String
+ private var str_representation: nullable NativeString = null
+
# Empty Rope
init do from("")
# Iterator on the substrings, starting at position `from`, in forward order
fun substrings_from(from: Int): IndexedIterator[Text] do return new SubstringsIterator(self, from)
+ redef fun to_cstring
+ do
+ if str_representation != null then return str_representation.as(not null)
+
+ var native_final_str = calloc_string(length + 1)
+
+ native_final_str[length] = '\0'
+
+ if self.length == 0 then
+ str_representation = native_final_str
+ return native_final_str
+ end
+
+ var offset = 0
+
+ for i in substrings do
+ var str = i.flatten
+ if str isa FlatString then str.items.copy_to(native_final_str, str.length, str.index_from, offset)
+ offset += i.length
+ end
+
+ str_representation = native_final_str
+
+ return native_final_str
+ end
+
# Path to the Leaf for `position`
private fun node_at(position: Int): Path
do
end
end
+ redef fun ==(o)
+ do
+ if not o isa Text then return false
+ if o.length != self.length then return false
+ var oit = o.chars.iterator
+ for i in self.chars.iterator do
+ if i != oit.item then return false
+ oit.next
+ end
+ return true
+ end
end
# Rope that cannot be modified
redef fun to_s do return self
+ redef fun empty do return once new RopeString.from("")
+
+ redef fun reversed
+ do
+ var ret = empty.as(RopeString)
+ for i in substrings do
+ ret = ret.prepend(i.reversed.to_s).as(RopeString)
+ end
+ return ret
+ end
+
+ redef fun to_upper
+ do
+ var ret = empty
+ for i in substrings do
+ ret += i.to_upper
+ end
+ return ret
+ end
+
+ redef fun to_lower
+ do
+ var ret = empty
+ for i in substrings do
+ ret += i.to_lower
+ end
+ return ret
+ end
+
+ redef fun +(o) do return insert_at(o.to_s, length)
+
+ redef fun *(n)
+ do
+ var ret = new RopeString.from("")
+ for i in [0..n[ do
+ ret = (ret + self).as(RopeString)
+ end
+ return ret
+ end
+
# Inserts a String `str` at position `pos`
fun insert_at(str: String, pos: Int): RopeString
do
return new RopeString.from_root(last_concat)
end
+ # Adds `s` at the beginning of self
+ fun prepend(s: String): String do return insert_at(s, 0)
+
# Adds `s` at the end of self
fun append(s: String): String
do