PageRenderTime 25ms CodeModel.GetById 20ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/gee/gee/arraylist.vala

http://libgdom3.googlecode.com/
Vala | 193 lines | 124 code | 40 blank | 29 comment | 22 complexity | 799ff8e2fc7407be2bb1849a4a773f6a MD5 | raw file
  1/* arraylist.vala
  2 *
  3 * Copyright (C) 2004-2005  Novell, Inc
  4 * Copyright (C) 2005  David Waite
  5 * Copyright (C) 2007-2008  J?rg Billeter
  6 *
  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.
 11
 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.
 16
 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
 20 *
 21 * Author:
 22 * 	J?rg Billeter <j@bitron.ch>
 23 */
 24
 25using GLib;
 26
 27/**
 28 * Arrays of arbitrary elements which grow automatically as elements are added.
 29 */
 30public class Gee.ArrayList<G> : Object, Iterable<G>, Collection<G>, List<G> {
 31	public int size {
 32		get { return _size; }
 33	}
 34
 35	public EqualFunc equal_func {
 36		set { _equal_func = value; }
 37	}
 38
 39	private G[] _items = new G[4];
 40	private int _size;
 41	private EqualFunc _equal_func;
 42
 43	// concurrent modification protection
 44	private int _stamp = 0;
 45
 46	public ArrayList (EqualFunc equal_func = GLib.direct_equal) {
 47		this.equal_func = equal_func;
 48	}
 49
 50	public Type get_element_type () {
 51		return typeof (G);
 52	}
 53
 54	public Gee.Iterator<G> iterator () {
 55		return new Iterator<G> (this);
 56	}
 57
 58	public bool contains (G item) {
 59		return (index_of (item) != -1);
 60	}
 61
 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;
 66			}
 67		}
 68		return -1;
 69	}
 70
 71	public weak G? get (int index) {
 72		assert (index >= 0 && index < _size);
 73
 74		return _items[index];
 75	}
 76
 77	public void set (int index, G item) {
 78		assert (index >= 0 && index < _size);
 79
 80		_items[index] = item;
 81	}
 82
 83	public bool add (G item) {
 84		if (_size == _items.length) {
 85			grow_if_needed (1);
 86		}
 87		_items[_size++] = item;
 88		_stamp++;
 89		return true;
 90	}
 91
 92	public void insert (int index, G item) {
 93		assert (index >= 0 && index <= _size);
 94
 95		if (_size == _items.length) {
 96			grow_if_needed (1);
 97		}
 98		shift (index, 1);
 99		_items[index] = item;
100		_stamp++;
101	}
102
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;
108			}
109		}
110		return false;
111	}
112
113	public void remove_at (int index) {
114		assert (index >= 0 && index < _size);
115
116		_items[index] = null;
117
118		shift (index + 1, -1);
119
120		_stamp++;
121	}
122
123	public void clear () {
124		for (int index = 0; index < _size; index++) {
125			_items[index] = null;
126		}
127		_size = 0;
128		_stamp++;
129	}
130
131	private void shift (int start, int delta) {
132		assert (start >= 0 && start <= _size && start >= -delta);
133
134		_items.move (start, start + delta, _size - start);
135
136		_size += delta;
137	}
138
139	private void grow_if_needed (int new_count) {
140		assert (new_count >= 0);
141
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);
146		}
147	}
148
149	private void set_capacity (int value) {
150		assert (value >= _size);
151
152		_items.resize (value);
153	}
154
155	private class Iterator<G> : Object, Gee.Iterator<G> {
156		public ArrayList<G> list {
157			set {
158				_list = value;
159				_stamp = _list._stamp;
160			}
161		}
162
163		private ArrayList<G> _list;
164		private int _index = -1;
165
166		// concurrent modification protection
167		public int _stamp = 0;
168
169		public Iterator (ArrayList list) {
170			this.list = list;
171		}
172
173		public bool next () {
174			assert (_stamp == _list._stamp);
175			if (_index < _list._size) {
176				_index++;
177			}
178			return (_index < _list._size);
179		}
180
181		public weak G? get () {
182			assert (_stamp == _list._stamp);
183
184			if (_index < 0 || _index >= _list._size) {
185				return null;
186			}
187
188			return _list.get (_index);
189		}
190
191	}
192}
193