lib: update some modules of standard to new constructors
[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 protected 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 return new ArrayIterator[E](self)
134 redef fun reverse_iterator do return new ArrayReverseIterator[E](self)
135 end
136
137 # Resizable one dimension array of objects.
138 abstract class AbstractArray[E]
139 super AbstractArrayRead[E]
140 super Sequence[E]
141
142 # Force the capacity to be at least `cap`.
143 # The capacity of the array is an internal information.
144 # However, this method can be used to prepare a large amount of add
145 fun enlarge(cap: Int) is abstract
146
147 redef fun push(item) do add(item)
148
149 redef fun pop
150 do
151 assert not_empty: not is_empty
152 var r = last
153 _length -= 1
154 return r
155 end
156
157 redef fun shift
158 do
159 assert not_empty: not is_empty
160 var r = first
161 var i = 1
162 var l = length
163 while i < l do
164 self[i-1] = self[i]
165 i += 1
166 end
167 _length = l - 1
168 return r
169 end
170
171 redef fun unshift(item)
172 do
173 var i = length - 1
174 while i >= 0 do
175 self[i+1] = self[i]
176 i -= 1
177 end
178 self[0] = item
179 end
180
181 redef fun insert(item: E, pos: Int)
182 do
183 enlarge(length + 1)
184 copy_to(pos, length-pos, self, pos + 1)
185 self[pos] = item
186 end
187
188 redef fun insert_all(coll, pos)
189 do
190 var l = coll.length
191 if l == 0 then return
192 enlarge(length + l)
193 _length += l
194 copy_to(pos, length-pos-l, self, pos + l)
195 for c in coll do
196 self[pos] = c
197 pos += 1
198 end
199 end
200
201 redef fun add(item) do self[length] = item
202
203 redef fun clear do _length = 0
204
205 redef fun remove(item) do remove_at(index_of(item))
206
207 redef fun remove_all(item)
208 do
209 var i = index_of(item)
210 while i >= 0 do
211 remove_at(i)
212 i = index_of_from(item, i)
213 end
214 end
215
216 redef fun remove_at(i)
217 do
218 var l = length
219 if i >= 0 and i < l then
220 var j = i + 1
221 while j < l do
222 self[j-1] = self[j]
223 j += 1
224 end
225 _length = l - 1
226 end
227 end
228
229 # Invert two elements in the array
230 #
231 # var a = [10, 20, 30, 40]
232 # a.swap_at(1, 3)
233 # assert a == [10, 40, 30, 20]
234 fun swap_at(a: Int,b: Int)
235 do
236 var e = self[a]
237 self[a] = self[b]
238 self[b] = e
239 end
240 end
241
242 # Resizable one dimension array of objects.
243 #
244 # Arrays have a literal representation.
245 # var a = [12, 32, 8]
246 # # is equivalent with:
247 # var b = new Array[Int]
248 # b.push(12)
249 # b.push(32)
250 # b.push(8)
251 # assert a == b
252 class Array[E]
253 super AbstractArray[E]
254 super ArrayCapable[E]
255
256 redef fun [](index)
257 do
258 assert index: index >= 0 and index < _length
259 return _items[index]
260 end
261
262 redef fun []=(index, item)
263 do
264 assert index: index >= 0 and index < _length + 1
265 if _capacity <= index then
266 enlarge(index + 1)
267 end
268 if _length <= index then
269 _length = index + 1
270 end
271 _items[index] = item
272 end
273
274 redef fun add(item)
275 do
276 var l = _length
277 if _capacity <= l then
278 enlarge(l + 1)
279 end
280 _length = l + 1
281 _items[l] = item
282 end
283
284 redef fun enlarge(cap)
285 do
286 var c = _capacity
287 if cap <= c then return
288 while c <= cap do c = c * 2 + 2
289 var a = calloc_array(c)
290 if _capacity > 0 then _items.copy_to(a, _length)
291 _items = a
292 _capacity = c
293 end
294
295 # Create an empty array.
296 init
297 do
298 _capacity = 0
299 _length = 0
300 end
301
302 # Create an array from a collection.
303 init from(items: Collection[E]) do
304 with_capacity(items.length)
305 self.add_all(items)
306 end
307
308 # Create an array with some `objects`.
309 init with_items(objects: E...)
310 do
311 _items = objects._items
312 _capacity = objects._capacity
313 _length = objects.length
314 end
315
316 # Create an empty array with a given capacity.
317 init with_capacity(cap: Int)
318 do
319 assert positive: cap >= 0
320 _items = calloc_array(cap)
321 _capacity = cap
322 _length = 0
323 end
324
325 # Create an array of `count` elements
326 init filled_with(value: E, count: Int)
327 do
328 assert positive: count >= 0
329 _items = calloc_array(count)
330 _capacity = count
331 _length = count
332 var i = 0
333 while i < count do
334 self[i] = value
335 i += 1
336 end
337 end
338
339 # Create a array filled with a given native array.
340 init with_native(nat: NativeArray[E], size: Int)
341 do
342 assert positive: size >= 0
343 _items = nat
344 _capacity = size
345 _length = size
346 end
347
348 # The internal storage.
349 private var items: nullable NativeArray[E] = null
350
351 # Do not use this method
352 # FIXME: Remove it once modules can intrude non local modules
353 fun intern_items: NativeArray[E] do return _items.as(not null)
354
355 # The size of `_items`.
356 private var capacity: Int = 0
357
358 redef fun ==(o)
359 do
360 if not o isa Array[nullable Object] then return super
361 # Efficient implementation
362 var l = length
363 if l != o.length then return false
364 var i = 0
365 var it = _items
366 var oit = o._items
367 while i < l do
368 if it[i] != oit[i] then return false
369 i += 1
370 end
371 return true
372 end
373
374 # Concatenation of arrays.
375 #
376 # Returns a new array built by concatenating `self` and `other` together.
377 #
378 # var a1 = [1,2,3]
379 # var a2 = [4,5,6]
380 # var a3 = a1 + a2
381 # assert a3 == [1,2,3,4,5,6]
382 #
383 # Because a new array is always created, future modification on `self` and `other`
384 # does not impact the previously computed result.
385 #
386 # a1.add(30)
387 # a2.add(60)
388 # assert a3 == [1,2,3,4,5,6] # unchanged
389 # assert a1 + a2 == [1,2,3,30,4,5,6,60]
390 fun +(other: Array[E]): Array[E]
391 do
392 var res = new Array[E].with_capacity(length + other.length)
393 res.append(self)
394 res.append(other)
395 return res
396 end
397 end
398
399 # An `Iterator` on `AbstractArray`
400 private class ArrayIterator[E]
401 super IndexedIterator[E]
402
403 redef fun item do return _array[_index]
404
405 # redef fun item=(e) do _array[_index] = e
406
407 redef fun is_ok do return _index < _array.length
408
409 redef fun next do _index += 1
410
411 redef var index = 0
412
413 private var array: AbstractArrayRead[E]
414 end
415
416 private class ArrayReverseIterator[E]
417 super ArrayIterator[E]
418
419 redef fun is_ok do return _index >= 0
420
421 redef fun next do _index -= 1
422
423 init
424 do
425 _index = _array.length - 1
426 end
427 end
428
429 # Others collections ##########################################################
430
431 # A set implemented with an Array.
432 class ArraySet[E: Object]
433 super Set[E]
434
435 # The stored elements.
436 private var array: Array[E] is noinit
437
438 redef fun has(e) do return _array.has(e)
439
440 redef fun add(e) do if not _array.has(e) then _array.add(e)
441
442 redef fun is_empty do return _array.is_empty
443
444 redef fun length do return _array.length
445
446 redef fun first
447 do
448 assert _array.length > 0
449 return _array.first
450 end
451
452 redef fun remove(item)
453 do
454 var i = _array.index_of(item)
455 if i >= 0 then remove_at(i)
456 end
457
458 redef fun remove_all(item) do remove(item)
459
460 redef fun clear do _array.clear
461
462 redef fun iterator do return new ArraySetIterator[E](_array.iterator)
463
464 # Assume the capacity is at least `cap`.
465 fun enlarge(cap: Int) do _array.enlarge(cap)
466
467 private fun remove_at(i: Int)
468 do
469 _array[i] = _array.last
470 _array.pop
471 end
472
473 # Create an empty set
474 init do _array = new Array[E]
475
476 # Create an empty set with a given capacity.
477 init with_capacity(i: Int) do _array = new Array[E].with_capacity(i)
478
479 redef fun new_set do return new ArraySet[E]
480 end
481
482 # Iterators on sets implemented with arrays.
483 private class ArraySetIterator[E: Object]
484 super Iterator[E]
485
486 redef fun is_ok do return _iter.is_ok
487
488 redef fun next do _iter.next
489
490 redef fun item: E do return _iter.item
491
492 private var iter: ArrayIterator[E]
493 end
494
495
496 # Associative arrays implemented with an array of (key, value) pairs.
497 class ArrayMap[K: Object, E]
498 super CoupleMap[K, E]
499
500 # O(n)
501 redef fun [](key)
502 do
503 var i = index(key)
504 if i >= 0 then
505 return _items[i].second
506 else
507 return provide_default_value(key)
508 end
509 end
510
511 # O(n)
512 redef fun []=(key, item)
513 do
514 var i = index(key)
515 if i >= 0 then
516 _items[i].second = item
517 else
518 _items.push(new Couple[K,E](key, item))
519 end
520 end
521
522 redef var keys: RemovableCollection[K] = new ArrayMapKeys[K, E](self)
523 redef var values: RemovableCollection[E] = new ArrayMapValues[K, E](self)
524
525 # O(1)
526 redef fun length do return _items.length
527
528 redef fun couple_iterator do return _items.iterator
529
530 redef fun is_empty do return _items.is_empty
531
532 redef fun clear do _items.clear
533
534 # Assume the capacity to be at least `cap`.
535 fun enlarge(cap: Int) do _items.enlarge(cap)
536
537 redef fun couple_at(key)
538 do
539 var i = index(key)
540 if i >= 0 then
541 return _items[i]
542 else
543 return null
544 end
545 end
546
547 # Internal storage.
548 private var items = new Array[Couple[K,E]]
549
550 # fast remove the ith element of the array
551 private fun remove_at_index(i: Int)
552 do
553 _items[i] = _items.last
554 _items.pop
555 end
556
557 # The last positive result given by a index(1) call
558 private var last_index: Int = 0
559
560 # Where is the `key` in `_item`?
561 # return -1 if not found
562 private fun index(key: K): Int
563 do
564 var l = _last_index
565 if l < _items.length and _items[l].first == key then return l
566
567 var i = 0
568 while i < _items.length do
569 if _items[i].first == key then
570 _last_index = i
571 return i
572 end
573 i += 1
574 end
575 return -1
576 end
577 end
578
579 private class ArrayMapKeys[K: Object, E]
580 super RemovableCollection[K]
581 # The original map
582 var map: ArrayMap[K, E]
583 redef fun count(k) do if self.has(k) then return 1 else return 0
584 redef fun first do return self.map._items.first.first
585 redef fun has(k) do return self.map.index(k) >= 0
586 redef fun has_only(k) do return (self.has(k) and self.length == 1) or self.is_empty
587 redef fun is_empty do return self.map.is_empty
588 redef fun length do return self.map.length
589 redef fun iterator do return new MapKeysIterator[K, E](self.map.iterator)
590 redef fun clear do self.map.clear
591 redef fun remove(key)
592 do
593 var i = self.map.index(key)
594 if i >= 0 then self.map.remove_at_index(i)
595 end
596 redef fun remove_all(key) do self.remove(key)
597 end
598
599 private class ArrayMapValues[K: Object, E]
600 super RemovableCollection[E]
601 # The original map
602 var map: ArrayMap[K, E]
603 redef fun first do return self.map._items.first.second
604 redef fun is_empty do return self.map.is_empty
605 redef fun length do return self.map.length
606 redef fun iterator do return new MapValuesIterator[K, E](self.map.iterator)
607
608 # O(n)
609 redef fun has(item)
610 do
611 for i in self.map._items do if i.second == item then return true
612 return false
613 end
614
615 # O(n)
616 redef fun has_only(item)
617 do
618 for i in self.map._items do if i.second != item then return false
619 return true
620 end
621
622 # O(n)
623 redef fun count(item)
624 do
625 var nb = 0
626 for i in self.map._items do if i.second == item then nb += 1
627 return nb
628 end
629
630 redef fun clear do self.map.clear
631
632 redef fun remove(item)
633 do
634 var map = self.map
635 var i = map._items.length - 1
636 while i >= 0 do
637 if map._items[i].second == item then
638 map.remove_at_index(i)
639 return
640 end
641 i -= 1
642 end
643 end
644
645 redef fun remove_all(item)
646 do
647 var map = self.map
648 var i = map._items.length - 1
649 while i >= 0 do
650 if map._items[i].second == item then
651 map.remove_at_index(i)
652 end
653 i -= 1
654 end
655 end
656 end
657
658 # Comparable array for comparable elements.
659 #
660 # For two arrays, if one is a prefix, then it is lower.
661 #
662 # ~~~
663 # var a12 = new ArrayCmp[nullable Int].with_items(1,2)
664 # var a123 = new ArrayCmp[nullable Int].with_items(1,2,3)
665 # assert a12 < a123
666 # ~~~
667 #
668 # Otherwise, the first element just after the longest
669 # common prefix gives the order between the two arrays.
670 #
671 # ~~~
672 # var a124 = new ArrayCmp[nullable Int].with_items(1,2,4)
673 # var a13 = new ArrayCmp[nullable Int].with_items(1,3)
674 # assert a12 < a123
675 # assert a123 < a13
676 # ~~~
677 #
678 # Obviously, two equal arrays are equal.
679 #
680 # ~~~
681 # var b12 = new ArrayCmp[nullable Int].with_items(1,2)
682 # assert (a12 <=> b12) == 0
683 # ~~~
684 #
685 # `null` is considered lower than any other elements.
686 # But is still greater than no element.
687 #
688 # ~~~
689 # var a12n = new ArrayCmp[nullable Int].with_items(1,2,null)
690 # assert a12n < a123
691 # assert a12 < a12n
692 # ~~~
693 class ArrayCmp[E: nullable Comparable]
694 super Array[E]
695 super Comparable
696 redef type OTHER: ArrayCmp[E] is fixed
697
698 redef fun <(o) do return (self <=> o) < 0
699
700 redef fun <=>(o)
701 do
702 var it = _items
703 var oit = o._items
704 var i = 0
705 var l = length
706 var ol = o.length
707 var len
708 if l < ol then len = l else len = ol
709 while i < len do
710 var a = it[i]
711 var b = oit[i]
712 if a != null then
713 if b == null then return 1
714 var d = a <=> b.as(Comparable)
715 if d != 0 then return d
716 else
717 if b != null then return -1
718 end
719 i += 1
720 end
721 return l <=> ol
722 end
723 end
724
725 # Others tools ################################################################
726
727 redef class Iterator[E]
728 # Interate on `self` and build an array
729 fun to_a: Array[E]
730 do
731 var res = new Array[E]
732 while is_ok do
733 res.add(item)
734 next
735 end
736 return res
737 end
738 end
739
740 redef class Collection[E]
741 # Build a new array from a collection
742 fun to_a: Array[E]
743 do
744 var res = new Array[E].with_capacity(length)
745 res.add_all(self)
746 return res
747 end
748 end
749
750 # Native classes ##############################################################
751
752 # Subclasses of this class can create native arrays
753 interface ArrayCapable[E]
754 # Get a new array of `size` elements.
755 protected fun calloc_array(size: Int): NativeArray[E] is intern
756 end
757
758 # Native Nit array
759 # Access are unchecked and it has a fixed size
760 # Not for public use: may become private.
761 universal NativeArray[E]
762 # Creates a new NativeArray of capacity `length`
763 new(length: Int) is intern
764 # The length of the array
765 fun length: Int is intern
766 # Use `self` to initialize a standard Nit Array.
767 fun to_a: Array[E] do return new Array[E].with_native(self, length)
768 fun [](index: Int): E is intern
769 fun []=(index: Int, item: E) is intern
770 fun copy_to(dest: NativeArray[E], length: Int) is intern
771 #fun =(o: NativeArray[E]): Bool is intern
772 #fun !=(o: NativeArray[E]): Bool is intern
773 end