# 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
for e in self do if self.count(e) != other.count(e) then return false
return true
end
+
+ # Does the collection contain at least one element of `other`?
+ #
+ # assert [1,3,4,2].has_any([1..10]) == true
+ # assert [1,3,4,2].has_any([5..10]) == false
+ #
+ # Note that the default implementation is general and correct for any lawful Collections.
+ # It is memory-efficient but relies on `has` so may be CPU-inefficient for some kind of collections.
+ fun has_any(other: Collection[nullable Object]): Bool
+ do
+ for o in other do
+ if has(o) then return true
+ end
+ return false
+ end
end
# Iterators generate a series of elements, one at a time.
# Iterate over `self`
fun iterator: Iterator[E] do return self
+ # Pre-iteration hook.
+ #
+ # Used to inform `self` that the iteration is starting.
+ # Specific iterators can use this to prepare some resources.
+ #
+ # Is automatically invoked at the beginning of `for` structures.
+ #
+ # Do nothing by default.
+ fun start do end
+
# Post-iteration hook.
#
# Used to inform `self` that the iteration is over.
# assert s.has(b) == true
interface Set[E]
super SimpleCollection[E]
+ super Cloneable
redef fun has_only(item)
do
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
return nhs
end
+ redef fun clone do return union(self)
+
# Returns a new instance of `Set`.
#
# Depends on the subclass, mainly used for copy services
# 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]
# Set a new `item` at `key`.
#fun item=(item: E) is abstract
+ # Pre-iteration hook.
+ #
+ # Used to inform `self` that the iteration is starting.
+ # Specific iterators can use this to prepare some resources.
+ #
+ # Is automatically invoked at the beginning of `for` structures.
+ #
+ # Do nothing by default.
+ fun start do end
+
# Post-iteration hook.
#
# Used to inform `self` that the iteration is over.
# REQUIRE `index >= 0 and index < length`
fun [](index: Int): E is abstract
+ # Return the index-th element but wrap
+ #
+ # Whereas `self[]` requires the index to exists, the `modulo` accessor automatically
+ # wraps overbound and underbouds indexes.
+ #
+ # ~~~
+ # var a = [10,20,30]
+ # assert a.modulo(1) == 20
+ # assert a.modulo(3) == 10
+ # assert a.modulo(-1) == 30
+ # assert a.modulo(-10) == 30
+ # ~~~
+ #
+ # REQUIRE `not_empty`
+ # ENSURE `result == self[modulo_index(index)]`
+ fun modulo(index: Int): E do return self[modulo_index(index)]
+
+ # Returns the real index for a modulo index.
+ #
+ # ~~~
+ # var a = [10,20,30]
+ # assert a.modulo_index(1) == 1
+ # assert a.modulo_index(3) == 0
+ # assert a.modulo_index(-1) == 2
+ # assert a.modulo_index(-10) == 2
+ # ~~~
+ #
+ # REQUIRE `not_empty`
+ fun modulo_index(index: Int): Int
+ do
+ var length = self.length
+ if index >= 0 then
+ return index % length
+ else
+ return length - (-1 - index) % length - 1
+ end
+ end
+
# Get the last item.
# Is equivalent with `self[length-1]`.
#
# assert a.last_index_of_from(20, 2) == 1
# assert a.last_index_of_from(20, 1) == 1
# assert a.last_index_of_from(20, 0) == -1
- fun last_index_of_from(item: nullable Object, pos: Int): Int
- do
- var res = -1
- var p = 0
- var i = iterator
- while i.is_ok do
- if p>pos then break
- if i.item == item then res = p
- i.next
- p += 1
+ fun last_index_of_from(item: nullable Object, pos: Int): Int do
+ var i = pos
+ while i >= 0 do
+ if self[i] == item then return i
+ i -= 1
end
- return res
+ return -1
end
# Two sequences are equals if they have the same items in the same order.
# REQUIRE `index >= 0 and index <= length`
fun []=(index: Int, item: E) is abstract
+ # Set the index-th element but wrap
+ #
+ # Whereas `self[]=` requires the index to exists, the `modulo` accessor automatically
+ # wraps overbound and underbouds indexes.
+ #
+ # ~~~
+ # var a = [10,20,30]
+ # a.modulo(1) = 200
+ # a.modulo(3) = 100
+ # a.modulo(-1) = 300
+ # a.modulo(-10) = 301
+ # assert a == [100, 200, 301]
+ # ~~~
+ #
+ # REQUIRE `not_empty`
+ # ENSURE `self[modulo_index(index)] == value`
+ fun modulo=(index: Int, value: E) do self[modulo_index(index)] = value
+
# Insert an element at a given position, following elements are shifted.
#
# var a = [10, 20, 30, 40]
#
# 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.