# This file is part of NIT ( http://www.nitlanguage.org ). # # Copyright 2004-2008 Jean Privat # # This file is free software, which comes along with NIT. This software is # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. You can modify it is you want, provided this header # is kept unaltered, and a notification of the changes is added. # You are allowed to redistribute it and sell it, alone or is a part of # another product. # This module define several abtract collection classes. package abstract_collection import kernel # The root of the collection hierarchy. # # Instances of this class offers an iterator method. # # Colections instances can use the "for" structure: # var x: Collection[U] # ... # for u in x do # # u is a U # ... # end # that is equivalent with # var x: Collection[U] # ... # var i = x.iterator # while i.is_ok do # var u = i.item # u is a U # ... # i.next # end # # This abstract class implements its others methods with an iterator. # Subclasses may redefine them with an efficient implementation. interface Collection[E] # Get a new iterator on the collection. fun iterator: Iterator[E] is abstract # Is there no item in the collection ? fun is_empty: Bool is abstract # Number of items in the collection. fun length: Int is abstract # Is `item' in the collection ? # Comparaisons are done with == fun has(item: E): Bool is abstract # Is the collection contain only `item' ? # Comparaisons are done with == # Return true if the collection is empty. fun has_only(item: E): Bool is abstract # How many occurences of `item' are in the collection ? # Comparaisons are done with == fun count(item: E): Int is abstract # Return one the item of the collection fun first: E is abstract end # Naive implementation of collections method # You only have to define iterator! interface NaiveCollection[E] special Collection[E] redef fun is_empty do return length == 0 redef fun length do var nb = 0 for i in self do nb += nb return nb end redef fun has(item) do for i in self do if i == item then return true return false end redef fun has_only(item) do for i in self do if i != item then return false return true end redef fun count(item) do var nb = 0 for i in self do if i == item then nb += 1 return nb end redef fun first do assert length > 0 return iterator.item end end # Instances of the Iterator class generates a series of elements, one at a time. # They are mainly used with collections. interface Iterator[E] # The current item. # Require `is_ok'. fun item: E is abstract # Jump to the next item. # Require `is_ok'. fun next is abstract # Is there a current item ? fun is_ok: Bool is abstract end # A collection that contains only one item. class Container[E] special Collection[E] redef fun first do return _item redef fun is_empty do return false redef fun length do return 1 redef fun has(an_item) do return _item == an_item redef fun has_only(an_item) do return _item == an_item redef fun count(an_item) do if _item == an_item then return 1 else return 0 end end redef fun iterator do return new ContainerIterator[E](self) # Create a new instance with a given initial value. init(e: E) do _item = e # The stored item readable writable var _item: E end # This iterator is quite stupid since it is used for only one item. class ContainerIterator[E] special Iterator[E] redef fun item do return _container.item redef fun next do _is_ok = false init(c: Container[E]) do _container = c redef readable var _is_ok: Bool = true var _container: Container[E] end # Items can be removed from this collection interface RemovableCollection[E] special Collection[E] # Remove all items fun clear is abstract # Remove an occucence of `item' fun remove(item: E) is abstract # Remove all occurences of `item' fun remove_all(item: E) do while has(item) do remove(item) end # Items can be added to these collections. interface SimpleCollection[E] special RemovableCollection[E] # Add an item in a collection. # Ensure col.has(item) fun add(item: E) is abstract # Add each item of `coll`. fun add_all(coll: Collection[E]) do for i in coll do add(i) end # Abstract sets. # # Set contains contains only one element with the same value (according to =). # var s : Set[E] # var a = "Hello" # var b = "Hello" # ... # s.add(a) # s.has(b) # --> true interface Set[E] special SimpleCollection[E] redef fun has_only(item) do var l = length if l == 1 then return has(item) else if l == 0 then return true else return false end end # Only 0 or 1 redef fun count(item) do if has(item) then return 1 else return 0 end end # Synonym of remove since there is only one item redef fun remove_all(item) do remove(item) end interface MapRead[K, E] special Collection[E] # Get the item at `key'. fun [](key: K): E is abstract # Is there an item at `key'. fun has_key(key: K): Bool is abstract redef fun iterator: MapIterator[K, E] is abstract end # Maps are associative collections: `key' -> `item'. # # The main operator over maps is []. # # var map: Map[U, V] # ... # map[u1] = v1 # Associate 'v1' to 'u1' # map[u2] = v2 # Associate 'v2' to 'u2' # map[u1] # -> v1 # map[u2] # -> v2 # map.has_key(u1) # -> true # map.has_key(u3) # -> false interface Map[K, E] special RemovableCollection[E] special MapRead[K, E] # Set the`item' at `key'. fun []=(key: K, item: E) is abstract # Remove the item at `key' fun remove_at(key: K) is abstract # Add each (key,value) of `map' into `self'. # If a same key exists in `map' and `self', then the value in self is discarded. fun recover_with(map: Map[K, E]) do var i = map.iterator while i.is_ok do self[i.key] = i.item i.next end end end # Iterators for Map. interface MapIterator[K, E] special Iterator[E] # The key of the current item. fun key: K is abstract # Set a new `item' at `key'. #fun item=(item: E) is abstract end # Indexed collection are ordoned collections. # The first item is 0. The last is `length'-1. interface IndexedCollectionRead[E] special MapRead[Int, E] # Get the first item. # Is equivalent with `self'[0]. redef fun first do assert not_empty: not is_empty return self[0] end # Get the last item. # Is equivalent with `self'[`length'-1]. fun last: E do assert not_empty: not is_empty return self[length-1] end # Return the index of the first occurence of `item'. # Return -1 if `item' is not found fun index_of(item: E): Int do var i = iterator while i.is_ok do if i.item == item then return i.index i.next end return -1 end redef fun iterator: IndexedIterator[E] is abstract end # Indexed collection are ordoned collections. # The first item is 0. The last is `length'-1. interface IndexedCollection[E] special IndexedCollectionRead[E] special Map[Int, E] special SimpleCollection[E] # Set the first item. # Is equivalent with `self'[0] = `item'. fun first=(item: E) do self[0] = item end # Set the last item. # Is equivalent with `self'[length-1] = `item'. fun last=(item: E) do var l = length if l > 0 then self[l-1] = item else self[0] = item end end # A synonym of `push' redef fun add(e) do push(e) # Add an item after the last. fun push(e: E) is abstract # Add each item of `coll` after the last. fun append(coll: Collection[E]) do for i in coll do push(i) # Remove the last item. fun pop: E is abstract # Add an item before the last. fun unshift(e: E) is abstract # Remove the first item. # The second item become the first. fun shift: E is abstract end # Iterators on indexed collections. interface IndexedIterator[E] special MapIterator[Int, E] # The index of the current item. fun index: Int is abstract # A synonym of index. redef fun key do return index end # Associatives arrays that internally uses couples to represent each (key, value) pairs. interface CoupleMap[K, E] special Map[K, E] # Return the couple of the corresponding key # Return null if the key is no associated element protected fun couple_at(key: K): nullable Couple[K, E] is abstract redef fun [](key) do var c = couple_at(key) if c == null then abort else return c.second end end redef fun has_key(key) do return couple_at(key) != null end # Iterator on CoupleMap # # Actually is is a wrapper around an iterator of the internal array of the map. class CoupleMapIterator[K, E] special MapIterator[K, E] redef fun item do return _iter.item.second #redef fun item=(e) do _iter.item.second = e redef fun key do return _iter.item.first redef fun is_ok do return _iter.is_ok redef fun next do _iter.next end var _iter: Iterator[Couple[K,E]] init(i: Iterator[Couple[K,E]]) do _iter = i end # Some tools ################################################################### # Two objects in a simple structure. class Couple[F, S] # The first element of the couple. readable writable var _first: F # The second element of the couple. readable writable var _second: S # Create a new instance with a first and a second object. init(f: F, s: S) do _first = f _second = s end end