# It is memory-efficient but relies on `has` so may be CPU-inefficient for some kind of collections.
fun has_all(other: Collection[nullable Object]): Bool
do
+ if is_same_instance(other) then return true
+ var ol = other.length
+ var l = length
+ if ol == 0 then return true
+ if l == 0 then return false
+ if ol == 1 then return has(other.first)
for x in other do if not has(x) then return false
return true
end
redef fun next_by(step) do real.next_by(step * self.step)
end
+# An iterator that lazyly cache the current item.
+#
+# This class can be used as an helper to build simple iterator with a single and simplier `next_item` method.
+# The only constraint is that `next_item` returns null on the last item, so `null` cannot be a valid element.
+abstract class CachedIterator[E: Object]
+ super Iterator[E]
+
+ # Get the next item if any.
+ # Returns null if there is no next item.
+ fun next_item: nullable E is abstract
+
+ # The last item effectively read.
+ # `null` if on start, after a next of if no more items are available.
+ protected var cache: nullable E = null
+
+ # The current item, if any.
+ # If not, the cache is effectively filled (with `next_item`).
+ # Return `null` iff there is no more elements.
+ protected fun current_item: nullable E
+ do
+ var cache = self.cache
+ if cache != null then return cache
+ cache = next_item
+ self.cache = cache
+ return cache
+ end
+
+ redef fun item do return current_item.as(not null)
+
+ redef fun is_ok do return current_item != null
+
+ redef fun next do
+ # If needed, fill the cache (an consume the current element)
+ current_item
+ # Empty the cache (so the next element will be read)
+ cache = null
+ end
+end
+
# A collection that contains only one item.
#
# Used to pass arguments by reference.
interface SimpleCollection[E]
super RemovableCollection[E]
- # Add an item in a collection.
+ # Add `item` to this collection.
#
# var a = [1,2]
# a.add 3
fun add(item: E) is abstract
# Add each item of `coll`.
+ #
# var a = [1,2]
# a.add_all([3..5])
# assert a.has(4) == true
var res = 23 + length
# Note: the order of the elements must not change the hash value.
# So, unlike usual hash functions, the accumulator is not combined with itself.
- for e in self do res += e.hash
+ for e in self do
+ if e != null then res += e.hash
+ end
return res
end
# Add each (key,value) of `map` into `self`.
# If a same key exists in `map` and `self`, then the value in self is discarded.
#
- # It is the analogous of `SimpleCollection::add_all`
- #
# var x = new HashMap[String, Int]
# x["four"] = 4
# x["five"] = 5
# var y = new HashMap[String, Int]
# y["four"] = 40
# y["nine"] = 90
- # x.recover_with y
+ # x.add_all y
# assert x["four"] == 40
# assert x["five"] == 5
# assert x["nine"] == 90
- fun recover_with(map: MapRead[K, V])
+ fun add_all(map: MapRead[K, V])
do
var i = map.iterator
while i.is_ok do
end
end
+ # Alias for `add_all`
+ fun recover_with(map: MapRead[K, V]) is deprecated do add_all(map)
+
# Remove all items
#
# var x = new HashMap[String, Int]
end
end
+ # Try to get an element, return `null` if the `index` is invalid.
+ #
+ # ~~~
+ # var a = [10,20,30]
+ # assert a.get_or_null(1) == 20
+ # assert a.get_or_null(3) == null
+ # assert a.get_or_null(-1) == null
+ # assert a.get_or_null(-10) == null
+ # ~~~
+ fun get_or_null(index: Int): nullable E
+ do
+ if index >= 0 and index < length then return self[index]
+ return null
+ end
+
+ # Try to get an element, return `default` if the `index` is invalid.
+ #
+ # ~~~
+ # var a = [10,20,30]
+ # assert a.get_or_default(1, -1) == 20
+ # assert a.get_or_default(3, -1) == -1
+ # assert a.get_or_default(-1, -1) == -1
+ # assert a.get_or_default(-10, -1) == -1
+ # ~~~
+ fun get_or_default(index: Int, default: E): E
+ do
+ if index >= 0 and index < length then return self[index]
+ return default
+ end
+
# Get the last item.
# Is equivalent with `self[length-1]`.
#
#
# REQUIRE `index >= 0 and index < length`
fun remove_at(index: Int) is abstract
+
+ # Rotates the elements of self once to the left
+ #
+ # ~~~nit
+ # var a = [12, 23, 34, 45]
+ # a.rotate_left
+ # assert a == [23, 34, 45, 12]
+ # ~~~
+ fun rotate_left do
+ var fst = shift
+ push fst
+ end
+
+ # Rotates the elements of self once to the right
+ #
+ # ~~~nit
+ # var a = [12, 23, 34, 45]
+ # a.rotate_right
+ # assert a == [45, 12, 23, 34]
+ # ~~~
+ fun rotate_right do
+ var lst = pop
+ unshift lst
+ end
end
# Iterators on indexed collections.