3 * Copyright (C) 2011-2012 Maciej Piechotka
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 * Maciej Piechotka <uzytkownik2@gmail.com>
24 public delegate A FoldFunc<A, G> (owned G g, owned A a);
25 public delegate void ForallFunc<G> (owned G g);
26 public delegate Lazy<A>? UnfoldFunc<A> ();
27 public delegate Traversable.Stream StreamFunc<G, A> (Traversable.Stream state, owned Lazy<G>? g, out Lazy<A>? lazy);
28 public delegate A MapFunc<A, G> (owned G g);
29 public delegate bool Predicate<G> (G g);
33 * It's a common interface for {@link Iterator} and {@link Iterable}. It
34 * provides a fast, high level functions.
36 * ''{@link Iterator} implementation:'' Please note that most of the functions
37 * affect the state of the iterator by moving it forward.
38 * Even if the iterator is {@link BidirIterator} it ''must not''
41 * ''{@link Iterable} implementation:'' validy ({@link Iterator.valid})
42 * of returned iterator is the same as for invalid
43 * iterator. In other words the following code is semantically equivalent:
46 * var x = iterable.function (args);
47 * var x = iterable.iterator ().function(args);
53 public interface Gee.Traversable<G> : Object {
55 * Apply function to each element returned by iterator.
57 * ''{@link Iterator} implementation:'' Operation moves the iterator
58 * to last element in iteration. If iterator points at some element it
59 * will be included in iteration.
61 public new abstract void foreach (ForallFunc<G> f);
64 * Stream function is an abstract function allowing writing many
67 * The stream function accepts three parameter:
69 * 1. state. It is usually the last returned value from function but
70 * it may be {@link Stream.END} when {@link Stream.CONTINUE} was
71 * returned and there was no more elements.
72 * 1. input. It is valid only if first argument is
73 * {@link Stream.CONTINUE}
74 * 1. output. It is valid only if result is Stream.YIELD
76 * It may return one of 3 results:
78 * 1. {@link Stream.YIELD}. It means that value was yielded and can
79 * be passed to outgoing iterator.
80 * 1. {@link Stream.CONTINUE}. It means that the function needs to be
81 * called with next element or with {@link Stream.END} if it is
82 * end of stream). If the state element was Stream.END during the
83 * current iteration function ''must not'' return {@link Stream.CONTINUE}
84 * 1. Stream.END. It means that the last argument was yielded.
86 * If the function yields the value immediately then the returning iterator
87 * is {@link Iterator.valid} and points to this value as well as in case when the
88 * parent iterator is {@link Iterator.valid} and function yields
89 * after consuming 1 input. In other case returned iterator is invalid.
91 * Note: In {@link Iterator} implementation: if iterator is
92 * {@link Iterator.valid} the current value should be fed
93 * immediately to function if during initial call function returns
94 * {@link Stream.CONTINUE}. The parent iterator cannot be used before
95 * the functions return {@link Stream.END} afterwards it points on the
96 * last element consumed.
98 * @param f function generating stream
99 * @return iterator containing values yielded by stream
101 public virtual Iterator<A> stream<A> (owned StreamFunc<G, A> f) {
104 // Yes - I've heard of polimorphism ;) but I don't want users to need to implement the method.
105 if ((self = this as Iterator<G>) != null) {
106 Traversable.Stream str;
107 Lazy<A>? initial = null;
108 bool need_next = true;
109 str = f (Stream.YIELD, null, out initial);
111 case Stream.CONTINUE:
113 str = f (Stream.CONTINUE, new Lazy<G> (() => {return self.get ();}), out initial);
116 case Stream.CONTINUE:
119 return Iterator.unfold<A> (() => {return null;});
121 assert_not_reached ();
130 return Iterator.unfold<A> (() => {return null;});
132 assert_not_reached ();
134 return Iterator.unfold<A> (() => {
136 if (str != Stream.CONTINUE)
137 str = f (Traversable.Stream.YIELD, null, out val);
138 while (str == Stream.CONTINUE) {
141 str = f (Traversable.Stream.END, null, out val);
142 assert (str != Traversable.Stream.CONTINUE);
148 str = f (Stream.CONTINUE, new Lazy<G> (() => {return self.get ();}), out val);
156 assert_not_reached ();
159 } else if ((iself = this as Iterable<G>) != null) {
160 return iself.iterator().stream<A> ((owned) f);
162 assert_not_reached ();
167 * Standard aggregation function.
169 * It takes a function, seed and first element, returns the new seed and
170 * progress to next element when the operation repeats.
172 * Note: Default implementation uses {@link foreach}.
174 * Note: In {@link Iterator} implementation operation moves the
175 * iterator to last element in iteration. If iterator is
176 * {@link Iterator.valid} the current element will be considered
180 public virtual A fold<A> (FoldFunc<A, G> f, owned A seed)
182 this.foreach ((item) => {seed = f ((owned) item, (owned) seed);});
187 * Produces an iterator pointing at elements generated by function passed.
189 * Iterator is lazy evaluated but value is force-evaluated when
190 * iterator moves to next element. ({@link Iterator.next})
192 * Note: Default implementation uses {@link stream}.
194 * Note: In {@link Iterator} implementation if the parent iterator is
195 * {@link Iterator.valid} so is the returned one. Using the parent
196 * iterator is not allowed before the inner iterator {@link Iterator.next}
197 * return false and then it points on its last element.
198 * The resulting iterator is {@link Iterator.valid} if the parent
201 * @param f Mapping function
202 * @return Iterator listing mapped value
204 public virtual Iterator<A> map<A> (MapFunc<A, G> f) {
205 return stream<A>((state, item, out val) => {
209 return Stream.CONTINUE;
210 case Stream.CONTINUE:
211 val = new Lazy<A>(() => {
214 return (f ((owned)tmp));
221 assert_not_reached ();
227 * Creates a new iterator that is initially pointing to seed. Then
228 * subsequent values are obtained after applying the function to previous
229 * value and the subsequent items.
231 * The resulting iterator is always valid and it contains the seed value.
233 * Note: Default implementation uses {@link stream}.
235 * Note: When the method is called on {@link Iterator} using the parent
236 * iterator is not allowed befor the inner iterator
237 * {@link Iterator.next} return false and then it points on its last
238 * element. The resulting iterator is {@link Iterator.valid}.
240 * @param f Folding function
241 * @param seed original seed value
242 * @return Iterator containing values of subsequent values of seed
244 public virtual Iterator<A> scan<A> (FoldFunc<A, G> f, owned A seed) {
245 bool seed_emitted = false;
246 return stream<A>((state, item, out val) => {
251 return Stream.CONTINUE;
253 val = new Lazy<A>.from_value (seed);
257 case Stream.CONTINUE:
258 val = new Lazy<A> (() => {
261 seed = f ((owned) tmp, (owned) seed);
269 assert_not_reached ();
275 * Creates a new iterator that contains only values that fullfills the
278 * Note: When the method is called on {@link Iterator} using the parent
279 * iterator is not allowed befor the inner iterator
280 * {@link Iterator.next} return false and then it points on its last
281 * element. The resulting iterator is {@link Iterator.valid} if parent
282 * iterator is {@link Iterator.valid} and value it is pointing on
283 * fullfills the predicate.
285 * @param f Folding function
286 * @return Iterator containing values of subsequent values of seed
288 public virtual Iterator<G> filter (owned Predicate<G> pred) {
289 return stream<G> ((state, item, out val) => {
293 return Stream.CONTINUE;
294 case Stream.CONTINUE:
301 return Stream.CONTINUE;
307 assert_not_reached ();
313 * Creates a new iterator which contains elements from iterable. The
314 * first argument states the offset i.e. number of elements the iterator
317 * Note: In {@link Iterator} implementation resulting iterator is
318 * {@link Iterator.valid} when parent iterator is
319 * {@link Iterator.valid} and the offset is 0. Using the parent
320 * iterator is not allowed before the inner iterator
321 * {@link Iterator.next} return false and then it points on its last
324 * @param offset the offset to first element the iterator is pointing to
325 * @param length maximum number of elements iterator may return. Negative
326 * value means that the number is unbounded
328 public virtual Iterator<G> chop (int offset, int length = -1) {
329 assert (offset >= 0);
330 return stream<G> ((state, item, out val) => {
335 return Stream.CONTINUE;
336 } else if (length > 0) {
338 return length != 0 ? Stream.CONTINUE : Stream.END;
339 } else if (length == 0) {
342 return Stream.CONTINUE;
344 case Stream.CONTINUE:
351 return Stream.CONTINUE;
357 assert_not_reached ();
364 * The type of the elements in this collection.
366 public virtual Type element_type { get { return typeof (G); } }