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