/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. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. * Author:
  20. * J?rg Billeter <j@bitron.ch>
  21. */
  22. using GLib;
  23. /**
  24. * Arrays of arbitrary elements which grow automatically as elements are added.
  25. */
  26. public class Gee.ArrayList<G> : Object, Iterable<G>, Collection<G>, List<G> {
  27. public int size {
  28. get { return _size; }
  29. }
  30. public EqualFunc equal_func {
  31. set { _equal_func = value; }
  32. }
  33. private G[] _items = new G[4];
  34. private int _size;
  35. private EqualFunc _equal_func;
  36. // concurrent modification protection
  37. private int _stamp = 0;
  38. public ArrayList (EqualFunc equal_func = GLib.direct_equal) {
  39. this.equal_func = equal_func;
  40. }
  41. public Type get_element_type () {
  42. return typeof (G);
  43. }
  44. public Gee.Iterator<G> iterator () {
  45. return new Iterator<G> (this);
  46. }
  47. public bool contains (G item) {
  48. return (index_of (item) != -1);
  49. }
  50. public int index_of (G item) {
  51. for (int index = 0; index < _size; index++) {
  52. if (_equal_func (_items[index], item)) {
  53. return index;
  54. }
  55. }
  56. return -1;
  57. }
  58. public weak G? get (int index) {
  59. assert (index >= 0 && index < _size);
  60. return _items[index];
  61. }
  62. public void set (int index, G item) {
  63. assert (index >= 0 && index < _size);
  64. _items[index] = item;
  65. }
  66. public bool add (G item) {
  67. if (_size == _items.length) {
  68. grow_if_needed (1);
  69. }
  70. _items[_size++] = item;
  71. _stamp++;
  72. return true;
  73. }
  74. public void insert (int index, G item) {
  75. assert (index >= 0 && index <= _size);
  76. if (_size == _items.length) {
  77. grow_if_needed (1);
  78. }
  79. shift (index, 1);
  80. _items[index] = item;
  81. _stamp++;
  82. }
  83. public bool remove (G item) {
  84. for (int index = 0; index < _size; index++) {
  85. if (_equal_func (_items[index], item)) {
  86. remove_at (index);
  87. return true;
  88. }
  89. }
  90. return false;
  91. }
  92. public void remove_at (int index) {
  93. assert (index >= 0 && index < _size);
  94. _items[index] = null;
  95. shift (index + 1, -1);
  96. _stamp++;
  97. }
  98. public void clear () {
  99. for (int index = 0; index < _size; index++) {
  100. _items[index] = null;
  101. }
  102. _size = 0;
  103. _stamp++;
  104. }
  105. private void shift (int start, int delta) {
  106. assert (start >= 0 && start <= _size && start >= -delta);
  107. _items.move (start, start + delta, _size - start);
  108. _size += delta;
  109. }
  110. private void grow_if_needed (int new_count) {
  111. assert (new_count >= 0);
  112. int minimum_size = _size + new_count;
  113. if (minimum_size > _items.length) {
  114. // double the capacity unless we add even more items at this time
  115. set_capacity (new_count > _items.length ? minimum_size : 2 * _items.length);
  116. }
  117. }
  118. private void set_capacity (int value) {
  119. assert (value >= _size);
  120. _items.resize (value);
  121. }
  122. private class Iterator<G> : Object, Gee.Iterator<G> {
  123. public ArrayList<G> list {
  124. set {
  125. _list = value;
  126. _stamp = _list._stamp;
  127. }
  128. }
  129. private ArrayList<G> _list;
  130. private int _index = -1;
  131. // concurrent modification protection
  132. public int _stamp = 0;
  133. public Iterator (ArrayList list) {
  134. this.list = list;
  135. }
  136. public bool next () {
  137. assert (_stamp == _list._stamp);
  138. if (_index < _list._size) {
  139. _index++;
  140. }
  141. return (_index < _list._size);
  142. }
  143. public weak G? get () {
  144. assert (_stamp == _list._stamp);
  145. if (_index < 0 || _index >= _list._size) {
  146. return null;
  147. }
  148. return _list.get (_index);
  149. }
  150. }
  151. }