Update Changelog
[profile/ivi/libgee.git] / gee / collection.vala
1 /* collection.vala
2  *
3  * Copyright (C) 2007-2009  Jürg Billeter
4  *
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.
9
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.
14
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
23 /**
24  * A generic collection of objects.
25  */
26 [GenericAccessors]
27 public interface Gee.Collection<G> : Iterable<G> {
28         /**
29          * The number of items in this collection.
30          */
31         public abstract int size { get; }
32
33         /**
34          * Specifies whether this collection is empty.
35          */
36         public virtual bool is_empty { get { return size == 0; } }
37         
38         /**
39          * Specifies whether this collection can change - i.e. wheather {@link add},
40          * {@link remove} etc. are legal operations.
41          */
42         public abstract bool read_only { get; }
43
44         /**
45          * Determines whether this collection contains the specified item.
46          *
47          * @param item the item to locate in the collection
48          *
49          * @return     ``true`` if item is found, ``false`` otherwise
50          */
51         public abstract bool contains (G item);
52
53         /**
54          * Adds an item to this collection. Must not be called on read-only
55          * collections.
56          *
57          * @param item the item to add to the collection
58          *
59          * @return     ``true`` if the collection has been changed, ``false`` otherwise
60          */
61         public abstract bool add (G item);
62
63         /**
64          * Removes the first occurence of an item from this collection. Must not
65          * be called on read-only collections.
66          *
67          * @param item the item to remove from the collection
68          *
69          * @return     ``true`` if the collection has been changed, ``false`` otherwise
70          */
71         public abstract bool remove (G item);
72
73         /**
74          * Removes all items from this collection. Must not be called on
75          * read-only collections.
76          */
77         public abstract void clear ();
78
79         /**
80          * Adds all items in the input collection to this collection.
81          *
82          * @param collection the collection which items will be added to this
83          *                   collection.
84          *
85          * @return     ``true`` if the collection has been changed, ``false`` otherwise
86          */
87         public virtual bool add_all (Collection<G> collection) {
88                 return collection.fold<bool> ((item, changed) => changed | add (item), false);
89         }
90
91         /**
92          * Returns ``true`` it this collection contains all items as the input
93          * collection.
94          *
95          * @param collection the collection which items will be compared with
96          *                   this collection.
97          *
98          * @return     ``true`` if the collection has been changed, ``false`` otherwise
99          */
100         public virtual bool contains_all (Collection<G> collection) {
101                 return collection.foreach ((item) => contains (item));
102         }
103
104         /**
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.
109          *
110          * @param collection the collection which items will be compared with
111          *                   this collection.
112          *
113          * @return     ``true`` if the collection has been changed, ``false`` otherwise
114          */
115         public virtual bool remove_all (Collection<G> collection) {
116                 return collection.fold<bool> ((item, changed) => changed | remove (item), false);
117         }
118
119         /**
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.
123          *
124          * @param collection the collection which items will be compared with
125          *                   this collection.
126          *
127          * @return     ``true`` if the collection has been changed, ``false`` otherwise
128          */
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)) {
134                                 iter.remove ();
135                                 changed = true;
136                         }
137                 }
138                 return changed;
139         }
140
141         /**
142          * Returns an array containing all of items from this collection.
143          *
144          * @return an array containing all of items from this collection
145          */
146         public virtual G[] to_array () {
147                 var t = typeof (G);
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);
170                 } else {
171                         G[] array = new G[size];
172                         int index = 0;
173                         foreach (G element in this) {
174                                 array[index++] = element;
175                         }
176                         return array;
177                 }
178         }
179
180         /**
181          * Adds all items in the input array to this collection.
182          *
183          * @param array the array which items will be added to this
184          *              collection.
185          *
186          * @return     ``true`` if the collection has been changed, ``false`` otherwise
187          */
188         public bool add_all_array (G[] array) {
189                 // FIXME: Change to virtual after bug #693455 is fixed
190                 bool changed = false;
191                 foreach (unowned G item in array) {
192                         changed |= add (item);
193                 }
194                 return changed;
195         }
196
197         /**
198          * Returns ``true`` it this collection contains all items as the input
199          * array.
200          *
201          * @param array the array which items will be compared with
202          *              this collection.
203          *
204          * @return     ``true`` if the collection has been changed, ``false`` otherwise
205          */
206         public bool contains_all_array (G[] array) {
207                 // FIXME: Change to virtual after bug #693455 is fixed
208                 foreach (unowned G item in array) {
209                         if (!contains (item)) {
210                                 return false;
211                         }
212                 }
213                 return true;
214         }
215
216         /**
217          * Removes the subset of items in this collection corresponding to the
218          * elments in the input array. If there is several occurrences of
219          * the same value in this collection they are decremented of the number
220          * of occurrences in the input array.
221          *
222          * @param array the array which items will be compared with
223          *              this collection.
224          *
225          * @return     ``true`` if the collection has been changed, ``false`` otherwise
226          */
227         public bool remove_all_array (G[] array) {
228                 // FIXME: Change to virtual after bug #693455 is fixed
229                 bool changed = false;
230                 foreach (unowned G item in array) {
231                         changed |= remove (item);
232                 }
233                 return changed;
234         }
235
236         private static bool[] to_bool_array (Collection<bool> coll) {
237                 bool[] array = new bool[coll.size];
238                 int index = 0;
239                 foreach (bool element in coll) {
240                         array[index++] = element;
241                 }
242                 return array;
243         }
244
245         private static char[] to_char_array (Collection<char> coll) {
246                 char[] array = new char[coll.size];
247                 int index = 0;
248                 foreach (char element in coll) {
249                         array[index++] = element;
250                 }
251                 return array;
252         }
253
254         private static uchar[] to_uchar_array (Collection<uchar> coll) {
255                 uchar[] array = new uchar[coll.size];
256                 int index = 0;
257                 foreach (uchar element in coll) {
258                         array[index++] = element;
259                 }
260                 return array;
261         }
262
263         private static int[] to_int_array (Collection<int> coll) {
264                 int[] array = new int[coll.size];
265                 int index = 0;
266                 foreach (int element in coll) {
267                         array[index++] = element;
268                 }
269                 return array;
270         }
271
272         private static uint[] to_uint_array (Collection<uint> coll) {
273                 uint[] array = new uint[coll.size];
274                 int index = 0;
275                 foreach (uint element in coll) {
276                         array[index++] = element;
277                 }
278                 return array;
279         }
280
281         private static int64[] to_int64_array (Collection<int64?> coll) {
282                 int64[] array = new int64[coll.size];
283                 int index = 0;
284                 foreach (int64 element in coll) {
285                         array[index++] = element;
286                 }
287                 return array;
288         }
289
290         private static uint64[] to_uint64_array (Collection<uint64?> coll) {
291                 uint64[] array = new uint64[coll.size];
292                 int index = 0;
293                 foreach (uint64 element in coll) {
294                         array[index++] = element;
295                 }
296                 return array;
297         }
298
299         private static long[] to_long_array (Collection<long> coll) {
300                 long[] array = new long[coll.size];
301                 int index = 0;
302                 foreach (long element in coll) {
303                         array[index++] = element;
304                 }
305                 return array;
306         }
307
308         private static ulong[] to_ulong_array (Collection<ulong> coll) {
309                 ulong[] array = new ulong[coll.size];
310                 int index = 0;
311                 foreach (ulong element in coll) {
312                         array[index++] = element;
313                 }
314                 return array;
315         }
316
317         private static float?[] to_float_array (Collection<float?> coll) {
318                 float?[] array = new float?[coll.size];
319                 int index = 0;
320                 foreach (float element in coll) {
321                         array[index++] = element;
322                 }
323                 return array;
324         }
325
326         private static double?[] to_double_array (Collection<double?> coll) {
327                 double?[] array = new double?[coll.size];
328                 int index = 0;
329                 foreach (double element in coll) {
330                         array[index++] = element;
331                 }
332                 return array;
333         }
334
335         /**
336          * The read-only view of this collection.
337          */
338         public abstract Collection<G> read_only_view { owned get; }
339
340         /**
341          * Returns an immutable empty collection.
342          *
343          * @return an immutable empty collection
344          */
345         public static Collection<G> empty<G> () {
346                 return new HashSet<G> ().read_only_view;
347         }
348 }
349