lib/standard/array: add `Array::sub`
[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: E): Int do return last_index_of_from(item, length-1)
67
68 redef fun index_of_from(item: E, pos: Int): Int
69 do
70 var i = pos
71 var len = length
72 while i < len do
73 if self[i] == item then
74 return i
75 end
76 i += 1
77 end
78 return -1
79 end
80
81 redef fun last_index_of_from(item: E, pos: Int): Int
82 do
83 var i = pos
84 while i >= 0 do
85 if self[i] == item then
86 return i
87 else
88 i -= 1
89 end
90 end
91 return -1
92 end
93
94 # Return a new array that is the reverse of `self`
95 #
96 # assert [1,2,3].reversed == [3, 2, 1]
97 fun reversed: Array[E]
98 do
99 var cmp = _length
100 var result = new Array[E].with_capacity(cmp)
101 while cmp > 0 do
102 cmp -= 1
103 result.add(self[cmp])
104 end
105 return result
106 end
107
108 # Copy a portion of `self` to an other array.
109 #
110 # var a = [1, 2, 3, 4]
111 # var b = [10, 20, 30, 40, 50]
112 # a.copy_to(1, 2, b, 2)
113 # assert b == [10, 20, 2, 3, 50]
114 fun copy_to(start: Int, len: Int, dest: AbstractArray[E], new_start: Int)
115 do
116 # TODO native one
117 var i = len
118 while i > 0 do
119 i -= 1
120 dest[new_start+i] = self[start+i]
121 end
122 end
123
124 redef fun output
125 do
126 var i = 0
127 var l = length
128 while i < l do
129 var e = self[i]
130 if e != null then e.output
131 i += 1
132 end
133 end
134
135 redef fun iterator: ArrayIterator[E] do
136 var res = _free_iterator
137 if res == null then return new ArrayIterator[E](self)
138 res._index = 0
139 _free_iterator = null
140 return res
141 end
142
143 # An old iterator, free to reuse.
144 # Once an iterator is `finish`, it become reusable.
145 # Since some arrays are iterated a lot, this avoid most of the
146 # continuous allocation/garbage-collection of the needed iterators.
147 private var free_iterator: nullable ArrayIterator[E] = null
148
149 redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
150
151 # Returns a sub-array containing `count` elements starting from `from`.
152 #
153 # For most cases (see other case bellow),
154 # the first element is `from` and
155 # the last element is `from+count-1`.
156 #
157 # ~~~
158 # var a = [10, 20, 30, 40, 50]
159 # assert a.sub(0, 3) == [10, 20, 30]
160 # assert a.sub(3, 2) == [40, 50]
161 # assert a.sub(3, 1) == [40]
162 # ~~~
163 #
164 # If `count` is 0 or negative then an empty array is returned
165 #
166 # ~~~
167 # assert a.sub(3,0).is_empty
168 # assert a.sub(3,-1).is_empty
169 # ~~~
170 #
171 # If `from < 0` or `from+count>length` then inexistent elements are ignored.
172 # In this case the length of the result is lower than count.
173 #
174 # ~~~
175 # assert a.sub(-2, 4) == [10, 20]
176 # assert a.sub(4, 99) == [50]
177 # assert a.sub(-9, 99) == [10,20,30,40,50]
178 # assert a.sub(-99, 9).is_empty
179 # ~~~
180 fun sub(from: Int, count: Int): Array[E] do
181 if from < 0 then
182 count += from
183 from = 0
184 end
185 if count < 0 then
186 count = 0
187 end
188 var to = from + count
189 if to > length then
190 to = length
191 end
192 var res = new Array[E].with_capacity(to - from)
193 while from < to do
194 res.add(self[from])
195 from += 1
196 end
197 return res
198 end
199 end
200
201 # Resizable one dimension array of objects.
202 abstract class AbstractArray[E]
203 super AbstractArrayRead[E]
204 super Sequence[E]
205
206 # Force the capacity to be at least `cap`.
207 # The capacity of the array is an internal information.
208 # However, this method can be used to prepare a large amount of add
209 fun enlarge(cap: Int) is abstract
210
211 redef fun push(item) do add(item)
212
213 redef fun pop
214 do
215 assert not_empty: not is_empty
216 var r = last
217 _length -= 1
218 return r
219 end
220
221 redef fun shift
222 do
223 assert not_empty: not is_empty
224 var r = first
225 var i = 1
226 var l = length
227 while i < l do
228 self[i-1] = self[i]
229 i += 1
230 end
231 _length = l - 1
232 return r
233 end
234
235 redef fun unshift(item)
236 do
237 var i = length - 1
238 while i >= 0 do
239 self[i+1] = self[i]
240 i -= 1
241 end
242 self[0] = item
243 end
244
245 redef fun insert(item: E, pos: Int)
246 do
247 enlarge(length + 1)
248 copy_to(pos, length-pos, self, pos + 1)
249 self[pos] = item
250 end
251
252 redef fun insert_all(coll, pos)
253 do
254 var l = coll.length
255 if l == 0 then return
256 enlarge(length + l)
257 _length += l
258 copy_to(pos, length-pos-l, self, pos + l)
259 for c in coll do
260 self[pos] = c
261 pos += 1
262 end
263 end
264
265 redef fun add(item) do self[length] = item
266
267 redef fun clear do _length = 0
268
269 redef fun remove(item) do remove_at(index_of(item))
270
271 redef fun remove_all(item)
272 do
273 var i = index_of(item)
274 while i >= 0 do
275 remove_at(i)
276 i = index_of_from(item, i)
277 end
278 end
279
280 redef fun remove_at(i)
281 do
282 var l = length
283 if i >= 0 and i < l then
284 var j = i + 1
285 while j < l do
286 self[j-1] = self[j]
287 j += 1
288 end
289 _length = l - 1
290 end
291 end
292
293 # Invert two elements in the array
294 #
295 # var a = [10, 20, 30, 40]
296 # a.swap_at(1, 3)
297 # assert a == [10, 40, 30, 20]
298 fun swap_at(a: Int,b: Int)
299 do
300 var e = self[a]
301 self[a] = self[b]
302 self[b] = e
303 end
304 end
305
306 # Resizable one dimension array of objects.
307 #
308 # Arrays have a literal representation.
309 #
310 # var a = [12, 32, 8]
311 # # is equivalent with:
312 # var b = new Array[Int]
313 # b.push(12)
314 # b.push(32)
315 # b.push(8)
316 # assert a == b
317 class Array[E]
318 super AbstractArray[E]
319 super Cloneable
320
321 redef fun [](index)
322 do
323 assert index: index >= 0 and index < _length
324 return _items[index]
325 end
326
327 redef fun []=(index, item)
328 do
329 assert index: index >= 0 and index < _length + 1
330 if _capacity <= index then
331 enlarge(index + 1)
332 end
333 if _length <= index then
334 _length = index + 1
335 end
336 _items[index] = item
337 end
338
339 redef fun add(item)
340 do
341 var l = _length
342 if _capacity <= l then
343 enlarge(l + 1)
344 end
345 _length = l + 1
346 _items[l] = item
347 end
348
349 # Slight optimization for arrays
350 redef fun add_all(items)
351 do
352 var l = _length
353 var nl = l + items.length
354 if _capacity < nl then
355 enlarge nl
356 end
357
358 if items isa Array[E] then
359 var k = 0
360 while l < nl do
361 _items[l] = items._items[k]
362 l += 1
363 k += 1
364 end
365 else
366 for item in items do
367 _items[l] = item
368 l += 1
369 end
370 end
371
372 _length = nl
373 end
374
375 redef fun enlarge(cap)
376 do
377 var c = _capacity
378 if cap <= c then return
379 while c <= cap do c = c * 2 + 2
380 var a = new NativeArray[E](c)
381 if _capacity > 0 then _items.copy_to(a, _length)
382 _items = a
383 _capacity = c
384 end
385
386 # Create an empty array.
387 init
388 do
389 _capacity = 0
390 _length = 0
391 end
392
393 # Create an array from a collection.
394 init from(items: Collection[E]) do
395 with_capacity(items.length)
396 self.add_all(items)
397 end
398
399 # Create an array with some `objects`.
400 init with_items(objects: E...)
401 do
402 _items = objects._items
403 _capacity = objects._capacity
404 _length = objects.length
405 end
406
407 # Create an empty array with a given capacity.
408 init with_capacity(cap: Int)
409 do
410 assert positive: cap >= 0
411 _items = new NativeArray[E](cap)
412 _capacity = cap
413 _length = 0
414 end
415
416 # Create an array of `count` elements
417 init filled_with(value: E, count: Int)
418 do
419 assert positive: count >= 0
420 _items = new NativeArray[E](count)
421 _capacity = count
422 _length = count
423 var i = 0
424 while i < count do
425 self[i] = value
426 i += 1
427 end
428 end
429
430 # Create a array filled with a given native array.
431 init with_native(nat: NativeArray[E], size: Int)
432 do
433 assert positive: size >= 0
434 _items = nat
435 _capacity = size
436 _length = size
437 end
438
439 # The internal storage.
440 private var items: nullable NativeArray[E] = null
441
442 # The size of `_items`.
443 private var capacity: Int = 0
444
445 redef fun ==(o)
446 do
447 if not o isa Array[nullable Object] then return super
448 # Efficient implementation
449 var l = length
450 if l != o.length then return false
451 var i = 0
452 var it = _items
453 var oit = o._items
454 while i < l do
455 if it[i] != oit[i] then return false
456 i += 1
457 end
458 return true
459 end
460
461 # Shallow clone of `self`
462 #
463 # ~~~
464 # var a = [1,2,3]
465 # var b = a.clone
466 # assert a == b
467 # a.add 4
468 # assert a != b
469 # b.add 4
470 # assert a == b
471 # ~~~
472 #
473 # Note that the clone is shallow and elements are shared between `self` and the result.
474 #
475 # ~~~
476 # var aa = [a]
477 # var bb = aa.clone
478 # assert aa == bb
479 # aa.first.add 5
480 # assert aa == bb
481 # ~~~
482 redef fun clone do return to_a
483
484 # Concatenation of arrays.
485 #
486 # Returns a new array built by concatenating `self` and `other` together.
487 #
488 # var a1 = [1,2,3]
489 # var a2 = [4,5,6]
490 # var a3 = a1 + a2
491 # assert a3 == [1,2,3,4,5,6]
492 #
493 # Because a new array is always created, future modification on `self` and `other`
494 # does not impact the previously computed result.
495 #
496 # a1.add(30)
497 # a2.add(60)
498 # assert a3 == [1,2,3,4,5,6] # unchanged
499 # assert a1 + a2 == [1,2,3,30,4,5,6,60]
500 fun +(other: Array[E]): Array[E]
501 do
502 var res = new Array[E].with_capacity(length + other.length)
503 res.append(self)
504 res.append(other)
505 return res
506 end
507
508 # Repetition of arrays.
509 #
510 # returns a new array built by concatenating `self` `repeat` times.
511 #
512 # var a = [1,2,3]
513 # assert (a * 0).is_empty
514 # assert a * 1 == [1,2,3]
515 # assert a * 2 == [1,2,3,1,2,3]
516 # assert (a * 10).length == 30
517 fun *(repeat: Int): Array[E]
518 do
519 assert repeat >= 0
520 var res = new Array[E].with_capacity(length * repeat)
521 while repeat > 0 do
522 res.add_all(self)
523 repeat -= 1
524 end
525 return res
526 end
527 end
528
529 # An `Iterator` on `AbstractArray`
530 private class ArrayIterator[E]
531 super IndexedIterator[E]
532
533 redef fun item do return _array[_index]
534
535 # redef fun item=(e) do _array[_index] = e
536
537 redef fun is_ok do return _index < _array.length
538
539 redef fun next do _index += 1
540
541 redef var index = 0
542
543 var array: AbstractArrayRead[E]
544
545 redef fun finish do _array._free_iterator = self
546 end
547
548 private class ArrayReverseIterator[E]
549 super ArrayIterator[E]
550
551 redef fun is_ok do return _index >= 0
552
553 redef fun next do _index -= 1
554
555 init
556 do
557 _index = _array.length - 1
558 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.as(Comparable)
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