core/array: fix implementation of naive copy_to to avoid overwriting
[nit.git] / lib / core / collection / array.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
5 #
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
12 # another product.
13
14 # This module introduces the standard array structure.
15 # It also implements two other abstract collections : ArrayMap and ArraySet
16 module array is
17 no_warning "useless-type-test" # to avoid warning with nitc while compiling with c_src
18 end
19
20 import abstract_collection
21
22 # One dimension array of objects.
23 abstract class AbstractArrayRead[E]
24 super SequenceRead[E]
25
26 redef var length = 0
27
28 redef fun is_empty do return _length == 0
29
30 redef fun has(item)
31 do
32 var i = 0
33 var l = length
34 while i < l do
35 if self[i] == item then return true
36 i += 1
37 end
38 return false
39 end
40
41 redef fun has_only(item)
42 do
43 var i = 0
44 var l = length
45 while i < l do
46 if self[i] != item then return false
47 i += 1
48 end
49 return true
50 end
51
52 redef fun count(item)
53 do
54 var res = 0
55 var i = 0
56 var l = length
57 while i < l do
58 if self[i] == item then res += 1
59 i += 1
60 end
61 return res
62 end
63
64 redef fun index_of(item) do return index_of_from(item, 0)
65
66 redef fun last_index_of(item) do return last_index_of_from(item, length-1)
67
68 redef fun index_of_from(item, pos) do
69 var i = pos
70 var len = length
71 while i < len do
72 if self[i] == item then
73 return i
74 end
75 i += 1
76 end
77 return -1
78 end
79
80 redef fun last_index_of_from(item, pos) do
81 var i = pos
82 while i >= 0 do
83 if self[i] == item then
84 return i
85 else
86 i -= 1
87 end
88 end
89 return -1
90 end
91
92 # Return a new array that is the reverse of `self`
93 #
94 # assert [1,2,3].reversed == [3, 2, 1]
95 fun reversed: Array[E]
96 do
97 var cmp = _length
98 var result = new Array[E].with_capacity(cmp)
99 while cmp > 0 do
100 cmp -= 1
101 result.add(self[cmp])
102 end
103 return result
104 end
105
106 # Copy a portion of `self` to an other array.
107 #
108 # var a = [1, 2, 3, 4]
109 # var b = [10, 20, 30, 40, 50]
110 # a.copy_to(1, 2, b, 2)
111 # assert b == [10, 20, 2, 3, 50]
112 fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
113 do
114 # TODO native one
115 if start < new_start then
116 var i = len
117 while i > 0 do
118 i -= 1
119 dest[new_start+i] = self[start+i]
120 end
121 else
122 var i = 0
123 while i < len do
124 dest[new_start+i] = self[start+i]
125 i += 1
126 end
127 end
128 end
129
130 redef fun output
131 do
132 var i = 0
133 var l = length
134 while i < l do
135 var e = self[i]
136 if e != null then e.output
137 i += 1
138 end
139 end
140
141 redef fun iterator: IndexedIterator[E] do
142 var res = _free_iterator
143 if res == null then return new ArrayIterator[E](self)
144 res._index = 0
145 _free_iterator = null
146 return res
147 end
148
149 # An old iterator, free to reuse.
150 # Once an iterator is `finish`, it become reusable.
151 # Since some arrays are iterated a lot, this avoid most of the
152 # continuous allocation/garbage-collection of the needed iterators.
153 private var free_iterator: nullable ArrayIterator[E] = null
154
155 redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
156
157 # Returns a sub-array containing `count` elements starting from `from`.
158 #
159 # For most cases (see other case bellow),
160 # the first element is `from` and
161 # the last element is `from+count-1`.
162 #
163 # ~~~
164 # var a = [10, 20, 30, 40, 50]
165 # assert a.sub(0, 3) == [10, 20, 30]
166 # assert a.sub(3, 2) == [40, 50]
167 # assert a.sub(3, 1) == [40]
168 # ~~~
169 #
170 # If `count` is 0 or negative then an empty array is returned
171 #
172 # ~~~
173 # assert a.sub(3,0).is_empty
174 # assert a.sub(3,-1).is_empty
175 # ~~~
176 #
177 # If `from < 0` or `from+count>length` then inexistent elements are ignored.
178 # In this case the length of the result is lower than count.
179 #
180 # ~~~
181 # assert a.sub(-2, 4) == [10, 20]
182 # assert a.sub(4, 99) == [50]
183 # assert a.sub(-9, 99) == [10,20,30,40,50]
184 # assert a.sub(-99, 9).is_empty
185 # ~~~
186 fun sub(from: Int, count: Int): Array[E] do
187 if from < 0 then
188 count += from
189 from = 0
190 end
191 if count < 0 then
192 count = 0
193 end
194 var to = from + count
195 if to > length then
196 to = length
197 end
198 var res = new Array[E].with_capacity(to - from)
199 while from < to do
200 res.add(self[from])
201 from += 1
202 end
203 return res
204 end
205 end
206
207 # Resizable one dimension array of objects.
208 abstract class AbstractArray[E]
209 super AbstractArrayRead[E]
210 super Sequence[E]
211
212 # Force the capacity to be at least `cap`.
213 # The capacity of the array is an internal information.
214 # However, this method can be used to prepare a large amount of add
215 fun enlarge(cap: Int) is abstract
216
217 redef fun push(item) do add(item)
218
219 redef fun pop
220 do
221 assert not_empty: not is_empty
222 var r = last
223 _length -= 1
224 return r
225 end
226
227 redef fun shift
228 do
229 assert not_empty: not is_empty
230 var r = first
231 var l = length-1
232 copy_to(1, l, self, 0)
233 _length = l
234 return r
235 end
236
237 redef fun unshift(item)
238 do
239 var l = length
240 if l > 0 then
241 enlarge(l + 1)
242 copy_to(0, l, self, 1)
243 end
244 self[0] = item
245 end
246
247 redef fun insert(item, pos) do
248 enlarge(length + 1)
249 copy_to(pos, length-pos, self, pos + 1)
250 self[pos] = item
251 end
252
253 redef fun insert_all(coll, pos)
254 do
255 var l = coll.length
256 if l == 0 then return
257 enlarge(length + l)
258 _length += l
259 copy_to(pos, length-pos-l, self, pos + l)
260 for c in coll do
261 self[pos] = c
262 pos += 1
263 end
264 end
265
266 redef fun add(item) do self[length] = item
267
268 redef fun clear do _length = 0
269
270 redef fun remove(item) do remove_at(index_of(item))
271
272 redef fun remove_all(item)
273 do
274 var i = index_of(item)
275 while i >= 0 do
276 remove_at(i)
277 i = index_of_from(item, i)
278 end
279 end
280
281 redef fun remove_at(i)
282 do
283 var l = length
284 if i >= 0 and i < l then
285 var j = i + 1
286 while j < l do
287 self[j-1] = self[j]
288 j += 1
289 end
290 _length = l - 1
291 end
292 end
293
294 # Invert two elements in the array
295 #
296 # var a = [10, 20, 30, 40]
297 # a.swap_at(1, 3)
298 # assert a == [10, 40, 30, 20]
299 fun swap_at(a: Int,b: Int)
300 do
301 var e = self[a]
302 self[a] = self[b]
303 self[b] = e
304 end
305 end
306
307 # Resizable one dimension array of objects.
308 #
309 # Arrays have a literal representation.
310 #
311 # var a = [12, 32, 8]
312 # # is equivalent with:
313 # var b = new Array[Int]
314 # b.push(12)
315 # b.push(32)
316 # b.push(8)
317 # assert a == b
318 class Array[E]
319 super AbstractArray[E]
320 super Cloneable
321
322 redef fun [](index)
323 do
324 assert index: index >= 0 and index < _length
325 return _items[index]
326 end
327
328 redef fun []=(index, item)
329 do
330 assert index: index >= 0 and index < _length + 1
331 if _capacity <= index then
332 enlarge(index + 1)
333 end
334 if _length <= index then
335 _length = index + 1
336 end
337 _items[index] = item
338 end
339
340 redef fun add(item)
341 do
342 var l = _length
343 if _capacity <= l then
344 enlarge(l + 1)
345 end
346 _length = l + 1
347 _items[l] = item
348 end
349
350 # Slight optimization for arrays
351 redef fun add_all(items)
352 do
353 var l = _length
354 var nl = l + items.length
355 if _capacity < nl then
356 enlarge nl
357 end
358
359 if items isa Array[E] then
360 var k = 0
361 while l < nl do
362 _items[l] = items._items[k]
363 l += 1
364 k += 1
365 end
366 else
367 for item in items do
368 _items[l] = item
369 l += 1
370 end
371 end
372
373 _length = nl
374 end
375
376 redef fun enlarge(cap)
377 do
378 var c = _capacity
379 if cap <= c then return
380 while c <= cap do c = c * 2 + 2
381 var a = new NativeArray[E](c)
382 if _capacity > 0 then _items.copy_to(a, _length)
383 _items = a
384 _capacity = c
385 end
386
387 # Create an empty array.
388 init
389 do
390 _capacity = 0
391 _length = 0
392 end
393
394 # Create an array from a collection.
395 init from(items: Collection[E]) do
396 with_capacity(items.length)
397 self.add_all(items)
398 end
399
400 # Create an array with some `objects`.
401 init with_items(objects: E...)
402 do
403 _items = objects._items
404 _capacity = objects._capacity
405 _length = objects.length
406 end
407
408 # Create an empty array with a given capacity.
409 init with_capacity(cap: Int)
410 do
411 assert positive: cap >= 0
412 _items = new NativeArray[E](cap)
413 _capacity = cap
414 _length = 0
415 end
416
417 # Create an array of `count` elements
418 init filled_with(value: E, count: Int)
419 do
420 assert positive: count >= 0
421 _items = new NativeArray[E](count)
422 _capacity = count
423 _length = count
424 var i = 0
425 while i < count do
426 self[i] = value
427 i += 1
428 end
429 end
430
431 # Create a array filled with a given native array.
432 init with_native(nat: NativeArray[E], size: Int)
433 do
434 assert positive: size >= 0
435 _items = nat
436 _capacity = size
437 _length = size
438 end
439
440 # The internal storage.
441 private var items: nullable NativeArray[E] = null
442
443 # The size of `_items`.
444 private var capacity: Int = 0
445
446 redef fun ==(o)
447 do
448 if not o isa Array[nullable Object] then return super
449 # Efficient implementation
450 var l = length
451 if l != o.length then return false
452 var i = 0
453 var it = _items
454 var oit = o._items
455 while i < l do
456 if it[i] != oit[i] then return false
457 i += 1
458 end
459 return true
460 end
461
462 # Shallow clone of `self`
463 #
464 # ~~~
465 # var a = [1,2,3]
466 # var b = a.clone
467 # assert a == b
468 # a.add 4
469 # assert a != b
470 # b.add 4
471 # assert a == b
472 # ~~~
473 #
474 # Note that the clone is shallow and elements are shared between `self` and the result.
475 #
476 # ~~~
477 # var aa = [a]
478 # var bb = aa.clone
479 # assert aa == bb
480 # aa.first.add 5
481 # assert aa == bb
482 # ~~~
483 redef fun clone do return to_a
484
485 # Concatenation of arrays.
486 #
487 # Returns a new array built by concatenating `self` and `other` together.
488 #
489 # var a1 = [1,2,3]
490 # var a2 = [4,5,6]
491 # var a3 = a1 + a2
492 # assert a3 == [1,2,3,4,5,6]
493 #
494 # Because a new array is always created, future modification on `self` and `other`
495 # does not impact the previously computed result.
496 #
497 # a1.add(30)
498 # a2.add(60)
499 # assert a3 == [1,2,3,4,5,6] # unchanged
500 # assert a1 + a2 == [1,2,3,30,4,5,6,60]
501 fun +(other: Array[E]): Array[E]
502 do
503 var res = new Array[E].with_capacity(length + other.length)
504 res.append(self)
505 res.append(other)
506 return res
507 end
508
509 # Repetition of arrays.
510 #
511 # returns a new array built by concatenating `self` `repeat` times.
512 #
513 # var a = [1,2,3]
514 # assert (a * 0).is_empty
515 # assert a * 1 == [1,2,3]
516 # assert a * 2 == [1,2,3,1,2,3]
517 # assert (a * 10).length == 30
518 fun *(repeat: Int): Array[E]
519 do
520 assert repeat >= 0
521 var res = new Array[E].with_capacity(length * repeat)
522 while repeat > 0 do
523 res.add_all(self)
524 repeat -= 1
525 end
526 return res
527 end
528 end
529
530 # An `Iterator` on `AbstractArray`
531 private class ArrayIterator[E]
532 super IndexedIterator[E]
533
534 redef fun item do return _array[_index]
535
536 # redef fun item=(e) do _array[_index] = e
537
538 redef fun is_ok do return _index < _array.length
539
540 redef fun next do _index += 1
541
542 redef var index = 0
543
544 var array: AbstractArrayRead[E]
545
546 redef fun finish do _array._free_iterator = self
547 end
548
549 private class ArrayReverseIterator[E]
550 super ArrayIterator[E]
551
552 redef fun is_ok do return _index >= 0
553
554 redef fun next do _index -= 1
555
556 init
557 do
558 _index = _array.length - 1
559 end
560
561 # Do not cache `self`
562 redef fun finish do end
563 end
564
565 # Others collections ##########################################################
566
567 # A set implemented with an Array.
568 class ArraySet[E]
569 super Set[E]
570 super Cloneable
571
572 # The stored elements.
573 private var array: Array[E] is noinit
574
575 redef fun has(e) do return _array.has(e)
576
577 redef fun add(e) do if not _array.has(e) then _array.add(e)
578
579 redef fun is_empty do return _array.is_empty
580
581 redef fun length do return _array.length
582
583 redef fun first
584 do
585 assert _array.length > 0
586 return _array.first
587 end
588
589 redef fun remove(item)
590 do
591 var i = _array.index_of(item)
592 if i >= 0 then remove_at(i)
593 end
594
595 redef fun remove_all(item) do remove(item)
596
597 redef fun clear do _array.clear
598
599 redef fun iterator do return new ArraySetIterator[E](_array.iterator)
600
601 # Assume the capacity is at least `cap`.
602 fun enlarge(cap: Int) do _array.enlarge(cap)
603
604 private fun remove_at(i: Int)
605 do
606 _array[i] = _array.last
607 _array.pop
608 end
609
610 # Create an empty set
611 init do _array = new Array[E]
612
613 # Create an empty set with a given capacity.
614 init with_capacity(i: Int) do _array = new Array[E].with_capacity(i)
615
616 redef fun new_set do return new ArraySet[E]
617
618 # Shallow clone of `self`
619 #
620 # ~~~
621 # var a = new ArraySet[Int]
622 # a.add 1
623 # a.add 2
624 # var b = a.clone
625 # assert a == b
626 # a.add 3
627 # assert a != b
628 # b.add 3
629 # assert a == b
630 # ~~~
631 #
632 # Note that the clone is shallow and keys and values are shared between `self` and the result.
633 #
634 # ~~~
635 # var aa = new ArraySet[Array[Int]]
636 # aa.add([1,2])
637 # var bb = aa.clone
638 # assert aa == bb
639 # aa.first.add 5
640 # assert aa == bb
641 # ~~~
642 redef fun clone
643 do
644 var res = new ArraySet[E]
645 res.add_all self
646 return res
647 end
648 end
649
650 # Iterators on sets implemented with arrays.
651 private class ArraySetIterator[E]
652 super Iterator[E]
653
654 redef fun is_ok do return _iter.is_ok
655
656 redef fun next do _iter.next
657
658 redef fun item: E do return _iter.item
659
660 var iter: Iterator[E]
661 end
662
663
664 # Associative arrays implemented with an array of (key, value) pairs.
665 class ArrayMap[K, E]
666 super CoupleMap[K, E]
667 super Cloneable
668
669 # O(n)
670 redef fun [](key)
671 do
672 var i = index(key)
673 if i >= 0 then
674 return _items[i].second
675 else
676 return provide_default_value(key)
677 end
678 end
679
680 # O(n)
681 redef fun []=(key, item)
682 do
683 var i = index(key)
684 if i >= 0 then
685 _items[i].second = item
686 else
687 _items.push(new Couple[K,E](key, item))
688 end
689 end
690
691 redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self) is lazy
692 redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self) is lazy
693
694 # O(1)
695 redef fun length do return _items.length
696
697 redef fun couple_iterator do return _items.iterator
698
699 redef fun is_empty do return _items.is_empty
700
701 redef fun clear do _items.clear
702
703 # Assume the capacity to be at least `cap`.
704 fun enlarge(cap: Int) do _items.enlarge(cap)
705
706 redef fun couple_at(key)
707 do
708 var i = index(key)
709 if i >= 0 then
710 return _items[i]
711 else
712 return null
713 end
714 end
715
716 # Internal storage.
717 private var items = new Array[Couple[K,E]]
718
719 # fast remove the ith element of the array
720 private fun remove_at_index(i: Int)
721 do
722 _items[i] = _items.last
723 _items.pop
724 end
725
726 # The last positive result given by a index(1) call
727 private var last_index: Int = 0
728
729 # Where is the `key` in `_item`?
730 # return -1 if not found
731 private fun index(key: K): Int
732 do
733 var l = _last_index
734 if l < _items.length and _items[l].first == key then return l
735
736 var i = 0
737 while i < _items.length do
738 if _items[i].first == key then
739 _last_index = i
740 return i
741 end
742 i += 1
743 end
744 return -1
745 end
746
747 # Shallow clone of `self`
748 #
749 # ~~~
750 # var a = new ArrayMap[String,Int]
751 # a["one"] = 1
752 # a["two"] = 2
753 # var b = a.clone
754 # assert a == b
755 # a["zero"] = 0
756 # assert a != b
757 # ~~~
758 #
759 # Note that the clone is shallow and keys and values are shared between `self` and the result.
760 #
761 # ~~~
762 # var aa = new ArrayMap[String, Array[Int]]
763 # aa["two"] = [1,2]
764 # var bb = aa.clone
765 # assert aa == bb
766 # aa["two"].add 5
767 # assert aa == bb
768 # ~~~
769 redef fun clone
770 do
771 var res = new ArrayMap[K,E]
772 res.recover_with self
773 return res
774 end
775 end
776
777 private class ArrayMapKeys[K, E]
778 super RemovableCollection[K]
779 # The original map
780 var map: ArrayMap[K, E]
781 redef fun count(k) do if self.has(k) then return 1 else return 0
782 redef fun first do return self.map._items.first.first
783 redef fun has(k) do return self.map.index(k) >= 0
784 redef fun has_only(k) do return (self.has(k) and self.length == 1) or self.is_empty
785 redef fun is_empty do return self.map.is_empty
786 redef fun length do return self.map.length
787 redef fun iterator do return new MapKeysIterator[K, E](self.map.iterator)
788 redef fun clear do self.map.clear
789 redef fun remove(key)
790 do
791 var i = self.map.index(key)
792 if i >= 0 then self.map.remove_at_index(i)
793 end
794 redef fun remove_all(key) do self.remove(key)
795 end
796
797 private class ArrayMapValues[K, E]
798 super RemovableCollection[E]
799 # The original map
800 var map: ArrayMap[K, E]
801 redef fun first do return self.map._items.first.second
802 redef fun is_empty do return self.map.is_empty
803 redef fun length do return self.map.length
804 redef fun iterator do return new MapValuesIterator[K, E](self.map.iterator)
805
806 # O(n)
807 redef fun has(item)
808 do
809 for i in self.map._items do if i.second == item then return true
810 return false
811 end
812
813 # O(n)
814 redef fun has_only(item)
815 do
816 for i in self.map._items do if i.second != item then return false
817 return true
818 end
819
820 # O(n)
821 redef fun count(item)
822 do
823 var nb = 0
824 for i in self.map._items do if i.second == item then nb += 1
825 return nb
826 end
827
828 redef fun clear do self.map.clear
829
830 redef fun remove(item)
831 do
832 var map = self.map
833 var i = map._items.length - 1
834 while i >= 0 do
835 if map._items[i].second == item then
836 map.remove_at_index(i)
837 return
838 end
839 i -= 1
840 end
841 end
842
843 redef fun remove_all(item)
844 do
845 var map = self.map
846 var i = map._items.length - 1
847 while i >= 0 do
848 if map._items[i].second == item then
849 map.remove_at_index(i)
850 end
851 i -= 1
852 end
853 end
854 end
855
856 # Comparable array for comparable elements.
857 #
858 # For two arrays, if one is a prefix, then it is lower.
859 #
860 # ~~~
861 # var a12 = new ArrayCmp[nullable Int].with_items(1,2)
862 # var a123 = new ArrayCmp[nullable Int].with_items(1,2,3)
863 # assert a12 < a123
864 # ~~~
865 #
866 # Otherwise, the first element just after the longest
867 # common prefix gives the order between the two arrays.
868 #
869 # ~~~
870 # var a124 = new ArrayCmp[nullable Int].with_items(1,2,4)
871 # var a13 = new ArrayCmp[nullable Int].with_items(1,3)
872 # assert a12 < a123
873 # assert a123 < a13
874 # ~~~
875 #
876 # Obviously, two equal arrays are equal.
877 #
878 # ~~~
879 # var b12 = new ArrayCmp[nullable Int].with_items(1,2)
880 # assert (a12 <=> b12) == 0
881 # ~~~
882 #
883 # `null` is considered lower than any other elements.
884 # But is still greater than no element.
885 #
886 # ~~~
887 # var a12n = new ArrayCmp[nullable Int].with_items(1,2,null)
888 # assert a12n < a123
889 # assert a12 < a12n
890 # ~~~
891 class ArrayCmp[E: nullable Comparable]
892 super Array[E]
893 super Comparable
894 redef type OTHER: ArrayCmp[E] is fixed
895
896 redef fun <(o) do return (self <=> o) < 0
897
898 redef fun <=>(o)
899 do
900 var it = _items
901 var oit = o._items
902 var i = 0
903 var l = length
904 var ol = o.length
905 var len
906 if l < ol then len = l else len = ol
907 while i < len do
908 var a = it[i]
909 var b = oit[i]
910 if a != null then
911 if b == null then return 1
912 var d = a <=> b
913 if d != 0 then return d
914 else
915 if b != null then return -1
916 end
917 i += 1
918 end
919 return l <=> ol
920 end
921 end
922
923 # Others tools ################################################################
924
925 redef class Iterator[E]
926 # Interate on `self` and build an array
927 fun to_a: Array[E]
928 do
929 var res = new Array[E]
930 while is_ok do
931 res.add(item)
932 next
933 end
934 return res
935 end
936 end
937
938 redef class Collection[E]
939 # Build a new array from a collection
940 fun to_a: Array[E]
941 do
942 var res = new Array[E].with_capacity(length)
943 res.add_all(self)
944 return res
945 end
946 end
947
948 # Native classes ##############################################################
949
950 # Native Nit array
951 # Access are unchecked and it has a fixed size
952 # Not for public use: may become private.
953 universal NativeArray[E]
954 # Creates a new NativeArray of capacity `length`
955 new(length: Int) is intern
956 # The length of the array
957 fun length: Int is intern
958 # Use `self` to initialize a standard Nit Array.
959 fun to_a: Array[E] do return new Array[E].with_native(self, length)
960
961 # Get item at `index`.
962 fun [](index: Int): E is intern
963
964 # Set `item` at `index`.
965 fun []=(index: Int, item: E) is intern
966
967 # Copy `length` items to `dest`.
968 fun copy_to(dest: NativeArray[E], length: Int) is intern
969 #fun =(o: NativeArray[E]): Bool is intern
970 #fun !=(o: NativeArray[E]): Bool is intern
971 end