$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
p_double.hh
1 // Copyright (C) 2008, 2009, 2013 EPITA Research and Development
2 // 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_SITE_SET_P_DOUBLE_HH
28 # define MLN_CORE_SITE_SET_P_DOUBLE_HH
29 
39 # include <mln/core/internal/pseudo_site_base.hh>
40 # include <mln/core/internal/site_set_iterator_base.hh>
41 
42 
43 namespace mln
44 {
45 
46  // p_double_psite<S,Sp>
47 
48  template <typename S, typename Sp>
49  class p_double_psite : public internal::pseudo_site_base_< const mln_psite(Sp)&,
50  p_double_psite<S,Sp> >
51  {
52  public:
53 
55 
56  // Target associated type.
57  typedef S target;
58 
60  const S* target_() const;
62 
63  void change_target(const S& newtarget);
64 
65  bool is_valid() const;
66 
67  unsigned index() const;
68  const mln_psite(Sp)& p() const;
69 
70  void change_i(unsigned i);
71 
72  void change_p(const mln_psite(Sp)& p);
73 
75  // As a Proxy:
76  const mln_psite(Sp)& subj_();
78 
79  private:
80 
81  const target* s_;
82  mutable unsigned i_;
83  mutable mln_psite(Sp) p_;
84  };
85 
86 
87 
88  // p_double_piter<S,I1,I2>
89 
90  template <typename S, typename I1, typename I2>
92  :
93  public internal::site_set_iterator_base< S,
94  p_double_piter<S,I1,I2> >
95  {
98  public:
99 
101  p_double_piter();
102 
104  p_double_piter(const S& s);
105 
107  void change_target(const S& newtarget);
108 
110  bool is_valid_() const;
111 
113  void invalidate_();
114 
116  void start_();
117 
119  void next_();
120 
121  protected:
122  using super_::p_;
123  using super_::s_;
124 
125  private:
126  I1 i1_;
127  I2 i2_;
128 
129  // Progress to the next valid state if it exists.
130  void progress_();
131 
132  };
133 
134 
135 
136 # ifndef MLN_INCLUDE_ONLY
137 
138 
139  // p_double_psite<S,Sp>
140 
141  template <typename S, typename Sp>
142  inline
144  {
145  }
146 
147  template <typename S, typename Sp>
148  inline
149  const mln_psite(Sp)&
150  p_double_psite<S,Sp>::subj_()
151  {
152  return p_;
153  }
154 
155  template <typename S, typename Sp>
156  inline
157  const S*
158  p_double_psite<S,Sp>::target_() const
159  {
160  return s_;
161  }
162 
163  template <typename S, typename Sp>
164  inline
165  void
167  {
168  s_ = & s;
169  }
170 
171  template <typename S, typename Sp>
172  inline
173  bool
175  {
176  return s_ != 0 && p_.is_valid();
177  }
178 
179  template <typename S, typename Sp>
180  inline
181  unsigned
183  {
184  return i_;
185  }
186 
187  template <typename S, typename Sp>
188  inline
189  const mln_psite(Sp)&
191  {
192  return p_;
193  }
194 
195  template <typename S, typename Sp>
196  inline
197  void
199  {
200  i_ = i;
201  }
202 
203  template <typename S, typename Sp>
204  inline
205  void
206  p_double_psite<S,Sp>::change_p(const mln_psite(Sp)& p)
207  {
208  p_ = p;
209  }
210 
211 
212  // p_double_piter<S,I1,I2>
213 
214  template <typename S, typename I1, typename I2>
215  inline
216  p_double_piter<S,I1,I2>::p_double_piter()
217  {
218  }
219 
220  template <typename S, typename I1, typename I2>
221  inline
222  p_double_piter<S,I1,I2>::p_double_piter(const S& s)
223  {
224  this->change_target(s);
225  }
226 
227  template <typename S, typename I1, typename I2>
228  inline
229  void
230  p_double_piter<S,I1,I2>::change_target(const S& newtarget)
231  {
232  this->super_::change_target(newtarget);
233  i1_.change_target(newtarget.set_1_());
234  invalidate_();
235  }
236 
237  template <typename S, typename I1, typename I2>
238  inline
239  bool
240  p_double_piter<S,I1,I2>::is_valid_() const
241  {
242  return i2_.is_valid();
243  }
244 
245  template <typename S, typename I1, typename I2>
246  inline
247  void
248  p_double_piter<S,I1,I2>::invalidate_()
249  {
250  i2_.invalidate();
251  }
252 
253  template <typename S, typename I1, typename I2>
254  inline
255  void
256  p_double_piter<S,I1,I2>::start_()
257  {
258  i1_.start();
259  if (i1_.is_valid())
260  {
261  i2_.change_target(s_->set_2_(i1_));
262  i2_.start();
263  if (! i2_.is_valid())
264  progress_();
265  else
266  {
267  p_.change_i(i1_.index_());
268  p_.change_p(i2_);
269  }
270  }
271  else
272  i2_.invalidate();
273  mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
274  }
275 
276  template <typename S, typename I1, typename I2>
277  inline
278  void
279  p_double_piter<S,I1,I2>::next_()
280  {
281  i2_.next();
282  if (! i2_.is_valid())
283  progress_();
284  else
285  p_.change_p(i2_);
286  mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
287  }
288 
289  template <typename S, typename I1, typename I2>
290  inline
291  void
292  p_double_piter<S,I1,I2>::progress_()
293  {
294  // This routine is general; it does not make the assumption that
295  // the site set type features is_empty().
296  while (! i2_.is_valid() && i1_.is_valid())
297  {
298  i1_.next();
299  if (! i1_.is_valid())
300  {
301  // End of iterations.
302  i2_.invalidate(); // Safety.
303  return;
304  }
305  i2_.change_target(s_->set_2_(i1_));
306  i2_.start();
307  }
308  if (i2_.is_valid())
309  {
310  p_.change_i(i1_.index_());
311  p_.change_p(i2_);
312  }
313  }
314 
315 # endif // ! MLN_INCLUDE_ONLY
316 
317 } // end of namespace mln
318 
319 
320 #endif // ! MLN_CORE_SITE_SET_P_DOUBLE_HH