Fix crash when parsing metadata, fixes bug 563390
[vala-lang.git] / gee / arraylist.vala
blob183119b2651face744b159c5c559b86f2cf969c3
1 /* arraylist.vala
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
21 * Author:
22 * Jürg Billeter <j@bitron.ch>
25 using GLib;
27 /**
28 * Arrays of arbitrary elements which grow automatically as elements are added.
30 public class Gee.ArrayList<G> : CollectionObject, Iterable<G>, Collection<G>, List<G> {
31 public int size {
32 get { return _size; }
35 public EqualFunc equal_func {
36 set { _equal_func = value; }
39 private G[] _items = new G[4];
40 private int _size;
41 private EqualFunc _equal_func;
43 // concurrent modification protection
44 private int _stamp = 0;
46 public ArrayList (EqualFunc equal_func = GLib.direct_equal) {
47 this.equal_func = equal_func;
50 public Type get_element_type () {
51 return typeof (G);
54 public Gee.Iterator<G> iterator () {
55 return new Iterator<G> (this);
58 public bool contains (G item) {
59 return (index_of (item) != -1);
62 public int index_of (G item) {
63 for (int index = 0; index < _size; index++) {
64 if (_equal_func (_items[index], item)) {
65 return index;
68 return -1;
71 public G? get (int index) {
72 assert (index >= 0 && index < _size);
74 return _items[index];
77 public void set (int index, G item) {
78 assert (index >= 0 && index < _size);
80 _items[index] = item;
83 public bool add (G item) {
84 if (_size == _items.length) {
85 grow_if_needed (1);
87 _items[_size++] = item;
88 _stamp++;
89 return true;
92 public void insert (int index, G item) {
93 assert (index >= 0 && index <= _size);
95 if (_size == _items.length) {
96 grow_if_needed (1);
98 shift (index, 1);
99 _items[index] = item;
100 _stamp++;
103 public bool remove (G item) {
104 for (int index = 0; index < _size; index++) {
105 if (_equal_func (_items[index], item)) {
106 remove_at (index);
107 return true;
110 return false;
113 public void remove_at (int index) {
114 assert (index >= 0 && index < _size);
116 _items[index] = null;
118 shift (index + 1, -1);
120 _stamp++;
123 public void clear () {
124 for (int index = 0; index < _size; index++) {
125 _items[index] = null;
127 _size = 0;
128 _stamp++;
131 private void shift (int start, int delta) {
132 assert (start >= 0 && start <= _size && start >= -delta);
134 _items.move (start, start + delta, _size - start);
136 _size += delta;
139 private void grow_if_needed (int new_count) {
140 assert (new_count >= 0);
142 int minimum_size = _size + new_count;
143 if (minimum_size > _items.length) {
144 // double the capacity unless we add even more items at this time
145 set_capacity (new_count > _items.length ? minimum_size : 2 * _items.length);
149 private void set_capacity (int value) {
150 assert (value >= _size);
152 _items.resize (value);
155 private class Iterator<G> : CollectionObject, Gee.Iterator<G> {
156 public ArrayList<G> list {
157 set {
158 _list = value;
159 _stamp = _list._stamp;
163 private ArrayList<G> _list;
164 private int _index = -1;
166 // concurrent modification protection
167 public int _stamp = 0;
169 public Iterator (ArrayList list) {
170 this.list = list;
173 public bool next () {
174 assert (_stamp == _list._stamp);
175 if (_index < _list._size) {
176 _index++;
178 return (_index < _list._size);
181 public G? get () {
182 assert (_stamp == _list._stamp);
184 if (_index < 0 || _index >= _list._size) {
185 return null;
188 return _list.get (_index);