$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
site_relative_iterator_base.hh
1 // Copyright (C) 2008, 2009, 2011, 2012, 2013 EPITA Research and
2 // Development Laboratory (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 
61  template <typename S, typename E, typename C = mln_psite(S)>
63  {
64  public:
65 
68 
69  template <typename P>
70  void center_at(const P& c);
71 
74  void start_();
75 
77  void next_();
79 
82  const S& site_set() const;
83 
85  const C& center() const;
86 
93  const mln_psite(S)& subj_();
94 
96  const mln_psite(S)& p_hook_() const;
98 
100  void change_target(const S& s);
101 
107  E& update();
108 
109  protected:
110 
113  const C* c_;
114 
115  private:
116 
117  // Allows inherited classes to do extra work while centering.
118  // Default implementation.
119  template <typename P>
120  void center_at_(const P& c);
121 
123  mln_psite(S) p_;
124  };
125 
126 
127 
128 # ifndef MLN_INCLUDE_ONLY
129 
130  template <typename S, typename E, typename C>
131  inline
133  : c_(0)
134  {
135  void (E::*m1)() = & E::do_start_;
136  (void) m1;
137  void (E::*m2)() = & E::do_next_;
138  (void) m2;
139  mln_psite(S) (E::*m3)() const = & E::compute_p_;
140  (void) m3;
141  }
142 
143  template <typename S, typename E, typename C>
144  template <typename P>
145  inline
146  void
148  {
149  mlc_converts_to(P, const C&)::check();
150  c_ = & static_cast< const C& >(c);
151  exact(this)->center_at_(c); // May call some extra code.
152  this->invalidate();
153  }
154 
155  template <typename S, typename E, typename C>
156  inline
157  void
158  site_relative_iterator_base<S,E,C>::start_()
159  {
160  exact(this)->do_start_();
161  if (this->is_valid())
162  p_ = exact(this)->compute_p_();
163  }
164 
165  template <typename S, typename E, typename C>
166  inline
167  void
168  site_relative_iterator_base<S,E,C>::next_()
169  {
170  exact(this)->do_next_();
171  if (this->is_valid())
172  p_ = exact(this)->compute_p_();
173  }
174 
175  template <typename S, typename E, typename C>
176  inline
177  const C&
178  site_relative_iterator_base<S,E,C>::center() const
179  {
180  mln_precondition(c_ != 0);
181  return *c_;
182  }
183 
184  template <typename S, typename E, typename C>
185  inline
186  const S&
188  {
189  mln_precondition(this->s_ != 0);
190  return *this->s_;
191  }
192 
193  template <typename S, typename E, typename C>
194  inline
195  const mln_psite(S)&
196  site_relative_iterator_base<S,E,C>::subj_()
197  {
198  // valid => exact(this)->compute_p_() == p_
199  mln_assertion(!this->is_valid() || exact(this)->compute_p_() == p_);
200  return p_;
201  }
202 
203  template <typename S, typename E, typename C>
204  inline
205  const mln_psite(S)&
206  site_relative_iterator_base<S,E,C>::p_hook_() const
207  {
208  return p_;
209  }
210 
211  template <typename S, typename E, typename C>
212  inline
213  void
214  site_relative_iterator_base<S,E,C>::change_target(const S& s)
215  {
216  this->s_ = & s;
217  // p might be also updated since it can hold a pointer towards
218  // the set it designates, so:
219  if_possible::change_target(p_, s);
220  // Last:
221  this->invalidate();
222  }
223 
224  template <typename S, typename E, typename C>
225  inline
226  E&
228  {
229  mln_precondition(this->s_ && c_);
230  p_ = exact(this)->compute_p_();
231  mln_postcondition(this->is_valid());
232  return exact(*this);
233  }
234 
235  template <typename S, typename E, typename C>
236  template <typename P>
237  inline
238  void
239  site_relative_iterator_base<S,E,C>::center_at_(const P&)
240  {
241  // Default is no-op, meaning "no extra code".
242  }
243 
244 # endif // ! MLN_INCLUDE_ONLY
245 
246  } // end of namespace mln::internal
247 
248 } // end of namespace mln
249 
250 
251 #endif // ! MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH