$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
p_run.hh
1 // Copyright (C) 2007, 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_RUN_HH
28 # define MLN_CORE_SITE_SET_P_RUN_HH
29 
35 
36 # include <mln/core/internal/site_set_base.hh>
37 # include <mln/core/site_set/box.hh>
38 # include <mln/core/internal/pseudo_site_base.hh>
39 # include <mln/util/index.hh>
40 
41 
42 namespace mln
43 {
44 
45  // Forward declarations.
46  template <typename P> class p_run;
47  template <typename P> class p_run_psite;
48  template <typename P> class p_run_fwd_piter_;
49  template <typename P> class p_run_bkd_piter_;
50 
51  // We do not use here the p_indexed* classes to gain efficiency.
52 
53 
54  namespace trait
55  {
56 
57  template <typename P>
58  struct site_set_< p_run<P> >
59  {
60  typedef trait::site_set::nsites::known nsites;
61  typedef trait::site_set::bbox::straight bbox;
62  typedef trait::site_set::contents::fixed contents;
63  typedef trait::site_set::arity::unique arity;
64  };
65 
66  template <typename P>
67  struct set_precise_unary_< op::ord, p_run<P> >
68  {
69  typedef set_precise_unary_< op::ord, p_run<P> > ret; // Itself.
70  bool strict(const p_run<P>& lhs, const p_run<P>& rhs) const;
71  };
72 
73  } // end of namespace trait
74 
75 
76 
80 
86  template <typename P>
87  class p_run : public internal::site_set_base_< P, p_run<P> >
88  {
89  public:
90 
92  typedef P element;
93 
94 
97 
100 
103 
105  typedef fwd_piter piter;
106 
107 
109  p_run();
110 
112  p_run(const P& start, unsigned short len);
113 
115  p_run(const P& start, const P& end);
116 
118  void init(const P& start, unsigned short len);
119 
120 
122  bool has(const psite& p) const;
123 
125  bool has(const P& p) const;
126 
128  bool has_index(unsigned short i) const;
129 
131  unsigned nsites() const;
132 
134  unsigned short length() const;
135 
137  P operator[](unsigned short i) const;
138 
140  const P& start() const;
141 
143  P end() const;
144 
146  bool is_valid() const;
147 
148 
151 
153  mln::box<P> bbox() const;
154 
155 
157  std::size_t memory_size() const;
158 
159  protected:
160 
163 
165  unsigned len_;
166  };
167 
168 
170  template <typename P>
171  std::ostream& operator<<(std::ostream& ostr, const p_run<P>& r);
172 
173 
174 
175  // p_run_psite<P>
176 
177  template <typename P>
178  class p_run_psite : public internal::pseudo_site_base_< const P&,
179  p_run_psite<P> >
180  {
181  typedef p_run_psite<P> self;
183 
184  public:
185 
186  // This associated type is important to know that this particular
187  // pseudo site knows the site set it refers to.
188  typedef p_run<P> target;
189 
190  // As a Proxy:
191  const P& subj_();
192 
193  p_run_psite();
194 
195  p_run_psite(const p_run<P>& run, int i);
196 
197  int index() const;
198 
199  void change_index(int i);
200  void inc_index();
201  void dec_index();
202 
204  const p_run<P>* target_() const;
206 
207  void change_target(const p_run<P>& new_target);
208 
209  bool is_valid() const;
210 
211  operator util::index() const;
212 
213  const p_run<P>& run() const;
214 
215  private:
216 
217  const p_run<P>* run_;
218  int i_;
219  mutable P p_;
220  };
221 
222 
223 
224 # ifndef MLN_INCLUDE_ONLY
225 
226  template <typename P>
227  inline
229  {
230  len_ = 0;
231  }
232 
233  template <typename P>
234  inline
235  p_run<P>::p_run(const P& start, unsigned short len)
236  {
237  mln_precondition(len != 0);
238  init(start, len);
239  }
240 
241  template <typename P>
242  inline
243  p_run<P>::p_run(const P& start, const P& end)
244  : start_(start)
245  {
246  mln_precondition(cut_(end) == cut_(start));
247  mln_precondition(end.last_coord() >= start.last_coord());
248  len_ = end.last_coord() - start.last_coord() + 1;
249  }
250 
251  template <typename P>
252  inline
253  void
254  p_run<P>::init(const P& start, unsigned short len)
255  {
256  mln_precondition(len != 0);
257  start_ = start;
258  len_ = len;
259  }
260 
261  template <typename P>
262  inline
263  bool
264  p_run<P>::is_valid() const
265  {
266  return len_ != 0;
267  }
268 
269  template <typename P>
270  inline
272  p_run<P>::bbox() const
273  {
274  mln::box<P> b(this->start_, this->end());
275  return b;
276  }
277 
278  template <typename P>
279  inline
280  bool
281  p_run<P>::has(const psite& p) const
282  {
283  mln_precondition(p.target_() == this); // FIXME: Refine.
284  if (p.index() < 0 || unsigned(p.index()) >= len_)
285  return false;
286  // The type of rhs below is mln_site(p_run<P>).
287  mln_invariant(p.to_site() == (*this)[p.index()]);
288  return true;
289  }
290 
291  template <typename P>
292  inline
293  bool
294  p_run<P>::has(const P& p) const
295  {
296  mln_precondition(is_valid());
297  if (cut_(p) != cut_(start_))
298  return false;
299  return
300  p.last_coord() >= start_.last_coord() &&
301  p.last_coord() < start_.last_coord() + len_;
302  }
303 
304  template <typename P>
305  inline
306  bool
307  p_run<P>::has_index(unsigned short i) const
308  {
309  return i < len_;
310  }
311 
312  template <typename P>
313  inline
314  unsigned
315  p_run<P>::nsites() const
316  {
317  mln_precondition(is_valid());
318  return len_;
319  }
320 
321  template <typename P>
322  inline
323  unsigned short
324  p_run<P>::length() const
325  {
326  mln_precondition(is_valid());
327  return len_;
328  }
329 
330  template <typename P>
331  inline
332  P
333  p_run<P>::operator[](unsigned short i) const
334  {
335  mln_precondition(is_valid());
336  mln_precondition(i < len_);
337  P p = start_;
338  p.last_coord() += i;
339  return p;
340  }
341 
342  template <typename P>
343  inline
344  const P&
345  p_run<P>::start() const
346  {
347  return start_;
348  }
349 
350  template <typename P>
351  inline
352  P
353  p_run<P>::end() const
354  {
355  P p = start_;
356  p.last_coord() += len_ - 1;
357  return p;
358  }
359 
360  template <typename P>
361  inline
362  std::size_t
363  p_run<P>::memory_size() const
364  {
365  return sizeof(*this);
366  }
367 
368  template <typename P>
369  std::ostream& operator<<(std::ostream& ostr, const p_run<P>& r)
370  {
371  ostr << '(' << r.start() << ", " << r.length() << ')';
372  return ostr;
373  }
374 
375 
376 
377  // p_run_psite<P>
378 
379  template <typename P>
380  inline
382  : run_(0),
383  i_(0)
384  {
385  }
386 
387  template <typename P>
388  inline
389  p_run_psite<P>::p_run_psite(const p_run<P>& run, int i)
390  : run_(&run),
391  i_(i)
392  {
393  p_ = run.start();
394  p_.last_coord() += i_;
395  }
396 
397  template <typename P>
398  inline
399  bool
401  {
402  return run_ != 0 && run_->has_index(i_);
403  }
404 
405  template <typename P>
406  inline
407  int
408  p_run_psite<P>::index() const
409  {
410  return i_;
411  }
412 
413  template <typename P>
414  inline
415  void
417  {
418  p_.last_coord() += (i - i_);
419  i_ = i;
420  }
421 
422  template <typename P>
423  inline
424  void
426  {
427  --i_;
428  p_.last_coord() -= 1;
429  }
430 
431  template <typename P>
432  inline
433  void
435  {
436  ++i_;
437  p_.last_coord() += 1;
438  }
439 
440  template <typename P>
441  inline
442  const p_run<P>*
443  p_run_psite<P>::target_() const
444  {
445  return run_;
446  }
447 
448  template <typename P>
449  inline
450  void
451  p_run_psite<P>::change_target(const p_run<P>& new_target)
452  {
453  run_ = & new_target;
454  i_ = 0;
455  p_ = run_->start();
456  }
457 
458  template <typename P>
459  inline
460  const P&
462  {
463  return p_;
464  }
465 
466  template <typename P>
467  inline
468  p_run_psite<P>::operator util::index() const
469  {
470  return i_;
471  }
472 
473  template <typename P>
474  inline
475  const p_run<P>&
476  p_run_psite<P>::run() const
477  {
478  mln_precondition(run_ != 0);
479  return *run_;
480  }
481 
482  namespace trait
483  {
484 
485  template <typename P>
486  inline
487  bool
488  set_precise_unary_< op::ord, p_run<P> >::strict(const p_run<P>& lhs, const p_run<P>& rhs) const
489  {
490  return util::ord_strict(lhs.start(), rhs.start());
491  }
492 
493  } // end of namespace trait
494 
495 # endif // ! MLN_INCLUDE_ONLY
496 
497 } // end of namespace mln
498 
499 
500 # include <mln/core/site_set/p_run_piter.hh>
501 
502 
503 #endif // ! MLN_CORE_SITE_SET_P_RUN_HH