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