3 * Copyright (C) 2004-2005 Novell, Inc
4 * Copyright (C) 2005 David Waite
5 * Copyright (C) 2007-2008 Jürg Billeter
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Jürg Billeter <j@bitron.ch>
28 * Arrays of arbitrary elements which grow automatically as elements are added.
30 public class Vala
.ArrayList
<G
> : List
<G
> {
31 public override int size
{
35 public EqualFunc
<G
> equal_func
{
36 set { _equal_func
= value
; }
39 internal G
[] _items
= new G
[4];
41 private EqualFunc
<G
> _equal_func
;
43 // concurrent modification protection
44 private int _stamp
= 0;
46 public ArrayList (EqualFunc
<G
> equal_func
= GLib
.direct_equal
) {
47 this
.equal_func
= equal_func
;
50 public override Type
get_element_type () {
54 public override Vala
.Iterator
<G
> iterator () {
55 return new Iterator
<G
> (this
);
58 public override bool contains (G item
) {
59 return (index_of (item
) != -1);
62 public override int index_of (G item
) {
63 for (int index
= 0; index
< _size
; index
++) {
64 if (_equal_func (_items
[index
], item
)) {
71 public override G?
get (int index
) {
72 assert (index
>= 0 && index
< _size
);
77 public override void set (int index
, G item
) {
78 assert (index
>= 0 && index
< _size
);
83 public override bool add (G item
) {
84 if (_size
== _items
.length
) {
87 _items
[_size
++] = item
;
92 public override void insert (int index
, G item
) {
93 assert (index
>= 0 && index
<= _size
);
95 if (_size
== _items
.length
) {
103 public override bool remove (G item
) {
104 for (int index
= 0; index
< _size
; index
++) {
105 if (_equal_func (_items
[index
], item
)) {
113 public override G
remove_at (int index
) {
114 assert (index
>= 0 && index
< _size
);
116 G item
= _items
[index
];
117 _items
[index
] = null;
119 shift (index
+ 1, -1);
125 public override void clear () {
126 for (int index
= 0; index
< _size
; index
++) {
127 _items
[index
] = null;
133 private void shift (int start
, int delta
) {
134 assert (start
>= 0 && start
<= _size
&& start
>= -delta
);
136 _items
.move (start
, start
+ delta
, _size
- start
);
141 private void grow_if_needed (int new_count
) {
142 assert (new_count
>= 0);
144 int minimum_size
= _size
+ new_count
;
145 if (minimum_size
> _items
.length
) {
146 // double the capacity unless we add even more items at this time
147 set_capacity (new_count
> _items
.length ? minimum_size
: 2 * _items
.length
);
151 private void set_capacity (int value
) {
152 assert (value
>= _size
);
154 _items
.resize (value
);
157 private class Iterator
<G
> : Vala
.Iterator
<G
> {
158 public ArrayList
<G
> list
{
161 _stamp
= _list
._stamp
;
165 private ArrayList
<G
> _list
;
166 private int _index
= -1;
167 protected bool _removed
= false;
169 // concurrent modification protection
170 public int _stamp
= 0;
172 public Iterator (ArrayList list
) {
176 public override bool next () {
177 assert (_stamp
== _list
._stamp
);
178 if (_index
< _list
._size
) {
182 return (_index
< _list
._size
);
185 public override bool has_next () {
186 assert (_stamp
== _list
._stamp
);
187 return (_index
+ 1 < _list
._size
);
190 public override G?
get () {
191 assert (_stamp
== _list
._stamp
);
194 if (_index
< 0 || _index
>= _list
._size
) {
198 return _list
.get (_index
);
201 public override void remove () {
202 assert (_stamp
== _list
._stamp
);
203 assert (! _removed
&& _index
>= 0);
204 assert (_index
< _list
._size
);
206 _list
.remove_at (_index
);
209 _stamp
= _list
._stamp
;
212 public override bool valid
{
214 return _index
>= 0 && _index
< _list
._size
&& ! _removed
;