Update Changelog
[profile/ivi/libgee.git] / gee / iterator.vala
1 /* iterator.vala
2  *
3  * Copyright (C) 2007-2008  Jürg Billeter
4  * Copyright (C) 2009  Didier Villevalois, Maciej Piechotka
5  * Copyright (C) 2010-2011  Maciej Piechotka
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
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
20  *
21  * Author:
22  *      Jürg Billeter <j@bitron.ch>
23  *      Maciej Piechotka <uzytkownik2@gmail.com>
24  *      Didier 'Ptitjes Villevalois <ptitjes@free.fr>
25  */
26
27 /**
28  * An iterator over a collection.
29  *
30  * Gee's iterators are "on-track" iterators. They always point to an item
31  * except before the first call to {@link next}, or, when an
32  * item has been removed, until the next call to {@link next}.
33  *
34  * Please note that when the iterator is out of track, neither {@link get} nor
35  * {@link remove} are defined and both will fail. After the next call to
36  * {@link next}, they will be defined again.
37  */
38 public interface Gee.Iterator<G> : Object, Traversable<G> {
39         /**
40          * Advances to the next element in the iteration.
41          *
42          * @return ``true`` if the iterator has a next element
43          */
44         public abstract bool next ();
45
46         /**
47          * Checks whether there is a next element in the iteration.
48          *
49          * @return ``true`` if the iterator has a next element
50          */
51         public abstract bool has_next ();
52
53         /**
54          * Returns the current element in the iteration.
55          *
56          * @return the current element in the iteration
57          */
58         public abstract G get ();
59
60         /**
61          * Removes the current element in the iteration. The cursor is set in an
62          * in-between state. Both {@link get} and {@link remove} will fail until
63          * the next move of the cursor (calling {@link next}).
64          */
65         public abstract void remove ();
66         
67         /**
68          * Determines wheather the call to {@link get} is legal. It is false at the
69          * beginning and after {@link remove} call and true otherwise.
70          */
71         public abstract bool valid { get; }
72         
73         /**
74          * Determines wheather the call to {@link remove} is legal assuming the
75          * iterator is valid. The value must not change in runtime hence the user
76          * of iterator may cache it.
77          */
78         public abstract bool read_only { get; }
79
80         /**
81          * Create iterator from unfolding function. The lazy value is
82          * force-evaluated before progressing to next element.
83          *
84          * @param f Unfolding function
85          * @param current If iterator is to be valid it contains the current value of it
86          */
87         public static Iterator<A> unfold<A> (owned UnfoldFunc<A> f, owned Lazy<G>? current = null) {
88                 return new UnfoldIterator<A> ((owned) f, (owned) current);
89         }
90
91         /**
92          * Concatinate iterators.
93          *
94          * @param iters Iterators of iterators
95          * @return Iterator containg values of each iterator
96          */
97         public static Iterator<G> concat<G> (Iterator<Iterator<G>> iters) {
98                 Iterator<G>? current = null;
99                 if (iters.valid)
100                         current = iters.get ();
101                 return unfold<G> (() => {
102                         while (true) {
103                                 if (current == null) {
104                                         if (iters.next ()) {
105                                                 current = iters.get ();
106                                         } else {
107                                                 return null;
108                                         }
109                                 } else if (current.next ()) {
110                                         return new Lazy<G>.from_value (current.get ());
111                                 } else {
112                                         current = null;
113                                 }
114                         }
115                 });
116         }
117 }
118