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