lib: update HashMap and ArrayMap to support nullable keys
[nit.git] / lib / standard / collection / array.nit
index 7d710bd..44ea5d3 100644 (file)
@@ -109,7 +109,7 @@ abstract class AbstractArrayRead[E]
        #     var b = [10, 20, 30, 40, 50]
        #     a.copy_to(1, 2, b, 2)
        #     assert b      ==  [10, 20, 2, 3, 50]
-       protected fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
+       fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
        do
                # TODO native one
                var i = len
@@ -242,6 +242,7 @@ end
 # Resizable one dimension array of objects.
 #
 # Arrays have a literal representation.
+#
 #     var a = [12, 32, 8]
 #     # is equivalent with:
 #     var b = new Array[Int]
@@ -251,7 +252,6 @@ end
 #     assert a == b
 class Array[E]
        super AbstractArray[E]
-       super ArrayCapable[E]
 
        redef fun [](index)
        do
@@ -281,12 +281,38 @@ class Array[E]
                _items[l] = item
        end
 
+       # Slight optimization for arrays
+       redef fun add_all(items)
+       do
+               var l = _length
+               var nl = l + items.length
+               if _capacity < nl then
+                       enlarge nl
+               end
+
+               if items isa Array[E] then
+                       var k = 0
+                       while l < nl do
+                               _items[l] = items._items[k]
+                               l += 1
+                               k += 1
+                       end
+               else
+                       for item in items do
+                               _items[l] = item
+                               l += 1
+                       end
+               end
+
+               _length = nl
+       end
+
        redef fun enlarge(cap)
        do
                var c = _capacity
                if cap <= c then return
                while c <= cap do c = c * 2 + 2
-               var a = calloc_array(c)
+               var a = new NativeArray[E](c)
                if _capacity > 0 then _items.copy_to(a, _length)
                _items = a
                _capacity = c
@@ -317,7 +343,7 @@ class Array[E]
        init with_capacity(cap: Int)
        do
                assert positive: cap >= 0
-               _items = calloc_array(cap)
+               _items = new NativeArray[E](cap)
                _capacity = cap
                _length = 0
        end
@@ -326,7 +352,7 @@ class Array[E]
        init filled_with(value: E, count: Int)
        do
                assert positive: count >= 0
-               _items = calloc_array(count)
+               _items = new NativeArray[E](count)
                _capacity = count
                _length = count
                var i = 0
@@ -348,10 +374,6 @@ class Array[E]
        # The internal storage.
        private var items: nullable NativeArray[E] = null
 
-       # Do not use this method
-       # FIXME: Remove it once modules can intrude non local modules
-       fun intern_items: NativeArray[E] do return _items.as(not null)
-
        # The size of `_items`.
        private var capacity: Int = 0
 
@@ -399,11 +421,11 @@ class Array[E]
        #
        # returns a new array built by concatenating `self` `repeat` times.
        #
-       #    var a = [1,2,3]
-       #    assert (a * 0).is_empty
-       #    assert a * 1  ==  [1,2,3]
-       #    assert a * 2  ==  [1,2,3,1,2,3]
-       #    assert (a * 10).length  ==  30
+       #     var a = [1,2,3]
+       #     assert (a * 0).is_empty
+       #     assert a * 1  ==  [1,2,3]
+       #     assert a * 2  ==  [1,2,3,1,2,3]
+       #     assert (a * 10).length  ==  30
        fun *(repeat: Int): Array[E]
        do
                assert repeat >= 0
@@ -430,7 +452,7 @@ private class ArrayIterator[E]
 
        redef var index = 0
 
-       private var array: AbstractArrayRead[E]
+       var array: AbstractArrayRead[E]
 end
 
 private class ArrayReverseIterator[E]
@@ -509,12 +531,12 @@ private class ArraySetIterator[E: Object]
 
        redef fun item: E do return _iter.item
 
-       private var iter: ArrayIterator[E]
+       var iter: ArrayIterator[E]
 end
 
 
 # Associative arrays implemented with an array of (key, value) pairs.
-class ArrayMap[K: Object, E]
+class ArrayMap[K, E]
        super CoupleMap[K, E]
 
        # O(n)
@@ -596,7 +618,7 @@ class ArrayMap[K: Object, E]
        end
 end
 
-private class ArrayMapKeys[K: Object, E]
+private class ArrayMapKeys[K, E]
        super RemovableCollection[K]
        # The original map
        var map: ArrayMap[K, E]
@@ -616,7 +638,7 @@ private class ArrayMapKeys[K: Object, E]
        redef fun remove_all(key) do self.remove(key)
 end
 
-private class ArrayMapValues[K: Object, E]
+private class ArrayMapValues[K, E]
        super RemovableCollection[E]
        # The original map
        var map: ArrayMap[K, E]
@@ -769,12 +791,6 @@ end
 
 # Native classes ##############################################################
 
-# Subclasses of this class can create native arrays
-interface ArrayCapable[E]
-       # Get a new array of `size` elements.
-       protected fun calloc_array(size: Int): NativeArray[E] is intern
-end
-
 # Native Nit array
 # Access are unchecked and it has a fixed size
 # Not for public use: may become private.
@@ -785,8 +801,14 @@ universal NativeArray[E]
        fun length: Int is intern
        # Use `self` to initialize a standard Nit Array.
        fun to_a: Array[E] do return new Array[E].with_native(self, length)
+
+       # Get item at `index`.
        fun [](index: Int): E is intern
+
+       # Set `item` at `index`.
        fun []=(index: Int, item: E) is intern
+
+       # Copy `length` items to `dest`.
        fun copy_to(dest: NativeArray[E], length: Int) is intern
        #fun =(o: NativeArray[E]): Bool is intern
        #fun !=(o: NativeArray[E]): Bool is intern