lib: rename `standard` as `core`
[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: 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
557 # Do not cache `self`
558 redef fun finish do end
559 end
560
561 # Others collections ##########################################################
562
563 # A set implemented with an Array.
564 class ArraySet[E]
565 super Set[E]
566 super Cloneable
567
568 # The stored elements.
569 private var array: Array[E] is noinit
570
571 redef fun has(e) do return _array.has(e)
572
573 redef fun add(e) do if not _array.has(e) then _array.add(e)
574
575 redef fun is_empty do return _array.is_empty
576
577 redef fun length do return _array.length
578
579 redef fun first
580 do
581 assert _array.length > 0
582 return _array.first
583 end
584
585 redef fun remove(item)
586 do
587 var i = _array.index_of(item)
588 if i >= 0 then remove_at(i)
589 end
590
591 redef fun remove_all(item) do remove(item)
592
593 redef fun clear do _array.clear
594
595 redef fun iterator do return new ArraySetIterator[E](_array.iterator)
596
597 # Assume the capacity is at least `cap`.
598 fun enlarge(cap: Int) do _array.enlarge(cap)
599
600 private fun remove_at(i: Int)
601 do
602 _array[i] = _array.last
603 _array.pop
604 end
605
606 # Create an empty set
607 init do _array = new Array[E]
608
609 # Create an empty set with a given capacity.
610 init with_capacity(i: Int) do _array = new Array[E].with_capacity(i)
611
612 redef fun new_set do return new ArraySet[E]
613
614 # Shallow clone of `self`
615 #
616 # ~~~
617 # var a = new ArraySet[Int]
618 # a.add 1
619 # a.add 2
620 # var b = a.clone
621 # assert a == b
622 # a.add 3
623 # assert a != b
624 # b.add 3
625 # assert a == b
626 # ~~~
627 #
628 # Note that the clone is shallow and keys and values are shared between `self` and the result.
629 #
630 # ~~~
631 # var aa = new ArraySet[Array[Int]]
632 # aa.add([1,2])
633 # var bb = aa.clone
634 # assert aa == bb
635 # aa.first.add 5
636 # assert aa == bb
637 # ~~~
638 redef fun clone
639 do
640 var res = new ArraySet[E]
641 res.add_all self
642 return res
643 end
644 end
645
646 # Iterators on sets implemented with arrays.
647 private class ArraySetIterator[E]
648 super Iterator[E]
649
650 redef fun is_ok do return _iter.is_ok
651
652 redef fun next do _iter.next
653
654 redef fun item: E do return _iter.item
655
656 var iter: ArrayIterator[E]
657 end
658
659
660 # Associative arrays implemented with an array of (key, value) pairs.
661 class ArrayMap[K, E]
662 super CoupleMap[K, E]
663 super Cloneable
664
665 # O(n)
666 redef fun [](key)
667 do
668 var i = index(key)
669 if i >= 0 then
670 return _items[i].second
671 else
672 return provide_default_value(key)
673 end
674 end
675
676 # O(n)
677 redef fun []=(key, item)
678 do
679 var i = index(key)
680 if i >= 0 then
681 _items[i].second = item
682 else
683 _items.push(new Couple[K,E](key, item))
684 end
685 end
686
687 redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self) is lazy
688 redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self) is lazy
689
690 # O(1)
691 redef fun length do return _items.length
692
693 redef fun couple_iterator do return _items.iterator
694
695 redef fun is_empty do return _items.is_empty
696
697 redef fun clear do _items.clear
698
699 # Assume the capacity to be at least `cap`.
700 fun enlarge(cap: Int) do _items.enlarge(cap)
701
702 redef fun couple_at(key)
703 do
704 var i = index(key)
705 if i >= 0 then
706 return _items[i]
707 else
708 return null
709 end
710 end
711
712 # Internal storage.
713 private var items = new Array[Couple[K,E]]
714
715 # fast remove the ith element of the array
716 private fun remove_at_index(i: Int)
717 do
718 _items[i] = _items.last
719 _items.pop
720 end
721
722 # The last positive result given by a index(1) call
723 private var last_index: Int = 0
724
725 # Where is the `key` in `_item`?
726 # return -1 if not found
727 private fun index(key: K): Int
728 do
729 var l = _last_index
730 if l < _items.length and _items[l].first == key then return l
731
732 var i = 0
733 while i < _items.length do
734 if _items[i].first == key then
735 _last_index = i
736 return i
737 end
738 i += 1
739 end
740 return -1
741 end
742
743 # Shallow clone of `self`
744 #
745 # ~~~
746 # var a = new ArrayMap[String,Int]
747 # a["one"] = 1
748 # a["two"] = 2
749 # var b = a.clone
750 # assert a == b
751 # a["zero"] = 0
752 # assert a != b
753 # ~~~
754 #
755 # Note that the clone is shallow and keys and values are shared between `self` and the result.
756 #
757 # ~~~
758 # var aa = new ArrayMap[String, Array[Int]]
759 # aa["two"] = [1,2]
760 # var bb = aa.clone
761 # assert aa == bb
762 # aa["two"].add 5
763 # assert aa == bb
764 # ~~~
765 redef fun clone
766 do
767 var res = new ArrayMap[K,E]
768 res.recover_with self
769 return res
770 end
771 end
772
773 private class ArrayMapKeys[K, E]
774 super RemovableCollection[K]
775 # The original map
776 var map: ArrayMap[K, E]
777 redef fun count(k) do if self.has(k) then return 1 else return 0
778 redef fun first do return self.map._items.first.first
779 redef fun has(k) do return self.map.index(k) >= 0
780 redef fun has_only(k) do return (self.has(k) and self.length == 1) or self.is_empty
781 redef fun is_empty do return self.map.is_empty
782 redef fun length do return self.map.length
783 redef fun iterator do return new MapKeysIterator[K, E](self.map.iterator)
784 redef fun clear do self.map.clear
785 redef fun remove(key)
786 do
787 var i = self.map.index(key)
788 if i >= 0 then self.map.remove_at_index(i)
789 end
790 redef fun remove_all(key) do self.remove(key)
791 end
792
793 private class ArrayMapValues[K, E]
794 super RemovableCollection[E]
795 # The original map
796 var map: ArrayMap[K, E]
797 redef fun first do return self.map._items.first.second
798 redef fun is_empty do return self.map.is_empty
799 redef fun length do return self.map.length
800 redef fun iterator do return new MapValuesIterator[K, E](self.map.iterator)
801
802 # O(n)
803 redef fun has(item)
804 do
805 for i in self.map._items do if i.second == item then return true
806 return false
807 end
808
809 # O(n)
810 redef fun has_only(item)
811 do
812 for i in self.map._items do if i.second != item then return false
813 return true
814 end
815
816 # O(n)
817 redef fun count(item)
818 do
819 var nb = 0
820 for i in self.map._items do if i.second == item then nb += 1
821 return nb
822 end
823
824 redef fun clear do self.map.clear
825
826 redef fun remove(item)
827 do
828 var map = self.map
829 var i = map._items.length - 1
830 while i >= 0 do
831 if map._items[i].second == item then
832 map.remove_at_index(i)
833 return
834 end
835 i -= 1
836 end
837 end
838
839 redef fun remove_all(item)
840 do
841 var map = self.map
842 var i = map._items.length - 1
843 while i >= 0 do
844 if map._items[i].second == item then
845 map.remove_at_index(i)
846 end
847 i -= 1
848 end
849 end
850 end
851
852 # Comparable array for comparable elements.
853 #
854 # For two arrays, if one is a prefix, then it is lower.
855 #
856 # ~~~
857 # var a12 = new ArrayCmp[nullable Int].with_items(1,2)
858 # var a123 = new ArrayCmp[nullable Int].with_items(1,2,3)
859 # assert a12 < a123
860 # ~~~
861 #
862 # Otherwise, the first element just after the longest
863 # common prefix gives the order between the two arrays.
864 #
865 # ~~~
866 # var a124 = new ArrayCmp[nullable Int].with_items(1,2,4)
867 # var a13 = new ArrayCmp[nullable Int].with_items(1,3)
868 # assert a12 < a123
869 # assert a123 < a13
870 # ~~~
871 #
872 # Obviously, two equal arrays are equal.
873 #
874 # ~~~
875 # var b12 = new ArrayCmp[nullable Int].with_items(1,2)
876 # assert (a12 <=> b12) == 0
877 # ~~~
878 #
879 # `null` is considered lower than any other elements.
880 # But is still greater than no element.
881 #
882 # ~~~
883 # var a12n = new ArrayCmp[nullable Int].with_items(1,2,null)
884 # assert a12n < a123
885 # assert a12 < a12n
886 # ~~~
887 class ArrayCmp[E: nullable Comparable]
888 super Array[E]
889 super Comparable
890 redef type OTHER: ArrayCmp[E] is fixed
891
892 redef fun <(o) do return (self <=> o) < 0
893
894 redef fun <=>(o)
895 do
896 var it = _items
897 var oit = o._items
898 var i = 0
899 var l = length
900 var ol = o.length
901 var len
902 if l < ol then len = l else len = ol
903 while i < len do
904 var a = it[i]
905 var b = oit[i]
906 if a != null then
907 if b == null then return 1
908 var d = a <=> b
909 if d != 0 then return d
910 else
911 if b != null then return -1
912 end
913 i += 1
914 end
915 return l <=> ol
916 end
917 end
918
919 # Others tools ################################################################
920
921 redef class Iterator[E]
922 # Interate on `self` and build an array
923 fun to_a: Array[E]
924 do
925 var res = new Array[E]
926 while is_ok do
927 res.add(item)
928 next
929 end
930 return res
931 end
932 end
933
934 redef class Collection[E]
935 # Build a new array from a collection
936 fun to_a: Array[E]
937 do
938 var res = new Array[E].with_capacity(length)
939 res.add_all(self)
940 return res
941 end
942 end
943
944 # Native classes ##############################################################
945
946 # Native Nit array
947 # Access are unchecked and it has a fixed size
948 # Not for public use: may become private.
949 universal NativeArray[E]
950 # Creates a new NativeArray of capacity `length`
951 new(length: Int) is intern
952 # The length of the array
953 fun length: Int is intern
954 # Use `self` to initialize a standard Nit Array.
955 fun to_a: Array[E] do return new Array[E].with_native(self, length)
956
957 # Get item at `index`.
958 fun [](index: Int): E is intern
959
960 # Set `item` at `index`.
961 fun []=(index: Int, item: E) is intern
962
963 # Copy `length` items to `dest`.
964 fun copy_to(dest: NativeArray[E], length: Int) is intern
965 #fun =(o: NativeArray[E]): Bool is intern
966 #fun !=(o: NativeArray[E]): Bool is intern
967 end