X-Git-Url: http://nitlanguage.org diff --git a/lib/core/collection/array.nit b/lib/core/collection/array.nit index 0896bab..f01bbb5 100644 --- a/lib/core/collection/array.nit +++ b/lib/core/collection/array.nit @@ -111,11 +111,18 @@ abstract class AbstractArrayRead[E] # assert b == [10, 20, 2, 3, 50] fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int) do - # TODO native one - var i = len - while i > 0 do - i -= 1 - dest[new_start+i] = self[start+i] + if start < new_start then + var i = len + while i > 0 do + i -= 1 + dest[new_start+i] = self[start+i] + end + else + var i = 0 + while i < len do + dest[new_start+i] = self[start+i] + i += 1 + end end end @@ -314,7 +321,7 @@ class Array[E] redef fun [](index) do assert index: index >= 0 and index < _length - return _items[index] + return _items.as(not null)[index] end redef fun []=(index, item) @@ -326,7 +333,7 @@ class Array[E] if _length <= index then _length = index + 1 end - _items[index] = item + _items.as(not null)[index] = item end redef fun add(item) @@ -336,7 +343,7 @@ class Array[E] enlarge(l + 1) end _length = l + 1 - _items[l] = item + _items.as(not null)[l] = item end # Slight optimization for arrays @@ -351,13 +358,13 @@ class Array[E] if items isa Array[E] then var k = 0 while l < nl do - _items[l] = items._items[k] + _items.as(not null)[l] = items._items.as(not null)[k] l += 1 k += 1 end else for item in items do - _items[l] = item + _items.as(not null)[l] = item l += 1 end end @@ -365,13 +372,39 @@ class Array[E] _length = nl end + redef fun copy_to(start, len, dest, new_start) + do + # Fast code when source and destination are two arrays + + if not dest isa Array[E] then + super + return + end + + # Enlarge dest if required + var dest_len = new_start + len + if dest_len > dest.length then + dest.enlarge(dest_len) + dest.length = dest_len + end + + # Get underlying native arrays + var items = self.items + if items == null then return + var dest_items = dest.items + assert dest_items != null + + # Native copy + items.memmove(start, len, dest_items, new_start) + end + redef fun enlarge(cap) do var c = _capacity if cap <= c then return while c <= cap do c = c * 2 + 2 var a = new NativeArray[E](c) - if _capacity > 0 then _items.copy_to(a, _length) + if _capacity > 0 then _items.as(not null).copy_to(a, _length) _items = a _capacity = c end @@ -441,9 +474,10 @@ class Array[E] # Efficient implementation var l = length if l != o.length then return false + if l == 0 then return true var i = 0 - var it = _items - var oit = o._items + var it = _items.as(not null) + var oit = o._items.as(not null) while i < l do if it[i] != oit[i] then return false i += 1 @@ -559,7 +593,6 @@ 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 @@ -761,7 +794,7 @@ class ArrayMap[K, E] redef fun clone do var res = new ArrayMap[K,E] - res.recover_with self + res.add_all self return res end end @@ -889,10 +922,11 @@ class ArrayCmp[E: nullable Comparable] redef fun <=>(o) do - var it = _items - var oit = o._items var i = 0 var l = length + if l == 0 then return 0 + var it = _items.as(not null) + var oit = o._items.as(not null) var ol = o.length var len if l < ol then len = l else len = ol @@ -923,6 +957,7 @@ redef class Iterator[E] res.add(item) next end + finish return res end end @@ -958,6 +993,24 @@ universal NativeArray[E] # Copy `length` items to `dest`. fun copy_to(dest: NativeArray[E], length: Int) is intern + + # Copy `length` items to `dest` starting from `dest`. + fun memmove(start: Int, length: Int, dest: NativeArray[E], dest_start: Int) is intern do + if start < dest_start then + var i = length + while i > 0 do + i -= 1 + dest[dest_start+i] = self[start+i] + end + else + var i = 0 + while i < length do + dest[dest_start+i] = self[start+i] + i += 1 + end + end + end + #fun =(o: NativeArray[E]): Bool is intern #fun !=(o: NativeArray[E]): Bool is intern end