Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
branch_iter_ind.hh
1 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_UTIL_BRANCH_ITER_IND_HH
27 # define MLN_UTIL_BRANCH_ITER_IND_HH
28 
36 # include <stack>
37 # include <mln/util/tree.hh>
38 
39 namespace mln
40 {
41 
42  namespace util
43  {
44  template<typename T>
45  struct bi_elt
46  {
47  typedef std::vector< util::tree_node<T>* > child_list;
48 
49  bi_elt(child_list* list)
50  : list_(list),
51  previous_(0),
52  pos_(-1) {}
53 
54  child_list* list_;
55  util::tree_node<T>* previous_;
56  int pos_;
57  };
58 
65  template <typename T>
67  {
68  public:
70 
72  operator util::tree_node<T>&() const;
73  util::tree_node<T>& operator *();
74 
76  bool is_valid() const;
77 
79  void invalidate();
80 
82  void start();
83 
85  void next();
86 
88  unsigned deepness() const;
89 
90  private:
92  util::branch<T> branch_;
93 
95  std::stack< bi_elt<T> > s_;
96 
98  };
99 
100 # ifndef MLN_INCLUDE_ONLY
101 
102 
103  template <typename T>
104  inline
106  : branch_(branch)
107  {
108  invalidate();
109  }
110 
111  template <typename T>
112  inline
114  {
115  mln_assertion(n_);
116  return *n_;
117  }
118 
119  template <typename T>
120  inline
123  {
124  mln_assertion(n_);
125  return *n_;
126  }
127 
128  template <typename T>
129  inline
130  unsigned
132  {
133  mln_assertion(is_valid());
134  unsigned i = 0;
135  tree_node<T>* p = n_;
136  while (p)
137  {
138  p = p->parent();
139  i++;
140  }
141  return i;
142  }
143 
144  template <typename T>
145  inline
146  bool
148  {
149  return n_ != 0;
150  }
151 
152  template <typename T>
153  inline
154  void
156  {
157  n_ = 0;
158  }
159 
160 
161  template <typename T>
162  inline
163  void
165  {
166  s_.push(bi_elt<T>(&branch_.apex().children()));
167 
168  n_ = &branch_.apex();
169  }
170 
171  template <typename T>
172  inline
173  void
175  {
176  // First : list of children.
177  // Second : i;
178 
179  if (s_.size() == 0)
180  invalidate();
181  else
182  {
183  s_.top().pos_++;
184  if (s_.top().list_->size() == (unsigned)s_.top().pos_)
185  {
186  s_.pop();
187  next();
188  return;
189  }
190  else
191  {
192  mln_assertion(s_.top().list_->size() > (unsigned)s_.top().pos_);
193  if (s_.top().previous_ != 0)
194  mln_assertion(s_.top().previous_ == (*(s_.top().list_))[s_.top().pos_ - 1]);
195 
196  n_ = (*(s_.top().list_))[s_.top().pos_];
197  s_.top().previous_ = n_;
198 
199  if (!n_)
200  {
201  next();
202  return;
203  }
204 
205  mln_assertion(n_);
206  if (n_->children().size() > 0)
207  {
208  s_.push(bi_elt<T>(&n_->children()));
209  }
210  return;
211  }
212  }
213  }
214 
215 # endif // ! MLN_INCLUDE_ONLY
216 
217 
218  }
219 
220 } // end of namespace mln
221 
222 
223 #endif // ! MLN_UTIL_BRANCH_ITER_IND_HH