Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
complex_relative_iterator_base.hh
1 // Copyright (C) 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_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_BASE_HH
27 # define MLN_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_BASE_HH
28 
49 # include <vector>
50 
51 # include <mln/topo/internal/complex_iterator_base.hh>
52 
53 /* FIXME: By moving iterator `i_' into
54  internal::complex_relative_iterator_base, we'll be able to factor
55  more methods (do_next_, update_f); this requires the type of this
56  iterator be passed as an extra parameter to
57  internal::complex_relative_iterator_base. */
58 
59 
60 namespace mln
61 {
62 
63  namespace topo
64  {
65 
66  namespace internal
67  {
68 
69  // Forward declaration.
70  template <typename F, typename E>
71  class complex_iterator_base;
72 
73 
74  /*----------------------------------------------------------.
75  | topo::internal::complex_relative_iterator_base<C, F, E>. |
76  `----------------------------------------------------------*/
77 
83  template <typename C, typename F, typename E>
84  class complex_relative_iterator_base :
85  public complex_iterator_base<F, E>
86  {
87  typedef complex_relative_iterator_base<C, F, E> self_;
88 
89  public:
91  typedef C center_type;
93  typedef F face_type;
94 
97  complex_relative_iterator_base();
98  template <typename Fref>
99  complex_relative_iterator_base(const Fref& f_ref);
101 
105  void center_at(const center_type& c);
106 
108  void start();
110  void next_();
112 
113  protected:
116  const center_type* c_;
117 
118  // The type of the set of vicinity sites (adjacent face handles).
119  typedef std::vector<face_type> adj_faces_t;
121  adj_faces_t adj_faces_;
122  };
123 
124 
125 
126  /*------------------------------------------------------------------.
127  | topo::internal::forward_complex_relative_iterator_base<C, F, E>. |
128  `------------------------------------------------------------------*/
129 
136  template <typename C, typename F, typename E>
137  class forward_complex_relative_iterator_base
138  : public complex_relative_iterator_base<C, F, E>
139  {
140  typedef forward_complex_relative_iterator_base<C, F, E> self_;
141  typedef complex_relative_iterator_base<C, F, E> super_;
142 
143  public:
144  typedef F face_type;
145 
146  public:
149  forward_complex_relative_iterator_base();
150  template <typename Fref>
151  forward_complex_relative_iterator_base(const Fref& f_ref);
153 
154  public:
158  bool is_valid() const;
160  void invalidate();
161 
163  void do_start_();
165  void do_next_();
166 
168  void update_f_();
170 
171  protected:
173  typename super_::adj_faces_t::const_iterator i_;
174  };
175 
176 
177  /*-------------------------------------------------------------------.
178  | topo::internal::backward_complex_relative_iterator_base<C, F, E>. |
179  `-------------------------------------------------------------------*/
180 
187  template <typename C, typename F, typename E>
188  class backward_complex_relative_iterator_base
189  : public complex_relative_iterator_base<C, F, E>
190  {
191  typedef backward_complex_relative_iterator_base<C, F, E> self_;
192  typedef complex_relative_iterator_base<C, F, E> super_;
193 
194  public:
195  typedef F face_type;
196 
197  public:
200  backward_complex_relative_iterator_base();
201  template <typename Fref>
202  backward_complex_relative_iterator_base(const Fref& f_ref);
204 
205  public:
209  bool is_valid() const;
211  void invalidate();
212 
214  void do_start_();
216  void do_next_();
217 
219  void update_f_();
221 
222  protected:
224  typename super_::adj_faces_t::const_reverse_iterator i_;
225  };
226 
227 
228 
229 # ifndef MLN_INCLUDE_ONLY
230 
231  /*----------------------------------------------------------.
232  | topo::internal::complex_relative_iterator_base<C, F, E>. |
233  `----------------------------------------------------------*/
234 
235  template <typename C, typename F, typename E>
236  inline
237  complex_relative_iterator_base<C, F, E>::complex_relative_iterator_base()
238  : c_(0)
239  {
240  // Check for required methods in E.
241  void (E::*m)() = & E::update_adj_faces_;
242  m = 0;
243 
244  exact(this)->invalidate();
245  }
246 
247  template <typename C, typename F, typename E>
248  template <typename Fref>
249  inline
250  complex_relative_iterator_base<C, F, E>::complex_relative_iterator_base(const Fref& f_ref)
251  {
252  // Check for required methods in E.
253  void (E::*m)() = & E::update_adj_faces_;
254  m = 0;
255 
256  center_at(f_ref);
257  }
258 
259  template <typename C, typename F, typename E>
260  inline
261  void
262  complex_relative_iterator_base<C, F, E>::center_at(const C& c)
263  {
264  c_ = &c;
265  exact(this)->invalidate();
266  }
267 
268  template <typename C, typename F, typename E>
269  inline
270  void
271  complex_relative_iterator_base<C, F, E>::start()
272  {
273  exact(this)->do_start_();
274  if (exact(this)->is_valid())
275  exact(this)->update_f_();
276  }
277 
278  template <typename C, typename F, typename E>
279  inline
280  void
281  complex_relative_iterator_base<C, F, E>::next_()
282  {
283  exact(this)->do_next_();
284  if (exact(this)->is_valid())
285  exact(this)->update_f_();
286  }
287 
288 
289 
290  /*------------------------------------------------------------------.
291  | topo::internal::forward_complex_relative_iterator_base<C, F, E>. |
292  `------------------------------------------------------------------*/
293 
294  template <typename C, typename F, typename E>
295  inline
296  forward_complex_relative_iterator_base<C, F, E>::forward_complex_relative_iterator_base()
297  {
298  }
299 
300  template <typename C, typename F, typename E>
301  template <typename Fref>
302  inline
303  forward_complex_relative_iterator_base<C, F, E>::forward_complex_relative_iterator_base(const Fref& f_ref)
304  : super_(f_ref)
305  {
306  }
307 
308  template <typename C, typename F, typename E>
309  inline
310  bool
311  forward_complex_relative_iterator_base<C, F, E>::is_valid() const
312  {
313  return i_ != this->adj_faces_.end();
314  }
315 
316  template <typename C, typename F, typename E>
317  inline
318  void
319  forward_complex_relative_iterator_base<C, F, E>::invalidate()
320  {
321  i_ = this->adj_faces_.end();
322  }
323 
324  template <typename C, typename F, typename E>
325  inline
326  void
327  forward_complex_relative_iterator_base<C, F, E>::do_start_()
328  {
329  exact(this)->update_adj_faces_();
330  i_ = this->adj_faces_.begin();
331  }
332 
333  template <typename C, typename F, typename E>
334  inline
335  void
336  forward_complex_relative_iterator_base<C, F, E>::do_next_()
337  {
338  ++i_;
339  }
340 
341  template <typename C, typename F, typename E>
342  inline
343  void
344  forward_complex_relative_iterator_base<C, F, E>::update_f_()
345  {
346  mln_precondition(is_valid());
347  this->f_ = *i_;
348  }
349 
350 
351  /*-------------------------------------------------------------------.
352  | topo::internal::backward_complex_relative_iterator_base<C, F, E>. |
353  `-------------------------------------------------------------------*/
354 
355  template <typename C, typename F, typename E>
356  inline
357  backward_complex_relative_iterator_base<C, F, E>::backward_complex_relative_iterator_base()
358  {
359  }
360 
361  template <typename C, typename F, typename E>
362  template <typename Fref>
363  inline
364  backward_complex_relative_iterator_base<C, F, E>::backward_complex_relative_iterator_base(const Fref& f_ref)
365  : super_(f_ref)
366  {
367  }
368 
369  template <typename C, typename F, typename E>
370  inline
371  bool
372  backward_complex_relative_iterator_base<C, F, E>::is_valid() const
373  {
374  return i_ != this->adj_faces_.rend();
375  }
376 
377  template <typename C, typename F, typename E>
378  inline
379  void
380  backward_complex_relative_iterator_base<C, F, E>::invalidate()
381  {
382  i_ = this->adj_faces_.rend();
383  }
384 
385  template <typename C, typename F, typename E>
386  inline
387  void
388  backward_complex_relative_iterator_base<C, F, E>::do_start_()
389  {
390  exact(this)->update_adj_faces_();
391  i_ = this->adj_faces_.rbegin();
392  }
393 
394  template <typename C, typename F, typename E>
395  inline
396  void
397  backward_complex_relative_iterator_base<C, F, E>::do_next_()
398  {
399  ++i_;
400  }
401 
402  template <typename C, typename F, typename E>
403  inline
404  void
405  backward_complex_relative_iterator_base<C, F, E>::update_f_()
406  {
407  mln_precondition(is_valid());
408  this->f_ = *i_;
409  }
410 
411 # endif // ! MLN_INCLUDE_ONLY
412 
413  } // end of namespace mln::topo::internal
414 
415  } // end of namespace mln::topo
416 
417 } // end of namespace mln
418 
419 #endif // ! MLN_TOPO_INTERNAL_COMPLEX_RELATIVE_ITERATOR_BASE_HH