$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
p_array.hh
1 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 EPITA
2 // Research and 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_SITE_SET_P_ARRAY_HH
28 # define MLN_CORE_SITE_SET_P_ARRAY_HH
29 
40 
41 # include <vector>
42 
43 # include <mln/core/internal/site_set_base.hh>
44 # include <mln/core/internal/site_set_iterator_base.hh>
45 # include <mln/core/internal/pseudo_site_base.hh>
46 # include <mln/util/index.hh>
47 
48 
49 namespace mln
50 {
51 
52  // Forward declarations.
53  template <typename P> class p_array;
54 
55  template <typename S> class p_indexed_psite;
56  template <typename S> class p_indexed_fwd_piter;
57  template <typename S> class p_indexed_bkd_piter;
58 
59 
60 
61  namespace trait
62  {
63 
64  template <typename P>
65  struct site_set_< p_array<P> >
66  {
67  typedef trait::site_set::nsites::known nsites;
68  typedef trait::site_set::bbox::unknown bbox;
69  typedef trait::site_set::contents::growing contents;
70  typedef trait::site_set::arity::multiple arity;
71  };
72 
73  } // end of namespace trait
74 
75 
76 
82  //
83  template <typename P>
84  class p_array : public internal::site_set_base_< P, p_array<P> >
85  {
86  typedef p_array<P> self_;
87  public:
88  typedef typename std::vector<P>::size_type size_type;
89 
91  typedef P element;
92 
95 
98 
101 
103  typedef fwd_piter piter;
104 
105 
107  p_array();
108 
110  p_array(const std::vector<P>& vect);
111 
112 
114  void reserve(size_type n);
115 
116 
118  bool has(const psite& p) const;
119 
121  bool has(const util::index& i) const;
122 
124  bool is_valid() const;
125 
126 
128  void change(const psite& p, const P& new_p);
129 
131  unsigned nsites() const;
132 
133 
135  p_array<P>& append(const P& p);
136 
138  p_array<P>& append(const p_array<P>& other);
139 
141  typedef P i_element;
142 
144  void insert(const P& p);
145 
147  void clear();
148 
150  void resize(size_t size);
151 
152 
154  const P& operator[](unsigned i) const;
155 
157  P& operator[](unsigned i);
158 
160  const P& operator[](const util::index& i) const;
161  // FIXME: Is-it useful? (redundant with 'int'?)
162 
163 
165  std::size_t memory_size() const;
166 
168  const std::vector<P>& std_vector() const;
169 
172  std::vector<P>& hook_std_vector_();
174 
175  protected:
176 
177  std::vector<P> vect_;
178  };
179 
180 
181 
186  template <typename S>
187  class p_indexed_psite : public internal::pseudo_site_base_< const mln_element(S)&,
188  p_indexed_psite<S> >
189  {
190  public:
191 
192  typedef mln_element(S) element;
193 
194  // This associated type is important to know that this particular
195  // pseudo site knows the site set it refers to.
196  typedef S target;
197 
198  typedef S target_t; // To please g++-2.95.
199  // Also read the 'todo' in mln/core/concept/pseudo_site.hh.
200 
203  const element& subj_();
205 
206  // As Itself.
207 
208  p_indexed_psite();
209 
210  p_indexed_psite(const S& s, int i);
211 
212  const util::index& index() const;
213 
214  void change_index(int i);
215  void inc_index();
216  void dec_index();
217 
219  const S* target_() const;
221 
222  void change_target(const S& newtarget);
223 
224  bool is_valid() const;
225 
226  operator util::index() const;
227  operator int() const; // To interoperate, e.g., with fun::i2v expecting an int.
228  operator unsigned() const; // To avoid ambiguity when an unsigned is expected.
229 
231  void update_() const;
233 
234  private:
235 
236  const S* s_;
237  util::index i_;
238  mutable element p_;
239  };
240 
241 
242 
246  template <typename S>
248  :
249  public internal::site_set_iterator_base< S,
251  {
252  typedef p_indexed_fwd_piter<S> self;
254 
255  public:
256 
259 
261  p_indexed_fwd_piter(const S& s);
262 
265  bool is_valid_() const;
266 
268  void invalidate_();
269 
271  void start_();
272 
274  void next_();
276 
278  int index() const;
279 
280  protected:
281  using super::p_;
282  using super::s_;
283  };
284 
285 
286 
290  template <typename S>
292  :
294  p_indexed_bkd_piter<S> >
295  {
296  typedef p_indexed_bkd_piter<S> self;
298 
299  public:
300 
303 
305  p_indexed_bkd_piter(const S& s);
306 
309  bool is_valid_() const;
310 
312  void invalidate_();
313 
315  void start_();
316 
318  void next_();
320 
322  int index() const;
323 
324  protected:
325  using super::p_;
326  using super::s_;
327  };
328 
329 
330 
331  // Procedures.
332 
333  template <typename P, typename S>
334  int index_of_in(const P&, const S&);
335 
337  template <typename S>
338  int index_of_in(const p_indexed_psite<S>& p, const S& s);
339 
341  template <typename S, typename A>
342  int index_of_in(const p_indexed_psite<S>& p, const A& a);
343 
345  template <typename S, typename A>
346  int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr);
347 
349  template <typename S, typename A>
350  int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr);
351 
352 
353 
354 # ifndef MLN_INCLUDE_ONLY
355 
356 
357  // p_array<P>
358 
359  template <typename P>
360  inline
362  {
363  }
364 
365  template <typename P>
366  inline
367  p_array<P>::p_array(const std::vector<P>& vect)
368  : vect_(vect)
369  {
370  }
371 
372  template <typename P>
373  inline
374  void
375  p_array<P>::reserve(size_type n)
376  {
377  vect_.reserve(n);
378  }
379 
380  template <typename P>
381  inline
382  bool
383  p_array<P>::has(const psite& p) const
384  {
385  mln_precondition(p.target_() == this); // FIXME: Refine.
386  if (! has(p.index()))
387  return false;
388  // The type of rhs below is mln_site(p_array<P>).
389  mln_invariant(p == static_cast<P>((*this)[p.index()]));
390  return true;
391  }
392 
393  template <typename P>
394  inline
395  bool
396  p_array<P>::has(const util::index& i) const
397  {
398  return i >= 0 && unsigned(i) < nsites();
399  }
400 
401  template <typename P>
402  inline
403  bool
404  p_array<P>::is_valid() const
405  {
406  return true;
407  }
408 
409  template <typename P>
410  inline
411  const P&
412  p_array<P>::operator[](const util::index& i) const
413  {
414  mln_precondition(has(i));
415  return vect_[i];
416  }
417 
418  template <typename P>
419  inline
420  unsigned
421  p_array<P>::nsites() const
422  {
423  return vect_.size();
424  }
425 
426  template <typename P>
427  inline
428  p_array<P>&
429  p_array<P>::append(const P& p)
430  {
431  vect_.push_back(p);
432  return *this;
433  }
434 
435  template <typename P>
436  inline
437  void
438  p_array<P>::insert(const P& p)
439  {
440  vect_.push_back(p);
441  }
442 
443  template <typename P>
444  inline
445  p_array<P>&
446  p_array<P>::append(const p_array<P>& other)
447  {
448  vect_.insert(vect_.end(),
449  other.std_vector().begin(),
450  other.std_vector().end());
451  return *this;
452  }
453 
454  template <typename P>
455  inline
456  void
458  {
459  vect_.clear();
460  mln_postcondition(this->is_empty());
461  }
462 
463  template <typename P>
464  inline
465  void
466  p_array<P>::resize(size_t size)
467  {
468  mln_precondition(size >= 0);
469  vect_.resize(size);
470  }
471 
472  template <typename P>
473  inline
474  const P&
475  p_array<P>::operator[](unsigned i) const
476  {
477  mln_precondition(i < nsites());
478  return vect_[i];
479  }
480 
481  template <typename P>
482  inline
483  P&
484  p_array<P>::operator[](unsigned i)
485  {
486  mln_precondition(i < nsites());
487  return vect_[i];
488  }
489 
490  template <typename P>
491  inline
492  void
493  p_array<P>::change(const psite& p, const P& new_p)
494  {
495  mln_precondition(has(p));
496  vect_[p.index()] = new_p;
497  }
498 
499  template <typename P>
500  inline
501  std::size_t
503  {
504  return sizeof(*this) + nsites() * sizeof(P);
505  }
506 
507  template <typename P>
508  inline
509  const std::vector<P>&
510  p_array<P>::std_vector() const
511  {
512  return vect_;
513  }
514 
515  template <typename P>
516  inline
517  std::vector<P>&
519  {
520  return vect_;
521  }
522 
523 
524 
525  // p_indexed_psite<S>
526 
527  template <typename S>
528  inline
530  : s_(0),
531  i_(0)
532  {
533  }
534 
535  template <typename S>
536  inline
537  p_indexed_psite<S>::p_indexed_psite(const S& s, int i)
538  : s_(& s),
539  i_(i)
540  {
541  update_();
542  }
543 
544  template <typename S>
545  inline
546  const util::index&
548  {
549  return i_;
550  }
551 
552  template <typename S>
553  inline
554  void
556  {
557  i_ = i;
558  update_();
559  }
560 
561  template <typename S>
562  inline
563  void
565  {
566  --i_;
567  update_();
568  }
569 
570  template <typename S>
571  inline
572  void
574  {
575  ++i_;
576  update_();
577  }
578 
579  template <typename S>
580  inline
581  void
582  p_indexed_psite<S>::change_target(const S& newtarget)
583  {
584  s_ = & newtarget;
585  i_ = -1; // Invalidate.
586  }
587 
588  template <typename S>
589  inline
590  bool
592  {
593  return s_ != 0 && s_->has(i_);
594  }
595 
596  template <typename S>
597  inline
598  const S*
599  p_indexed_psite<S>::target_() const
600  {
601  return s_;
602  }
603 
604  template <typename S>
605  inline
606  const mln_element(S)&
608  {
609  if (is_valid())
610  mln_invariant(p_ == (*s_)[i_]);
611  return p_;
612  }
613 
614  template <typename S>
615  inline
616  void
617  p_indexed_psite<S>::update_() const
618  {
619  if (is_valid())
620  p_ = (*s_)[i_];
621  }
622 
623  template <typename S>
624  inline
625  p_indexed_psite<S>::operator util::index() const
626  {
627  return i_;
628  }
629 
630  template <typename S>
631  inline
632  p_indexed_psite<S>::operator int() const
633  {
634  return i_;
635  }
636 
637  template <typename S>
638  inline
639  p_indexed_psite<S>::operator unsigned() const
640  {
641  mln_precondition(i_ >= 0);
642  return i_;
643  }
644 
645 
646  // p_indexed_fwd_piter<S>.
647 
648  template <typename S>
649  inline
651  {
652  }
653 
654  template <typename S>
655  inline
657  {
658  this->change_target(s);
659  }
660 
661  template <typename S>
662  inline
663  bool
665  {
666  mln_invariant(p_.index() >= 0);
667  return p_.index() < int(s_->nsites());
668  }
669 
670  template <typename S>
671  inline
672  void
674  {
675  p_.change_index(s_->nsites());
676  }
677 
678  template <typename S>
679  inline
680  void
682  {
683  p_.change_index(0);
684  }
685 
686  template <typename S>
687  inline
688  void
690  {
691  p_.inc_index();
692  }
693 
694  template <typename S>
695  inline
696  int
698  {
699  return p_.index();
700  }
701 
702 
703  // p_indexed_bkd_piter<S>.
704 
705  template <typename S>
706  inline
708  {
709  }
710 
711  template <typename S>
712  inline
714  {
715  this->change_target(s);
716  }
717 
718  template <typename S>
719  inline
720  bool
722  {
723  mln_invariant(p_.index() < int(s_->nsites()));
724  return p_.index() >= 0;
725  }
726 
727  template <typename S>
728  inline
729  void
731  {
732  p_.change_index(-1);
733  }
734 
735  template <typename S>
736  inline
737  void
739  {
740  p_.change_index(s_->nsites() - 1);
741  }
742 
743  template <typename S>
744  inline
745  void
747  {
748  p_.dec_index();
749  }
750 
751  template <typename S>
752  inline
753  int
755  {
756  return p_.index();
757  }
758 
759 
760  // Procedures
761 
762  template <typename P, typename S>
763  int index_of_in(const P&, const S&)
764  {
765  return -1;
766  }
767 
768  template <typename S>
769  int index_of_in(const p_indexed_psite<S>& p, const S& s)
770  {
771  if ((void*)(p.target_()) == (void*)(&s))
772  return p.index();
773  else
774  return index_of_in(p.unproxy_(), s);
775  }
776 
777  template <typename S, typename A>
778  int index_of_in(const p_indexed_psite<S>& p, const A& a)
779  {
780  return index_of_in(p.unproxy_(), a);
781  }
782 
783  template <typename S, typename A>
784  inline
785  int
786  index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr)
787  {
788  return index_of_in(p.unproxy_(), arr);
789  }
790 
791  template <typename S, typename A>
792  inline
793  int
794  index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr)
795  {
796  return index_of_in(p.unproxy_(), arr);
797  }
798 
799 # endif // ! MLN_INCLUDE_ONLY
800 
801 } // end of namespace mln
802 
803 
804 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH