Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
site_relative_iterator_base.hh
1 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
2 // (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena 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 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH
28 # define MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH
29 
37 
38 
39 # include <vector>
40 # include <mln/core/internal/site_iterator_base.hh>
41 # include <mln/metal/converts_to.hh>
42 
43 
44 namespace mln
45 {
46 
47  namespace internal
48  {
49 
60  template <typename S, typename E, typename C = mln_psite(S)>
61  class site_relative_iterator_base : public site_iterator_base< S, E >
62  {
63  public:
64 
66  site_relative_iterator_base();
67 
68  template <typename P>
69  void center_at(const P& c);
70 
72  void start_();
73 
75  void next_();
76 
79  const S& site_set() const;
80 
82  const C& center() const;
83 
89  const mln_psite(S)& subj_();
90 
92  const mln_psite(S)& p_hook_() const;
93 
95  void change_target(const S& s);
96 
102  E& update();
103 
104  protected:
105 
108  const C* c_;
109 
110  private:
111 
112  // Allows inherited classes to do extra work while centering.
113  // Default implementation.
114  template <typename P>
115  void center_at_(const P& c);
116 
118  mln_psite(S) p_;
119  };
120 
121 
122 
123 # ifndef MLN_INCLUDE_ONLY
124 
125  template <typename S, typename E, typename C>
126  inline
127  site_relative_iterator_base<S,E,C>::site_relative_iterator_base()
128  : c_(0)
129  {
130  void (E::*m1)() = & E::do_start_;
131  m1 = 0;
132  void (E::*m2)() = & E::do_next_;
133  m2 = 0;
134  mln_psite(S) (E::*m3)() const = & E::compute_p_;
135  m3 = 0;
136  }
137 
138  template <typename S, typename E, typename C>
139  template <typename P>
140  inline
141  void
142  site_relative_iterator_base<S,E,C>::center_at(const P& c)
143  {
144  mlc_converts_to(P, const C&)::check();
145  c_ = & static_cast< const C& >(c);
146  exact(this)->center_at_(c); // May call some extra code.
147  this->invalidate();
148  }
149 
150  template <typename S, typename E, typename C>
151  inline
152  void
153  site_relative_iterator_base<S,E,C>::start_()
154  {
155  exact(this)->do_start_();
156  if (this->is_valid())
157  p_ = exact(this)->compute_p_();
158  }
159 
160  template <typename S, typename E, typename C>
161  inline
162  void
163  site_relative_iterator_base<S,E,C>::next_()
164  {
165  exact(this)->do_next_();
166  if (this->is_valid())
167  p_ = exact(this)->compute_p_();
168  }
169 
170  template <typename S, typename E, typename C>
171  inline
172  const C&
173  site_relative_iterator_base<S,E,C>::center() const
174  {
175  mln_precondition(c_ != 0);
176  return *c_;
177  }
178 
179  template <typename S, typename E, typename C>
180  inline
181  const S&
182  site_relative_iterator_base<S,E,C>::site_set() const
183  {
184  mln_precondition(this->s_ != 0);
185  return *this->s_;
186  }
187 
188  template <typename S, typename E, typename C>
189  inline
190  const mln_psite(S)&
191  site_relative_iterator_base<S,E,C>::subj_()
192  {
193  mln_assertion(exact(this)->compute_p_() == p_);
194  return p_;
195  }
196 
197  template <typename S, typename E, typename C>
198  inline
199  const mln_psite(S)&
200  site_relative_iterator_base<S,E,C>::p_hook_() const
201  {
202  return p_;
203  }
204 
205  template <typename S, typename E, typename C>
206  inline
207  void
208  site_relative_iterator_base<S,E,C>::change_target(const S& s)
209  {
210  this->s_ = & s;
211  // p might be also updated since it can hold a pointer towards
212  // the set it designates, so:
213  if_possible::change_target(p_, s);
214  // Last:
215  this->invalidate();
216  }
217 
218  template <typename S, typename E, typename C>
219  inline
220  E&
221  site_relative_iterator_base<S,E,C>::update()
222  {
223  mln_precondition(this->s_ && c_);
224  p_ = exact(this)->compute_p_();
225  mln_postcondition(this->is_valid());
226  return exact(*this);
227  }
228 
229  template <typename S, typename E, typename C>
230  template <typename P>
231  inline
232  void
233  site_relative_iterator_base<S,E,C>::center_at_(const P&)
234  {
235  // Default is no-op, meaning "no extra code".
236  }
237 
238 # endif // ! MLN_INCLUDE_ONLY
239 
240  } // end of namespace mln::internal
241 
242 } // end of namespace mln
243 
244 
245 #endif // ! MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH