650b26d98a6f871f24a93794a79c4700cd454dbe
[platform/upstream/libgee.git] / gee / unfolditerator.vala
1 /* unfolditerator.vala
2  *
3  * Copyright (C) 2011  Maciej Piechotka
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  *      Maciej Piechotka <uzytkownik2@gmail.com>
21  */
22
23 internal class Gee.UnfoldIterator<G> : Object, Traversable<G>, Iterator<G> {
24         public UnfoldIterator (owned UnfoldFunc<G> func, owned Lazy<G>? current = null) {
25                 _current = (owned)current;
26                 _func = (owned)func;
27                 _end = false;
28         }
29
30         public bool next () {
31                 if (has_next ()) {
32                         if (_current != null)
33                                 _current.eval ();
34                         _current = (owned)_next;
35                         return true;
36                 }
37                 return false;
38         }
39
40         public bool has_next () {
41                 if (_end)
42                         return false;
43                 if (_next != null)
44                         return true;
45                 _next = _func ();
46                 if (_next == null)
47                         _end = true;
48                 return _next != null;
49         }
50
51         public new G get () {
52                 assert (_current != null);
53                 return _current.value;
54         }
55
56         public void remove () {
57                 assert_not_reached ();
58         }
59
60         public bool valid { get { return _current != null; } }
61         public bool read_only { get { return true; } }
62
63         public void foreach (ForallFunc<G> f) {
64                 if (_current != null) {
65                         f (_current);
66                 }
67                 if (_next != null) {
68                         _current = (owned)_next;
69                         f (_current);
70                 } else if (_end) {
71                         return;
72                 }
73                 if (_current == null) {
74                         _current = _func ();
75                         if (_current == null) {
76                                 _end = true;
77                                 return;
78                         } else {
79                                 f (_current);
80                         }
81                 }
82                 while ((_next = _func ()) != null) {
83                         _current = (owned)_next;
84                         f (_current);
85                 }
86                 _end = true;
87         }
88
89         private UnfoldFunc<G> _func;
90         private Lazy<G>? _current;
91         private Lazy<G>? _next;
92         private bool _end;
93 }