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