diff options
Diffstat (limited to 'gee/collection.vala')
-rw-r--r-- | gee/collection.vala | 222 |
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. |