X-Git-Url: http://nitlanguage.org diff --git a/lib/standard/collection/array.nit b/lib/standard/collection/array.nit index 253dd9e..cdb5242 100644 --- a/lib/standard/collection/array.nit +++ b/lib/standard/collection/array.nit @@ -13,7 +13,9 @@ # 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 @@ -130,8 +132,70 @@ abstract class AbstractArrayRead[E] 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. @@ -477,6 +541,8 @@ private class ArrayIterator[E] redef var index = 0 var array: AbstractArrayRead[E] + + redef fun finish do _array._free_iterator = self end private class ArrayReverseIterator[E]