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