stdlib/strings: Introduced virtual types for Text classes, used later for factorization.
[nit.git] / lib / standard / string.nit
index e4c9fe4..d808851 100644 (file)
@@ -27,6 +27,15 @@ intrude import collection # FIXME should be collection::array
 
 # High-level abstraction for all text representations
 abstract class Text
+       super Comparable
+
+       redef type OTHER: Text
+
+       # Type of the view on self (.chars)
+       type SELFVIEW: StringCharView
+
+       # Type of self (used for factorization of several methods, ex : substring_from, empty...)
+       type SELFTYPE: Text
 
        # Gets a view on the chars of the Text object
        fun chars: StringCharView is abstract
@@ -421,10 +430,24 @@ abstract class Text
                return res.to_s
        end
 
+       redef fun ==(o)
+       do
+               if o == null then return false
+               if not o isa Text then return false
+               if self.is_same_instance(o) then return true
+               if self.length != o.length then return false
+               return self.chars == o.chars
+       end
+
+       redef fun <(o)
+       do
+               return self.chars < o.chars
+       end
+
 end
 
-# Common subclass for String and Buffer
-abstract class AbstractString
+# All kinds of array-based text representations.
+abstract class FlatText
        super Text
 
        private var items: NativeString
@@ -447,9 +470,12 @@ end
 # views on String and Buffer objects
 abstract class StringCharView
        super SequenceRead[Char]
+       super Comparable
 
        type SELFTYPE: Text
 
+       redef type OTHER: StringCharView
+
        private var target: SELFTYPE
 
        private init(tgt: SELFTYPE)
@@ -507,6 +533,36 @@ abstract class StringCharView
                return false
        end
 
+       redef fun ==(other)
+       do
+               if other == null then return false
+               if not other isa StringCharView then return false
+               var other_chars = other.iterator
+               for i in self do
+                       if i != other_chars.item then return false
+                       other_chars.next
+               end
+               return true
+       end
+
+       redef fun <(other)
+       do
+               var self_chars = self.iterator
+               var other_chars = other.iterator
+
+               while self_chars.is_ok and other_chars.is_ok do
+                       if self_chars.item < other_chars.item then return true
+                       if self_chars.item > other_chars.item then return false
+                       self_chars.next
+                       other_chars.next
+               end
+
+               if self_chars.is_ok then
+                       return false
+               else
+                       return true
+               end
+       end
 end
 
 # View on Buffer objects, extends Sequence
@@ -521,11 +577,11 @@ end
 
 # Immutable strings of characters.
 class String
-       super Comparable
-       super AbstractString
+       super FlatText
        super StringCapable
 
-       redef type OTHER: String
+       redef type SELFTYPE: String
+       redef type SELFVIEW: FlatStringCharView
 
        # Index in _items of the start of the string
        private var index_from: Int
@@ -664,7 +720,7 @@ class String
 
        redef fun ==(other)
        do
-               if not other isa String then return false
+               if not other isa String then return super
 
                if self.object_id == other.object_id then return true
 
@@ -694,6 +750,8 @@ class String
        #     assert ("aa" < "b")      ==  true
        redef fun <(other)
        do
+               if not other isa String then return super
+
                if self.object_id == other.object_id then return false
 
                var my_curr_char : Char
@@ -872,6 +930,9 @@ end
 abstract class Buffer
        super Text
 
+       redef type SELFVIEW: BufferCharView
+       redef type SELFTYPE: Buffer
+
        # Modifies the char contained at pos `index`
        #
        # DEPRECATED : Use self.chars.[]= instead
@@ -896,12 +957,12 @@ end
 
 # Mutable strings of characters.
 class FlatBuffer
-       super AbstractString
-       super Comparable
+       super FlatText
        super StringCapable
        super Buffer
 
-       redef type OTHER: String
+       redef type SELFVIEW: FlatBufferCharView
+       redef type SELFTYPE: FlatBuffer
 
        redef var chars: FlatBufferCharView = new FlatBufferCharView(self)
 
@@ -950,28 +1011,6 @@ class FlatBuffer
                return a.to_s_with_length(length)
        end
 
-       redef fun <(s)
-       do
-               var i = 0
-               var l1 = length
-               var l2 = s.length
-               while i < l1 and i < l2 do
-                       var c1 = self.chars[i].ascii
-                       var c2 = s.chars[i].ascii
-                       if c1 < c2 then
-                               return true
-                       else if c2 < c1 then
-                               return false
-                       end
-                       i += 1
-               end
-               if l1 < l2 then
-                       return true
-               else
-                       return false
-               end
-       end
-
        # Create a new empty string.
        init
        do
@@ -1004,21 +1043,6 @@ class FlatBuffer
                length += sl
        end
 
-       redef fun ==(o)
-       do
-               if not o isa FlatBuffer then return false
-               var l = length
-               if o.length != l then return false
-               var i = 0
-               var it = items
-               var oit = o.items
-               while i < l do
-                       if it[i] != oit[i] then return false
-                       i += 1
-               end
-               return true
-       end
-
        # Copies the content of self in `dest`
        fun copy(start: Int, len: Int, dest: Buffer, new_start: Int)
        do