X-Git-Url: http://nitlanguage.org diff --git a/lib/standard/collection/array.nit b/lib/standard/collection/array.nit index ae351cf..3cc0b57 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,7 +132,20 @@ 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) end @@ -252,6 +267,7 @@ end # assert a == b class Array[E] super AbstractArray[E] + super Cloneable redef fun [](index) do @@ -393,6 +409,29 @@ class Array[E] return true end + # Shallow clone of `self` + # + # ~~~ + # var a = [1,2,3] + # var b = a.clone + # assert a == b + # a.add 4 + # assert a != b + # b.add 4 + # assert a == b + # ~~~ + # + # Note that the clone is shallow and elements are shared between `self` and the result. + # + # ~~~ + # var aa = [a] + # var bb = aa.clone + # assert aa == bb + # aa.first.add 5 + # assert aa == bb + # ~~~ + redef fun clone do return to_a + # Concatenation of arrays. # # Returns a new array built by concatenating `self` and `other` together. @@ -453,6 +492,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] @@ -473,6 +514,7 @@ end # A set implemented with an Array. class ArraySet[E] super Set[E] + super Cloneable # The stored elements. private var array: Array[E] is noinit @@ -519,6 +561,37 @@ class ArraySet[E] init with_capacity(i: Int) do _array = new Array[E].with_capacity(i) redef fun new_set do return new ArraySet[E] + + # Shallow clone of `self` + # + # ~~~ + # var a = new ArraySet[Int] + # a.add 1 + # a.add 2 + # var b = a.clone + # assert a == b + # a.add 3 + # assert a != b + # b.add 3 + # assert a == b + # ~~~ + # + # Note that the clone is shallow and keys and values are shared between `self` and the result. + # + # ~~~ + # var aa = new ArraySet[Array[Int]] + # aa.add([1,2]) + # var bb = aa.clone + # assert aa == bb + # aa.first.add 5 + # assert aa == bb + # ~~~ + redef fun clone + do + var res = new ArraySet[E] + res.add_all self + return res + end end # Iterators on sets implemented with arrays. @@ -538,6 +611,7 @@ end # Associative arrays implemented with an array of (key, value) pairs. class ArrayMap[K, E] super CoupleMap[K, E] + super Cloneable # O(n) redef fun [](key) @@ -561,8 +635,8 @@ class ArrayMap[K, 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 @@ -616,6 +690,35 @@ class ArrayMap[K, E] end return -1 end + + # Shallow clone of `self` + # + # ~~~ + # var a = new ArrayMap[String,Int] + # a["one"] = 1 + # a["two"] = 2 + # var b = a.clone + # assert a == b + # a["zero"] = 0 + # assert a != b + # ~~~ + # + # Note that the clone is shallow and keys and values are shared between `self` and the result. + # + # ~~~ + # var aa = new ArrayMap[String, Array[Int]] + # aa["two"] = [1,2] + # var bb = aa.clone + # assert aa == bb + # aa["two"].add 5 + # assert aa == bb + # ~~~ + redef fun clone + do + var res = new ArrayMap[K,E] + res.recover_with self + return res + end end private class ArrayMapKeys[K, E]