# This module introduces the standard array structure.
# It also implements two other abstract collections : ArrayMap and ArraySet
-module array
+module array is
+ no_warning "useless-type-test" # to avoid warning with nitc while compiling with c_src
+end
import abstract_collection
end
end
- redef fun iterator: ArrayIterator[E] do return new ArrayIterator[E](self)
+ redef fun iterator: ArrayIterator[E] do
+ var res = _free_iterator
+ if res == null then return new ArrayIterator[E](self)
+ res._index = 0
+ _free_iterator = null
+ return res
+ end
+
+ # An old iterator, free to reuse.
+ # Once an iterator is `finish`, it become reusable.
+ # Since some arrays are iterated a lot, this avoid most of the
+ # continuous allocation/garbage-collection of the needed iterators.
+ private var free_iterator: nullable ArrayIterator[E] = null
+
redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
+
+ # Returns a sub-array containing `count` elements starting from `from`.
+ #
+ # For most cases (see other case bellow),
+ # the first element is `from` and
+ # the last element is `from+count-1`.
+ #
+ # ~~~
+ # var a = [10, 20, 30, 40, 50]
+ # assert a.sub(0, 3) == [10, 20, 30]
+ # assert a.sub(3, 2) == [40, 50]
+ # assert a.sub(3, 1) == [40]
+ # ~~~
+ #
+ # If `count` is 0 or negative then an empty array is returned
+ #
+ # ~~~
+ # assert a.sub(3,0).is_empty
+ # assert a.sub(3,-1).is_empty
+ # ~~~
+ #
+ # If `from < 0` or `from+count>length` then inexistent elements are ignored.
+ # In this case the length of the result is lower than count.
+ #
+ # ~~~
+ # assert a.sub(-2, 4) == [10, 20]
+ # assert a.sub(4, 99) == [50]
+ # assert a.sub(-9, 99) == [10,20,30,40,50]
+ # assert a.sub(-99, 9).is_empty
+ # ~~~
+ fun sub(from: Int, count: Int): Array[E] do
+ if from < 0 then
+ count += from
+ from = 0
+ end
+ if count < 0 then
+ count = 0
+ end
+ var to = from + count
+ if to > length then
+ to = length
+ end
+ var res = new Array[E].with_capacity(to - from)
+ while from < to do
+ res.add(self[from])
+ from += 1
+ end
+ return res
+ end
end
# Resizable one dimension array of objects.
redef var index = 0
var array: AbstractArrayRead[E]
+
+ redef fun finish do _array._free_iterator = self
end
private class ArrayReverseIterator[E]
end
end
- redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self)
- redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self)
+ redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self) is lazy
+ redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self) is lazy
# O(1)
redef fun length do return _items.length