end
end
+ # Escape string used in labels for graphviz
+ #
+ # assert ">><<".escape_to_dot == "\\>\\>\\<\\<"
+ fun escape_to_dot: String
+ do
+ return escape_more_to_c("|\{\}<>")
+ end
+
# Flat representation of self
fun flatten: FlatText is abstract
abstract class FlatText
super Text
- private var items: NativeString
+ # Underlying C-String (`char*`)
+ #
+ # Warning : Might be void in some subclasses, be sure to check
+ # if set before using it.
+ private var items: NativeString is noinit
# Real items, used as cache for to_cstring is called
private var real_items: nullable NativeString = null
fun insert_at(s: String, pos: Int): SELFTYPE is abstract
+ redef fun substrings: Iterator[String] is abstract
+
# Returns a reversed version of self
#
# assert "hello".reversed == "olleh"
super String
# Index in _items of the start of the string
- private var index_from: Int
+ private var index_from: Int is noinit
# Indes in _items of the last item of the string
- private var index_to: Int
+ private var index_to: Int is noinit
redef var chars: SequenceRead[Char] = new FlatStringCharView(self)
redef fun to_cstring: NativeString
do
- if real_items != null then return real_items.as(not null)
- if index_from > 0 or index_to != items.cstring_length - 1 then
+ if real_items != null then
+ return real_items.as(not null)
+ else
var newItems = calloc_string(length + 1)
self.items.copy_to(newItems, length, index_from, 0)
newItems[length] = '\0'
self.real_items = newItems
return newItems
end
- return items
end
redef fun ==(other)
# Specific implementations MUST set this to `true` in order to invalidate caches
protected var is_dirty = true
+ # Copy-On-Write flag
+ #
+ # If the `Buffer` was to_s'd, the next in-place altering
+ # operation will cause the current `Buffer` to be re-allocated.
+ #
+ # The flag will then be set at `false`.
+ protected var written = false
+
# Modifies the char contained at pos `index`
#
# DEPRECATED : Use self.chars.[]= instead
redef fun substrings do return new FlatSubstringsIter(self)
+ # Re-copies the `NativeString` into a new one and sets it as the new `Buffer`
+ #
+ # This happens when an operation modifies the current `Buffer` and
+ # the Copy-On-Write flag `written` is set at true.
+ private fun reset do
+ var nns = new NativeString(capacity)
+ items.copy_to(nns, length, 0, 0)
+ items = nns
+ written = false
+ end
+
redef fun [](index)
do
assert index >= 0
add(item)
return
end
+ if written then reset
assert index >= 0 and index < length
items[index] = item
end
redef fun clear do
is_dirty = true
+ if written then reset
length = 0
end
var c = capacity
if cap <= c then return
while c <= cap do c = c * 2 + 2
+ # The COW flag can be set at false here, since
+ # it does a copy of the current `Buffer`
+ written = false
var a = calloc_string(c+1)
if length > 0 then items.copy_to(a, length, 0, 0)
items = a
redef fun to_s: String
do
- return to_cstring.to_s_with_length(length)
+ written = true
+ if length == 0 then items = new NativeString(1)
+ return new FlatString.with_infos(items, length, 0, length - 1)
end
redef fun to_cstring
redef fun reverse
do
+ written = false
var ns = calloc_string(capacity)
var si = length - 1
var ni = 0
redef fun upper
do
+ if written then reset
var it = items
var id = length - 1
while id >= 0 do
redef fun lower
do
+ if written then reset
var it = items
var id = length - 1
while id >= 0 do
fun to_s_with_length(length: Int): FlatString
do
assert length >= 0
- return new FlatString.with_infos(self, length, 0, length - 1)
+ var str = new FlatString.with_infos(self, length, 0, length - 1)
+ return str
end
fun to_s_with_copy: FlatString
var length = cstring_length
var new_self = calloc_string(length + 1)
copy_to(new_self, length, 0, 0)
- return new FlatString.with_infos(new_self, length, 0, length - 1)
+ var str = new FlatString.with_infos(new_self, length, 0, length - 1)
+ new_self[length] = '\0'
+ str.real_items = new_self
+ return str
end
end
#
# Note: it caching is not usefull, see `alpha_comparator`
class CachedAlphaComparator
- super Comparator[Object]
+ super Comparator
+ redef type COMPARED: Object
private var cache = new HashMap[Object, String]
# see `alpha_comparator`
private class AlphaComparator
- super Comparator[Object]
+ super Comparator
redef fun compare(a, b) do return a.to_s <=> b.to_s
end
# var a = [1, 2, 3, 10, 20]
# alpha_comparator.sort(a)
# assert a == [1, 10, 2, 20, 3]
-fun alpha_comparator: Comparator[Object] do return once new AlphaComparator
+fun alpha_comparator: Comparator do return once new AlphaComparator
# The arguments of the program as given by the OS
fun args: Sequence[String]