3 * Copyright (C) 2007-2009 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * 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
20 * Jürg Billeter <j@bitron.ch>
24 * A generic collection of objects.
27 public interface Gee.Collection<G> : Iterable<G> {
29 * The number of items in this collection.
31 public abstract int size { get; }
34 * Specifies whether this collection is empty.
36 public virtual bool is_empty { get { return size == 0; } }
39 * Specifies whether this collection can change - i.e. wheather {@link add},
40 * {@link remove} etc. are legal operations.
42 public abstract bool read_only { get; }
45 * Determines whether this collection contains the specified item.
47 * @param item the item to locate in the collection
49 * @return ``true`` if item is found, ``false`` otherwise
51 public abstract bool contains (G item);
54 * Adds an item to this collection. Must not be called on read-only
57 * @param item the item to add to the collection
59 * @return ``true`` if the collection has been changed, ``false`` otherwise
61 public abstract bool add (G item);
64 * Removes the first occurence of an item from this collection. Must not
65 * be called on read-only collections.
67 * @param item the item to remove from the collection
69 * @return ``true`` if the collection has been changed, ``false`` otherwise
71 public abstract bool remove (G item);
74 * Removes all items from this collection. Must not be called on
75 * read-only collections.
77 public abstract void clear ();
80 * Adds all items in the input collection to this collection.
82 * @param collection the collection which items will be added to this
85 * @return ``true`` if the collection has been changed, ``false`` otherwise
87 public virtual bool add_all (Collection<G> collection) {
88 return collection.fold<bool> ((item, changed) => changed | add (item), false);
92 * Returns ``true`` it this collection contains all items as the input
95 * @param collection the collection which items will be compared with
98 * @return ``true`` if the collection has been changed, ``false`` otherwise
100 public virtual bool contains_all (Collection<G> collection) {
101 return collection.foreach ((item) => contains (item));
105 * Removes the subset of items in this collection corresponding to the
106 * elments in the input collection. If there is several occurrences of
107 * the same value in this collection they are decremented of the number
108 * of occurrences in the input collection.
110 * @param collection the collection which items will be compared with
113 * @return ``true`` if the collection has been changed, ``false`` otherwise
115 public virtual bool remove_all (Collection<G> collection) {
116 return collection.fold<bool> ((item, changed) => changed | remove (item), false);
120 * Removes all items in this collection that are not contained in the input
121 * collection. In other words all common items of both collections are
122 * retained in this collection.
124 * @param collection the collection which items will be compared with
127 * @return ``true`` if the collection has been changed, ``false`` otherwise
129 public virtual bool retain_all (Collection<G> collection) {
130 bool changed = false;
131 for (Iterator<G> iter = iterator(); iter.next ();) {
132 G item = iter.get ();
133 if (!collection.contains (item)) {
142 * Returns an array containing all of items from this collection.
144 * @return an array containing all of items from this collection
146 public virtual G[] to_array () {
148 if (t == typeof (bool)) {
149 return (G[]) to_bool_array ((Collection<bool>) this);
150 } else if (t == typeof (char)) {
151 return (G[]) to_char_array ((Collection<char>) this);
152 } else if (t == typeof (uchar)) {
153 return (G[]) to_uchar_array ((Collection<uchar>) this);
154 } else if (t == typeof (int)) {
155 return (G[]) to_int_array ((Collection<int>) this);
156 } else if (t == typeof (uint)) {
157 return (G[]) to_uint_array ((Collection<uint>) this);
158 } else if (t == typeof (int64)) {
159 return (G[]) to_int64_array ((Collection<int64>) this);
160 } else if (t == typeof (uint64)) {
161 return (G[]) to_uint64_array ((Collection<uint64>) this);
162 } else if (t == typeof (long)) {
163 return (G[]) to_long_array ((Collection<long>) this);
164 } else if (t == typeof (ulong)) {
165 return (G[]) to_ulong_array ((Collection<ulong>) this);
166 } else if (t == typeof (float)) {
167 return (G[]) to_float_array ((Collection<float>) this);
168 } else if (t == typeof (double)) {
169 return (G[]) to_double_array ((Collection<double>) this);
171 G[] array = new G[size];
173 foreach (G element in this) {
174 array[index++] = (owned)element;
181 * Adds all items in the input array to this collection.
183 * @param array the array which items will be added to this
186 * @return ``true`` if the collection has been changed, ``false`` otherwise
188 public bool add_all_array (G[] array) {
189 // FIXME: Change to virtual after bug #693455 is fixed
191 if (t == typeof (bool)) {
192 return add_all_bool_array ((Collection<bool>) this, (bool [])array);
193 } else if (t == typeof (char)) {
194 return add_all_char_array ((Collection<char>) this, (char [])array);
195 } else if (t == typeof (uchar)) {
196 return add_all_uchar_array ((Collection<uchar>) this, (uchar [])array);
197 } else if (t == typeof (int)) {
198 return add_all_int_array ((Collection<int>) this, (int [])array);
199 } else if (t == typeof (uint)) {
200 return add_all_uint_array ((Collection<uint>) this, (uint [])array);
201 } else if (t == typeof (int64)) {
202 return add_all_int64_array ((Collection<int64?>) this, (int64? [])array);
203 } else if (t == typeof (uint64)) {
204 return add_all_uint64_array ((Collection<uint64?>) this, (uint64? [])array);
205 } else if (t == typeof (long)) {
206 return add_all_long_array ((Collection<long>) this, (long [])array);
207 } else if (t == typeof (ulong)) {
208 return add_all_ulong_array ((Collection<ulong>) this, (ulong [])array);
209 } else if (t == typeof (float)) {
210 return add_all_float_array ((Collection<float>) this, (float? [])array);
211 } else if (t == typeof (double)) {
212 return add_all_double_array ((Collection<double>) this, (double? [])array);
214 bool changed = false;
215 foreach (unowned G item in array) {
216 changed |= add (item);
223 * Returns ``true`` it this collection contains all items as the input
226 * @param array the array which items will be compared with
229 * @return ``true`` if the collection has been changed, ``false`` otherwise
231 public bool contains_all_array (G[] array) {
232 // FIXME: Change to virtual after bug #693455 is fixed
234 if (t == typeof (bool)) {
235 return contains_all_bool_array ((Collection<bool>) this, (bool [])array);
236 } else if (t == typeof (char)) {
237 return contains_all_char_array ((Collection<char>) this, (char [])array);
238 } else if (t == typeof (uchar)) {
239 return contains_all_uchar_array ((Collection<uchar>) this, (uchar [])array);
240 } else if (t == typeof (int)) {
241 return contains_all_int_array ((Collection<int>) this, (int [])array);
242 } else if (t == typeof (uint)) {
243 return contains_all_uint_array ((Collection<uint>) this, (uint [])array);
244 } else if (t == typeof (int64)) {
245 return contains_all_int64_array ((Collection<int64?>) this, (int64? [])array);
246 } else if (t == typeof (uint64)) {
247 return contains_all_uint64_array ((Collection<uint64?>) this, (uint64? [])array);
248 } else if (t == typeof (long)) {
249 return contains_all_long_array ((Collection<long>) this, (long [])array);
250 } else if (t == typeof (ulong)) {
251 return contains_all_ulong_array ((Collection<ulong>) this, (ulong [])array);
252 } else if (t == typeof (float)) {
253 return contains_all_float_array ((Collection<float>) this, (float? [])array);
254 } else if (t == typeof (double)) {
255 return contains_all_double_array ((Collection<double>) this, (double? [])array);
257 foreach (unowned G item in array) {
258 if (!contains (item)) {
267 * Removes the subset of items in this collection corresponding to the
268 * elments in the input array. If there is several occurrences of
269 * the same value in this collection they are decremented of the number
270 * of occurrences in the input array.
272 * @param array the array which items will be compared with
275 * @return ``true`` if the collection has been changed, ``false`` otherwise
277 public bool remove_all_array (G[] array) {
278 // FIXME: Change to virtual after bug #693455 is fixed
280 if (t == typeof (bool)) {
281 return remove_all_bool_array ((Collection<bool>) this, (bool [])array);
282 } else if (t == typeof (char)) {
283 return remove_all_char_array ((Collection<char>) this, (char [])array);
284 } else if (t == typeof (uchar)) {
285 return remove_all_uchar_array ((Collection<uchar>) this, (uchar [])array);
286 } else if (t == typeof (int)) {
287 return remove_all_int_array ((Collection<int>) this, (int [])array);
288 } else if (t == typeof (uint)) {
289 return remove_all_uint_array ((Collection<uint>) this, (uint [])array);
290 } else if (t == typeof (int64)) {
291 return remove_all_int64_array ((Collection<int64?>) this, (int64? [])array);
292 } else if (t == typeof (uint64)) {
293 return remove_all_uint64_array ((Collection<uint64?>) this, (uint64? [])array);
294 } else if (t == typeof (long)) {
295 return remove_all_long_array ((Collection<long>) this, (long [])array);
296 } else if (t == typeof (ulong)) {
297 return remove_all_ulong_array ((Collection<ulong>) this, (ulong [])array);
298 } else if (t == typeof (float)) {
299 return remove_all_float_array ((Collection<float>) this, (float? [])array);
300 } else if (t == typeof (double)) {
301 return remove_all_double_array ((Collection<double>) this, (double? [])array);
303 bool changed = false;
304 foreach (unowned G item in array) {
305 changed |= remove (item);
312 * The read-only view of this collection.
314 public abstract Collection<G> read_only_view { owned get; }
317 * Returns an immutable empty collection.
319 * @return an immutable empty collection
321 public static Collection<G> empty<G> () {
322 return new HashSet<G> ().read_only_view;
325 private static bool[] to_bool_array (Collection<bool> coll) {
326 bool[] array = new bool[coll.size];
328 foreach (bool element in coll) {
329 array[index++] = element;
334 private static char[] to_char_array (Collection<char> coll) {
335 char[] array = new char[coll.size];
337 foreach (char element in coll) {
338 array[index++] = element;
343 private static uchar[] to_uchar_array (Collection<uchar> coll) {
344 uchar[] array = new uchar[coll.size];
346 foreach (uchar element in coll) {
347 array[index++] = element;
352 private static int[] to_int_array (Collection<int> coll) {
353 int[] array = new int[coll.size];
355 foreach (int element in coll) {
356 array[index++] = element;
361 private static uint[] to_uint_array (Collection<uint> coll) {
362 uint[] array = new uint[coll.size];
364 foreach (uint element in coll) {
365 array[index++] = element;
370 private static int64?[] to_int64_array (Collection<int64?> coll) {
371 int64?[] array = new int64?[coll.size];
373 foreach (int64? element in coll) {
374 array[index++] = (owned)element;
379 private static uint64?[] to_uint64_array (Collection<uint64?> coll) {
380 uint64?[] array = new uint64?[coll.size];
382 foreach (uint64? element in coll) {
383 array[index++] = (owned)element;
388 private static long[] to_long_array (Collection<long> coll) {
389 long[] array = new long[coll.size];
391 foreach (long element in coll) {
392 array[index++] = element;
397 private static ulong[] to_ulong_array (Collection<ulong> coll) {
398 ulong[] array = new ulong[coll.size];
400 foreach (ulong element in coll) {
401 array[index++] = element;
406 private static float?[] to_float_array (Collection<float?> coll) {
407 float?[] array = new float?[coll.size];
409 foreach (float? element in coll) {
410 array[index++] = (owned)element;
415 private static double?[] to_double_array (Collection<double?> coll) {
416 double?[] array = new double?[coll.size];
418 foreach (double? element in coll) {
419 array[index++] = (owned)element;
424 private static bool add_all_bool_array (Collection<bool> coll, bool[] arr) {
425 bool changed = false;
426 foreach (bool el in arr) {
427 changed |= coll.add (el);
432 private static bool add_all_char_array (Collection<char> coll, char[] arr) {
433 bool changed = false;
434 foreach (char el in arr) {
435 changed |= coll.add (el);
440 private static bool add_all_uchar_array (Collection<uchar> coll, uchar[] arr) {
441 bool changed = false;
442 foreach (uchar el in arr) {
443 changed |= coll.add (el);
448 private static bool add_all_int_array (Collection<int> coll, int[] arr) {
449 bool changed = false;
450 foreach (int el in arr) {
451 changed |= coll.add (el);
456 private static bool add_all_uint_array (Collection<uint> coll, uint[] arr) {
457 bool changed = false;
458 foreach (uint el in arr) {
459 changed |= coll.add (el);
464 private static bool add_all_int64_array (Collection<int64?> coll, int64?[] arr) {
465 bool changed = false;
466 foreach (unowned int64? el in arr) {
467 changed |= coll.add (el);
472 private static bool add_all_uint64_array (Collection<uint64?> coll, uint64?[] arr) {
473 bool changed = false;
474 foreach (unowned uint64? el in arr) {
475 changed |= coll.add (el);
480 private static bool add_all_long_array (Collection<long> coll, long[] arr) {
481 bool changed = false;
482 foreach (long el in arr) {
483 changed |= coll.add (el);
488 private static bool add_all_ulong_array (Collection<ulong> coll, ulong[] arr) {
489 bool changed = false;
490 foreach (ulong el in arr) {
491 changed |= coll.add (el);
496 private static bool add_all_float_array (Collection<float?> coll, float?[] arr) {
497 bool changed = false;
498 foreach (unowned float? el in arr) {
499 changed |= coll.add (el);
504 private static bool add_all_double_array (Collection<double?> coll, double?[] arr) {
505 bool changed = false;
506 foreach (unowned double? el in arr) {
507 changed |= coll.add (el);
512 private static bool contains_all_bool_array (Collection<bool> coll, bool[] arr) {
513 foreach (bool el in arr) {
514 if (!coll.contains (el)) {
521 private static bool contains_all_char_array (Collection<char> coll, char[] arr) {
522 foreach (char el in arr) {
523 if (!coll.contains (el)) {
530 private static bool contains_all_uchar_array (Collection<uchar> coll, uchar[] arr) {
531 foreach (uchar el in arr) {
532 if (!coll.contains (el)) {
539 private static bool contains_all_int_array (Collection<int> coll, int[] arr) {
540 foreach (int el in arr) {
541 if (!coll.contains (el)) {
548 private static bool contains_all_uint_array (Collection<uint> coll, uint[] arr) {
549 foreach (uint el in arr) {
550 if (!coll.contains (el)) {
557 private static bool contains_all_int64_array (Collection<int64?> coll, int64?[] arr) {
558 foreach (unowned int64? el in arr) {
559 if (!coll.contains (el)) {
566 private static bool contains_all_uint64_array (Collection<uint64?> coll, uint64?[] arr) {
567 foreach (unowned uint64? el in arr) {
568 if (!coll.contains (el)) {
575 private static bool contains_all_long_array (Collection<long> coll, long[] arr) {
576 foreach (long el in arr) {
577 if (!coll.contains (el)) {
584 private static bool contains_all_ulong_array (Collection<ulong> coll, ulong[] arr) {
585 foreach (ulong el in arr) {
586 if (!coll.contains (el)) {
593 private static bool contains_all_float_array (Collection<float?> coll, float?[] arr) {
594 foreach (unowned float? el in arr) {
595 if (!coll.contains (el)) {
602 private static bool contains_all_double_array (Collection<double?> coll, double?[] arr) {
603 foreach (unowned double? el in arr) {
604 if (!coll.contains (el)) {
611 private static bool remove_all_bool_array (Collection<bool> coll, bool[] arr) {
612 bool changed = false;
613 foreach (bool el in arr) {
614 changed |= coll.remove (el);
619 private static bool remove_all_char_array (Collection<char> coll, char[] arr) {
620 bool changed = false;
621 foreach (char el in arr) {
622 changed |= coll.remove (el);
627 private static bool remove_all_uchar_array (Collection<uchar> coll, uchar[] arr) {
628 bool changed = false;
629 foreach (uchar el in arr) {
630 changed |= coll.remove (el);
635 private static bool remove_all_int_array (Collection<int> coll, int[] arr) {
636 bool changed = false;
637 foreach (int el in arr) {
638 changed |= coll.remove (el);
643 private static bool remove_all_uint_array (Collection<uint> coll, uint[] arr) {
644 bool changed = false;
645 foreach (uint el in arr) {
646 changed |= coll.remove (el);
651 private static bool remove_all_int64_array (Collection<int64?> coll, int64?[] arr) {
652 bool changed = false;
653 foreach (unowned int64? el in arr) {
654 changed |= coll.remove (el);
659 private static bool remove_all_uint64_array (Collection<uint64?> coll, uint64?[] arr) {
660 bool changed = false;
661 foreach (unowned uint64? el in arr) {
662 changed |= coll.remove (el);
667 private static bool remove_all_long_array (Collection<long> coll, long[] arr) {
668 bool changed = false;
669 foreach (long el in arr) {
670 changed |= coll.remove (el);
675 private static bool remove_all_ulong_array (Collection<ulong> coll, ulong[] arr) {
676 bool changed = false;
677 foreach (ulong el in arr) {
678 changed |= coll.remove (el);
683 private static bool remove_all_float_array (Collection<float?> coll, float?[] arr) {
684 bool changed = false;
685 foreach (unowned float? el in arr) {
686 changed |= coll.remove (el);
691 private static bool remove_all_double_array (Collection<double?> coll, double?[] arr) {
692 bool changed = false;
693 foreach (unowned double? el in arr) {
694 changed |= coll.remove (el);