1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2004-2008 Jean Privat <jean@pryen.org>
4 # Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
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
14 # This module introduces the standard array structure.
15 # It also implements two other abstract collections : ArrayMap and ArraySet
18 import abstract_collection
20 # One dimension array of objects.
21 abstract class AbstractArrayRead[E
]
24 redef readable var _length
: Int = 0
26 redef fun is_empty
do return _length
== 0
33 if self[i
] == item
then return true
39 redef fun has_only
(item
)
44 if self[i
] != item
then return false
56 if self[i
] == item
then res
+= 1
62 redef fun index_of
(item
) do return index_of_from
(item
, 0)
64 # The index of the last occurrence of an element.
65 # Return -1 if not found.
66 fun last_index_of
(item
: E
): Int do return last_index_of_from
(item
, length-1
)
68 # The index of the first occurrence of an element starting from pos.
69 # Return -1 if not found.
70 fun index_of_from
(item
: E
, pos
: Int): Int
75 if self[i
] == item
then
83 # The index of the last occurrence of an element starting from pos.
84 # Return -1 if not found.
85 fun last_index_of_from
(item
: E
, pos
: Int): Int
89 if self[i
] == item
then
98 # Return a new array that is the reverse of `self'
100 # [1,2,3].reversed # -> [3, 2, 1]
101 fun reversed
: Array[E
]
104 var result
= new Array[E
].with_capacity
(cmp
)
107 result
.add
(self[cmp
])
112 # Copy a portion of `self' to an other array.
114 # var a = [1, 2, 3, 4]
115 # var b = [10, 20, 30, 40, 50]
116 # a.copy_to(1, 2, b, 2)
117 # b # -> [10, 20, 2, 3, 50]
118 protected fun copy_to
(start
: Int, len
: Int, dest
: AbstractArray[E
], new_start
: Int)
124 dest
[new_start
+i
] = self[start
+i
]
134 if e
!= null then e
.output
139 redef fun iterator
: ArrayIterator[E
] do return new ArrayIterator[E
](self)
141 # Two arrays are equals if they have the same items in the same order.
144 if not o
isa AbstractArray[E
] or o
is null then return false
146 if o
.length
!= l
then return false
149 if self[i
] != o
[i
] then return false
156 # Resizable one dimension array of objects.
157 abstract class AbstractArray[E
]
158 super AbstractArrayRead[E
]
161 # Force the capacity to be at least `cap'.
162 # The capacity of the array is an internal information.
163 # However, this method can be used to prepare a large amount of add
164 fun enlarge
(cap
: Int) is abstract
166 redef fun push
(item
) do add
(item
)
170 assert not_empty
: not is_empty
178 assert not_empty
: not is_empty
190 redef fun unshift
(item
)
200 # Insert an element at a given position, following elements are shifted.
202 # var a= [10, 20, 30, 40]
204 # a # -> [10, 20, 100, 30, 40]
205 fun insert
(item
: E
, pos
: Int)
208 copy_to
(pos
, length-pos
, self, pos
+ 1)
212 redef fun add
(item
) do self[length
] = item
214 redef fun clear
do _length
= 0
216 redef fun remove
(item
) do remove_at
(index_of
(item
))
218 redef fun remove_all
(item
)
220 var i
= index_of
(item
)
223 i
= index_of_from
(item
, i
)
227 redef fun remove_at
(i
)
230 if i
>= 0 and i
< l
then
240 # Invert two elements in the array
242 # var a = [10, 20, 30, 40]
244 # a # -> [10, 40, 30, 20]
245 fun swap_at
(a
: Int,b
: Int)
253 # Resizable one dimension array of objects.
255 # Arrays have a literal representation.
257 # is equivalent with:
263 super AbstractArray[E
]
264 super ArrayCapable[E
]
280 assert index
: index
>= 0 and index
< _length
284 redef fun []=(index
, item
)
286 assert index
: index
>= 0 and index
< _length
+ 1
287 if _capacity
<= index
then
290 if _length
<= index
then
299 if _capacity
<= l
then
306 redef fun enlarge
(cap
)
309 if cap
<= c
then return
310 while c
<= cap
do c
= c
* 2 + 2
311 var a
= calloc_array
(c
)
312 if _capacity
> 0 then _items
.copy_to
(a
, _length
)
317 # Create an empty array.
324 # Create an array with some `items'.
325 init with_items
(objects
: E
...)
327 _items
= objects
._items
328 _capacity
= objects
._capacity
329 _length
= objects
.length
332 # Create an empty array with a given capacity.
333 init with_capacity
(cap
: Int)
335 assert positive
: cap
>= 0
336 _items
= calloc_array
(cap
)
341 # Create an array of `count' elements
342 init filled_with
(value
: E
, count
: Int)
344 assert positive
: count
>= 0
345 _items
= calloc_array
(count
)
355 # Create a array filled with a given native array.
356 init with_native
(nat
: NativeArray[E
], size
: Int)
358 assert positive
: size
>= 0
364 # The internal storage.
365 var _items
: nullable NativeArray[E
] = null
367 # Do not use this method
368 # FIXME: Remove it once modules can intrude non local modules
369 fun intern_items
: NativeArray[E
] do return _items
.as(not null)
371 # The size of `_items'.
372 var _capacity
: Int = 0
374 # Sort the array using the !cmp function.
378 sub_sort
(0, length-1
) !cmp
(x
,y
) = cmp
(x
, y
)
381 # Sort `array' between `from' and `to' indices
382 private fun sub_sort
(from
: Int, to
: Int)
387 else if from
+ 7 < to
then
388 var pivot
= self[from
]
392 while i
<= to
and cmp
(self[i
], pivot
) <= 0 do i
+= 1
393 while j
> i
and cmp
(self[j
], pivot
) >= 0 do j
-= 1
400 self[from
] = self[i-1
]
402 sub_sort
(from
, i-2
) !cmp
(x
,y
) = cmp
(x
, y
)
403 sub_sort
(i
, to
) !cmp
(x
,y
) = cmp
(x
, y
)
411 if cmp
(min_v
, self[j
]) > 0 then
427 # An `Iterator' on `AbstractArray'
428 class ArrayIterator[E
]
429 super IndexedIterator[E
]
431 redef fun item
do return _array
[_index
]
433 # redef fun item=(e) do _array[_index] = e
435 redef fun is_ok
do return _index
< _array
.length
437 redef fun next
do _index
+= 1
439 init(a
: AbstractArrayRead[E
])
445 redef readable var _index
: Int = 0
446 var _array
: AbstractArrayRead[E
]
449 # Others collections ##########################################################
451 # A set implemented with an Array.
452 class ArraySet[E
: Object]
455 # The stored elements.
458 redef fun has
(e
) do return _array
.has
(e
)
460 redef fun add
(e
) do if not _array
.has
(e
) then _array
.add
(e
)
462 redef fun is_empty
do return _array
.is_empty
464 redef fun length
do return _array
.length
468 assert _array
.length
> 0
472 redef fun remove
(item
)
474 var i
= _array
.index_of
(item
)
475 if i
>= 0 then remove_at
(i
)
478 redef fun remove_all
(item
) do remove
(item
)
480 redef fun clear
do _array
.clear
482 redef fun iterator
do return new ArraySetIterator[E
](_array
.iterator
)
484 # Assume the capacity is at least `cap'.
485 fun enlarge
(cap
: Int) do _array
.enlarge
(cap
)
487 private fun remove_at
(i
: Int)
489 _array
[i
] = _array
.last
493 # Create an empty set
494 init do _array
= new Array[E
]
496 # Create an empty set with a given capacity.
497 init with_capacity
(i
: Int) do _array
= new Array[E
].with_capacity
(i
)
500 # Iterators on sets implemented with arrays.
501 class ArraySetIterator[E
: Object]
504 redef fun is_ok
do return _iter
.is_ok
506 redef fun next
do _iter
.next
508 redef fun item
: E
do return _iter
.item
510 init(iter
: ArrayIterator[E
]) do _iter
= iter
512 var _iter
: ArrayIterator[E
]
516 # Associative arrays implemented with an array of (key, value) pairs.
517 class ArrayMap[K
: Object, E
]
518 super CoupleMap[K
, E
]
525 return _items
[i
].second
532 redef fun []=(key
, item
)
536 _items
[i
].second
= item
538 _items
.push
(new Couple[K
,E
](key
, item
))
542 redef var keys
: ArrayMapKeys[K
, E
] = new ArrayMapKeys[K
, E
](self)
543 redef var values
: ArrayMapValues[K
, E
] = new ArrayMapValues[K
, E
](self)
546 redef fun length
do return _items
.length
548 redef fun iterator
: CoupleMapIterator[K
, E
] do return new CoupleMapIterator[K
, E
](_items
.iterator
)
550 redef fun is_empty
do return _items
.is_empty
552 redef fun clear
do _items
.clear
554 # Assume the capacity to be at least `cap'.
555 fun enlarge
(cap
: Int) do _items
.enlarge
(cap
)
557 redef fun couple_at
(key
)
568 var _items
: Array[Couple[K
,E
]]
570 # fast remove the ith element of the array
571 private fun remove_at_index
(i
: Int)
573 _items
[i
] = _items
.last
577 # The last positive result given by a index(1) call
578 var _last_index
: Int = 0
580 # Where is the `key' in `_item'?
581 # return -1 if not found
582 private fun index
(key
: K
): Int
585 if l
< _items
.length
and _items
[l
].first
== key
then return l
588 while i
< _items
.length
do
589 if _items
[i
].first
== key
then
601 _items
= new Array[Couple[K
,E
]]
605 class ArrayMapKeys[K
: Object, E
]
606 super RemovableCollection[K
]
608 var map
: ArrayMap[K
, E
]
609 redef fun count
(k
) do if self.has
(k
) then return 1 else return 0
610 redef fun first
do return self.map
._items
.first
.first
611 redef fun has
(k
) do return self.map
.index
(k
) >= 0
612 redef fun has_only
(k
) do return (self.has
(k
) and self.length
== 1) or self.is_empty
613 redef fun is_empty
do return self.map
.is_empty
614 redef fun length
do return self.map
.length
615 redef fun iterator
do return new MapKeysIterator[K
, E
](self.map
.iterator
)
616 redef fun clear
do self.map
.clear
617 redef fun remove
(key
)
619 var i
= self.map
.index
(key
)
620 if i
>= 0 then self.map
.remove_at_index
(i
)
622 redef fun remove_all
(key
) do self.remove
(key
)
625 class ArrayMapValues[K
: Object, E
]
626 super RemovableCollection[K
]
628 var map
: ArrayMap[K
, E
]
629 redef fun first
do return self.map
._items
.first
.first
630 redef fun is_empty
do return self.map
.is_empty
631 redef fun length
do return self.map
.length
632 redef fun iterator
do return new MapValuesIterator[K
, E
](self.map
.iterator
)
637 for i
in self.map
._items
do if i
.second
== item
then return true
642 redef fun has_only
(item
)
644 for i
in self.map
._items
do if i
.second
!= item
then return false
649 redef fun count
(item
)
652 for i
in self.map
._items
do if i
.second
== item
then nb
+= 1
656 redef fun clear
do self.map
.clear
658 redef fun remove
(item
)
661 var i
= map
._items
.length
- 1
663 if map
._items
[i
].second
== item
then
664 map
.remove_at_index
(i
)
671 redef fun remove_all
(item
)
674 var i
= map
._items
.length
- 1
676 if map
._items
[i
].second
== item
then
677 map
.remove_at_index
(i
)
685 # Others tools ################################################################
687 redef class Iterator[E
]
688 # Interate on `self' and build an array
691 var res
= new Array[E
]
700 redef class Collection[E
]
701 # Build a new array from a collection
708 # Native classes ##############################################################
710 # Subclasses of this class can create native arrays
711 interface ArrayCapable[E
]
712 # Get a new array of `size' elements.
713 protected fun calloc_array
(size
: Int): NativeArray[E
] is intern
716 # Native C array (void ...).
717 universal NativeArray[E
]
718 fun [](index
: Int): E
is intern
719 fun []=(index
: Int, item
: E
) is intern
720 fun copy_to
(dest
: NativeArray[E
], length
: Int) is intern
721 #fun =(o: NativeArray[E]): Bool is intern
722 #fun !=(o: NativeArray[E]): Bool is intern