lib/standard: optimize `Array::add_all`
[nit.git] / lib / standard / collection / array.nit
index ca6e9fa..e70acd2 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]
@@ -280,6 +281,32 @@ 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
@@ -398,11 +425,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
@@ -429,7 +456,7 @@ private class ArrayIterator[E]
 
        redef var index = 0
 
-       private var array: AbstractArrayRead[E]
+       var array: AbstractArrayRead[E]
 end
 
 private class ArrayReverseIterator[E]
@@ -508,7 +535,7 @@ private class ArraySetIterator[E: Object]
 
        redef fun item: E do return _iter.item
 
-       private var iter: ArrayIterator[E]
+       var iter: ArrayIterator[E]
 end
 
 
@@ -778,8 +805,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