summaryrefslogtreecommitdiff
path: root/gee/collection.vala
diff options
context:
space:
mode:
Diffstat (limited to 'gee/collection.vala')
-rw-r--r--gee/collection.vala222
1 files changed, 216 insertions, 6 deletions
diff --git a/gee/collection.vala b/gee/collection.vala
index 3bc12a8..a6dfb4f 100644
--- a/gee/collection.vala
+++ b/gee/collection.vala
@@ -23,6 +23,7 @@
/**
* A generic collection of objects.
*/
+[GenericAccessors]
public interface Gee.Collection<G> : Iterable<G> {
/**
* The number of items in this collection.
@@ -32,7 +33,13 @@ public interface Gee.Collection<G> : Iterable<G> {
/**
* Specifies whether this collection is empty.
*/
- public abstract bool is_empty { get; }
+ public virtual bool is_empty { get { return size == 0; } }
+
+ /**
+ * Specifies whether this collection can change - i.e. wheather {@link add},
+ * {@link remove} etc. are legal operations.
+ */
+ public abstract bool read_only { get; }
/**
* Determines whether this collection contains the specified item.
@@ -77,7 +84,9 @@ public interface Gee.Collection<G> : Iterable<G> {
*
* @return ``true`` if the collection has been changed, ``false`` otherwise
*/
- public abstract bool add_all (Collection<G> collection);
+ public virtual bool add_all (Collection<G> collection) {
+ return collection.fold<bool> ((item, changed) => changed | add (item), false);
+ }
/**
* Returns ``true`` it this collection contains all items as the input
@@ -88,7 +97,9 @@ public interface Gee.Collection<G> : Iterable<G> {
*
* @return ``true`` if the collection has been changed, ``false`` otherwise
*/
- public abstract bool contains_all (Collection<G> collection);
+ public virtual bool contains_all (Collection<G> collection) {
+ return collection.foreach ((item) => contains (item));
+ }
/**
* Removes the subset of items in this collection corresponding to the
@@ -101,7 +112,9 @@ public interface Gee.Collection<G> : Iterable<G> {
*
* @return ``true`` if the collection has been changed, ``false`` otherwise
*/
- public abstract bool remove_all (Collection<G> collection);
+ public virtual bool remove_all (Collection<G> collection) {
+ return collection.fold<bool> ((item, changed) => changed | remove (item), false);
+ }
/**
* Removes all items in this collection that are not contained in the input
@@ -113,14 +126,211 @@ public interface Gee.Collection<G> : Iterable<G> {
*
* @return ``true`` if the collection has been changed, ``false`` otherwise
*/
- public abstract bool retain_all (Collection<G> collection);
+ public virtual bool retain_all (Collection<G> collection) {
+ bool changed = false;
+ for (Iterator<G> iter = iterator(); iter.next ();) {
+ G item = iter.get ();
+ if (!collection.contains (item)) {
+ iter.remove ();
+ changed = true;
+ }
+ }
+ return changed;
+ }
/**
* Returns an array containing all of items from this collection.
*
* @return an array containing all of items from this collection
*/
- public abstract G[] to_array();
+ public virtual G[] to_array () {
+ var t = typeof (G);
+ if (t == typeof (bool)) {
+ return (G[]) to_bool_array ((Collection<bool>) this);
+ } else if (t == typeof (char)) {
+ return (G[]) to_char_array ((Collection<char>) this);
+ } else if (t == typeof (uchar)) {
+ return (G[]) to_uchar_array ((Collection<uchar>) this);
+ } else if (t == typeof (int)) {
+ return (G[]) to_int_array ((Collection<int>) this);
+ } else if (t == typeof (uint)) {
+ return (G[]) to_uint_array ((Collection<uint>) this);
+ } else if (t == typeof (int64)) {
+ return (G[]) to_int64_array ((Collection<int64>) this);
+ } else if (t == typeof (uint64)) {
+ return (G[]) to_uint64_array ((Collection<uint64>) this);
+ } else if (t == typeof (long)) {
+ return (G[]) to_long_array ((Collection<long>) this);
+ } else if (t == typeof (ulong)) {
+ return (G[]) to_ulong_array ((Collection<ulong>) this);
+ } else if (t == typeof (float)) {
+ return (G[]) to_float_array ((Collection<float>) this);
+ } else if (t == typeof (double)) {
+ return (G[]) to_double_array ((Collection<double>) this);
+ } else {
+ G[] array = new G[size];
+ int index = 0;
+ foreach (G element in this) {
+ array[index++] = element;
+ }
+ return array;
+ }
+ }
+
+ /**
+ * Adds all items in the input array to this collection.
+ *
+ * @param array the array which items will be added to this
+ * collection.
+ *
+ * @return ``true`` if the collection has been changed, ``false`` otherwise
+ */
+ public bool add_all_array (G[] array) {
+ // FIXME: Change to virtual after bug #693455 is fixed
+ bool changed = false;
+ foreach (unowned G item in array) {
+ changed |= add (item);
+ }
+ return changed;
+ }
+
+ /**
+ * Returns ``true`` it this collection contains all items as the input
+ * array.
+ *
+ * @param array the array which items will be compared with
+ * this collection.
+ *
+ * @return ``true`` if the collection has been changed, ``false`` otherwise
+ */
+ public bool contains_all_array (G[] array) {
+ // FIXME: Change to virtual after bug #693455 is fixed
+ foreach (unowned G item in array) {
+ if (!contains (item)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Removes the subset of items in this collection corresponding to the
+ * elments in the input array. If there is several occurrences of
+ * the same value in this collection they are decremented of the number
+ * of occurrences in the input array.
+ *
+ * @param array the array which items will be compared with
+ * this collection.
+ *
+ * @return ``true`` if the collection has been changed, ``false`` otherwise
+ */
+ public bool remove_all_array (G[] array) {
+ // FIXME: Change to virtual after bug #693455 is fixed
+ bool changed = false;
+ foreach (unowned G item in array) {
+ changed |= remove (item);
+ }
+ return changed;
+ }
+
+ private static bool[] to_bool_array (Collection<bool> coll) {
+ bool[] array = new bool[coll.size];
+ int index = 0;
+ foreach (bool element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static char[] to_char_array (Collection<char> coll) {
+ char[] array = new char[coll.size];
+ int index = 0;
+ foreach (char element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static uchar[] to_uchar_array (Collection<uchar> coll) {
+ uchar[] array = new uchar[coll.size];
+ int index = 0;
+ foreach (uchar element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static int[] to_int_array (Collection<int> coll) {
+ int[] array = new int[coll.size];
+ int index = 0;
+ foreach (int element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static uint[] to_uint_array (Collection<uint> coll) {
+ uint[] array = new uint[coll.size];
+ int index = 0;
+ foreach (uint element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static int64[] to_int64_array (Collection<int64?> coll) {
+ int64[] array = new int64[coll.size];
+ int index = 0;
+ foreach (int64 element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static uint64[] to_uint64_array (Collection<uint64?> coll) {
+ uint64[] array = new uint64[coll.size];
+ int index = 0;
+ foreach (uint64 element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static long[] to_long_array (Collection<long> coll) {
+ long[] array = new long[coll.size];
+ int index = 0;
+ foreach (long element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static ulong[] to_ulong_array (Collection<ulong> coll) {
+ ulong[] array = new ulong[coll.size];
+ int index = 0;
+ foreach (ulong element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static float?[] to_float_array (Collection<float?> coll) {
+ float?[] array = new float?[coll.size];
+ int index = 0;
+ foreach (float element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
+
+ private static double?[] to_double_array (Collection<double?> coll) {
+ double?[] array = new double?[coll.size];
+ int index = 0;
+ foreach (double element in coll) {
+ array[index++] = element;
+ }
+ return array;
+ }
/**
* The read-only view of this collection.