• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

p_array.hh

00001 // Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_CORE_SITE_SET_P_ARRAY_HH
00027 # define MLN_CORE_SITE_SET_P_ARRAY_HH
00028 
00039 
00040 # include <vector>
00041 
00042 # include <mln/core/internal/site_set_base.hh>
00043 # include <mln/core/internal/site_set_iterator_base.hh>
00044 # include <mln/core/internal/pseudo_site_base.hh>
00045 # include <mln/util/index.hh>
00046 
00047 
00048 namespace mln
00049 {
00050 
00051   // Forward declarations.
00052   template <typename P> class  p_array;
00053 
00054   template <typename S> class  p_indexed_psite;
00055   template <typename S> struct p_indexed_fwd_piter;
00056   template <typename S> struct p_indexed_bkd_piter;
00057 
00058 
00059 
00060   namespace trait
00061   {
00062 
00063     template <typename P>
00064     struct site_set_< p_array<P> >
00065     {
00066       typedef trait::site_set::nsites::known     nsites;
00067       typedef trait::site_set::bbox::unknown     bbox;
00068       typedef trait::site_set::contents::growing contents;
00069       typedef trait::site_set::arity::multiple   arity;
00070     };
00071 
00072   } // end of namespace trait
00073 
00074 
00075 
00081   //
00082   template <typename P>
00083   class p_array : public internal::site_set_base_< P, p_array<P> >
00084   {
00085     typedef p_array<P> self_;
00086   public:
00087     typedef typename std::vector<P>::size_type size_type;
00088 
00090     typedef P element;
00091 
00093     typedef p_indexed_psite<self_> psite;
00094 
00096     typedef p_indexed_fwd_piter<self_> fwd_piter;
00097 
00099     typedef p_indexed_bkd_piter<self_> bkd_piter;
00100 
00102     typedef fwd_piter piter;
00103 
00104 
00106     p_array();
00107 
00109     p_array(const std::vector<P>& vect);
00110 
00111 
00113     void reserve(size_type n);
00114 
00115 
00117     bool has(const psite& p) const;
00118 
00120     bool has(const util::index& i) const;
00121 
00123     bool is_valid() const;
00124 
00125 
00127     void change(const psite& p, const P& new_p);
00128 
00130     unsigned nsites() const;
00131 
00132 
00134     p_array<P>& append(const P& p);
00135 
00137     p_array<P>& append(const p_array<P>& other);
00138 
00140     typedef P i_element;
00141 
00143     void insert(const P& p);
00144 
00146     void clear();
00147 
00149     void resize(size_t size);
00150 
00151 
00153     const P& operator[](unsigned i) const;
00154 
00156     P& operator[](unsigned i);
00157 
00159     const P& operator[](const util::index& i) const;
00160     // FIXME: Is-it useful?  (redundant with 'int'?)
00161 
00162 
00164     std::size_t memory_size() const;
00165 
00167     const std::vector<P>& std_vector() const;
00168 
00170     std::vector<P>& hook_std_vector_();
00171 
00172   protected:
00173 
00174     std::vector<P> vect_;
00175   };
00176 
00177 
00178 
00181   template <typename S>
00182   class p_indexed_psite : public internal::pseudo_site_base_< const mln_element(S)&,
00183                                                               p_indexed_psite<S> >
00184   {
00185   public:
00186 
00187     typedef mln_element(S) element;
00188 
00189     // This associated type is important to know that this particular
00190     // pseudo site knows the site set it refers to.
00191     typedef S target;
00192 
00193     typedef S target_t; // To please g++-2.95.
00194     // Also read the 'todo' in mln/core/concept/pseudo_site.hh.
00195 
00196     // As a Proxy:
00197     const element& subj_();
00198 
00199     // As Itself.
00200 
00201     p_indexed_psite();
00202 
00203     p_indexed_psite(const S& s, int i);
00204 
00205     const util::index& index() const;
00206 
00207     void change_index(int i);
00208     void inc_index();
00209     void dec_index();
00210 
00211     const S* target_() const;
00212     void change_target(const S& newtarget);
00213 
00214     bool is_valid() const;
00215 
00216     operator util::index() const;
00217     operator int() const;      // To interoperate, e.g., with fun::i2v expecting an int.
00218     operator unsigned() const; // To avoid ambiguity when an unsigned is expected.
00219 
00220     void update_() const;
00221 
00222   private:
00223 
00224     const S* s_;
00225     util::index i_;
00226     mutable element p_;
00227   };
00228 
00229 
00230 
00232 
00233   template <typename S>
00234   class p_indexed_fwd_piter
00235     :
00236     public internal::site_set_iterator_base< S,
00237                                              p_indexed_fwd_piter<S> >
00238   {
00239     typedef p_indexed_fwd_piter<S> self;
00240     typedef internal::site_set_iterator_base<S, self> super;
00241 
00242   public:
00243 
00245     p_indexed_fwd_piter();
00246 
00248     p_indexed_fwd_piter(const S& s);
00249 
00251     bool is_valid_() const;
00252 
00254     void invalidate_();
00255 
00257     void start_();
00258 
00260     void next_();
00261 
00263     int index() const;
00264 
00265   protected:
00266     using super::p_;
00267     using super::s_;
00268   };
00269 
00270 
00271 
00273 
00274   template <typename S>
00275   class p_indexed_bkd_piter
00276     :
00277     public internal::site_set_iterator_base< S,
00278                                              p_indexed_bkd_piter<S> >
00279   {
00280     typedef p_indexed_bkd_piter<S> self;
00281     typedef internal::site_set_iterator_base<S, self> super;
00282 
00283   public:
00284 
00286     p_indexed_bkd_piter();
00287 
00289     p_indexed_bkd_piter(const S& s);
00290 
00292     bool is_valid_() const;
00293 
00295     void invalidate_();
00296 
00298     void start_();
00299 
00301     void next_();
00302 
00304     int index() const;
00305 
00306   protected:
00307     using super::p_;
00308     using super::s_;
00309   };
00310 
00311 
00312 
00313   // Procedures.
00314 
00315   template <typename P, typename S>
00316   int index_of_in(const P&, const S&);
00317 
00318   template <typename S>
00319   int index_of_in(const p_indexed_psite<S>& p, const S& s);
00320 
00321   template <typename S, typename A>
00322   int index_of_in(const p_indexed_psite<S>& p, const A& a);
00323 
00324   template <typename S, typename A>
00325   int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr);
00326 
00327   template <typename S, typename A>
00328   int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr);
00329 
00330 
00331 
00332 # ifndef MLN_INCLUDE_ONLY
00333 
00334 
00335   // p_array<P>
00336 
00337   template <typename P>
00338   inline
00339   p_array<P>::p_array()
00340   {
00341   }
00342 
00343   template <typename P>
00344   inline
00345   p_array<P>::p_array(const std::vector<P>& vect)
00346     : vect_(vect)
00347   {
00348   }
00349 
00350   template <typename P>
00351   inline
00352   void
00353   p_array<P>::reserve(size_type n)
00354   {
00355     vect_.reserve(n);
00356   }
00357 
00358   template <typename P>
00359   inline
00360   bool
00361   p_array<P>::has(const psite& p) const
00362   {
00363     mln_precondition(p.target_() == this); // FIXME: Refine.
00364     if (! has(p.index()))
00365       return false;
00366     // The type of rhs below is mln_site(p_array<P>).
00367     mln_invariant(p == static_cast<P>((*this)[p.index()]));
00368     return true;
00369   }
00370 
00371   template <typename P>
00372   inline
00373   bool
00374   p_array<P>::has(const util::index& i) const
00375   {
00376     return i >= 0 && unsigned(i) < nsites();
00377   }
00378 
00379   template <typename P>
00380   inline
00381   bool
00382   p_array<P>::is_valid() const
00383   {
00384     return true;
00385   }
00386 
00387   template <typename P>
00388   inline
00389   const P&
00390   p_array<P>::operator[](const util::index& i) const
00391   {
00392     mln_precondition(has(i));
00393     return vect_[i];
00394   }
00395 
00396   template <typename P>
00397   inline
00398   unsigned
00399   p_array<P>::nsites() const
00400   {
00401     return vect_.size();
00402   }
00403 
00404   template <typename P>
00405   inline
00406   p_array<P>&
00407   p_array<P>::append(const P& p)
00408   {
00409     vect_.push_back(p);
00410     return *this;
00411   }
00412 
00413   template <typename P>
00414   inline
00415   void
00416   p_array<P>::insert(const P& p)
00417   {
00418     vect_.push_back(p);
00419   }
00420 
00421   template <typename P>
00422   inline
00423   p_array<P>&
00424   p_array<P>::append(const p_array<P>& other)
00425   {
00426     vect_.insert(vect_.end(),
00427                  other.std_vector().begin(),
00428                  other.std_vector().end());
00429     return *this;
00430   }
00431 
00432   template <typename P>
00433   inline
00434   void
00435   p_array<P>::clear()
00436   {
00437     vect_.clear();
00438     mln_postcondition(this->is_empty());
00439   }
00440 
00441   template <typename P>
00442   inline
00443   void
00444   p_array<P>::resize(size_t size)
00445   {
00446     mln_precondition(size >= 0);
00447     vect_.resize(size);
00448   }
00449 
00450   template <typename P>
00451   inline
00452   const P&
00453   p_array<P>::operator[](unsigned i) const
00454   {
00455     mln_precondition(i < nsites());
00456     return vect_[i];
00457   }
00458 
00459   template <typename P>
00460   inline
00461   P&
00462   p_array<P>::operator[](unsigned i)
00463   {
00464     mln_precondition(i < nsites());
00465     return vect_[i];
00466   }
00467 
00468   template <typename P>
00469   inline
00470   void
00471   p_array<P>::change(const psite& p, const P& new_p)
00472   {
00473     mln_precondition(has(p));
00474     vect_[p.index()] = new_p;
00475   }
00476 
00477   template <typename P>
00478   inline
00479   std::size_t
00480   p_array<P>::memory_size() const
00481   {
00482     return sizeof(*this) + nsites() * sizeof(P);
00483   }
00484 
00485   template <typename P>
00486   inline
00487   const std::vector<P>&
00488   p_array<P>::std_vector() const
00489   {
00490     return vect_;
00491   }
00492 
00493   template <typename P>
00494   inline
00495   std::vector<P>&
00496   p_array<P>::hook_std_vector_()
00497   {
00498     return vect_;
00499   }
00500 
00501 
00502 
00503   // p_indexed_psite<S>
00504 
00505   template <typename S>
00506   inline
00507   p_indexed_psite<S>::p_indexed_psite()
00508     : s_(0),
00509       i_(0)
00510   {
00511   }
00512 
00513   template <typename S>
00514   inline
00515   p_indexed_psite<S>::p_indexed_psite(const S& s, int i)
00516     : s_(& s),
00517       i_(i)
00518   {
00519     update_();
00520   }
00521 
00522   template <typename S>
00523   inline
00524   const util::index&
00525   p_indexed_psite<S>::index() const
00526   {
00527     return i_;
00528   }
00529 
00530   template <typename S>
00531   inline
00532   void
00533   p_indexed_psite<S>::change_index(int i)
00534   {
00535     i_ = i;
00536     update_();
00537   }
00538 
00539   template <typename S>
00540   inline
00541   void
00542   p_indexed_psite<S>::dec_index()
00543   {
00544     --i_;
00545     update_();
00546   }
00547 
00548   template <typename S>
00549   inline
00550   void
00551   p_indexed_psite<S>::inc_index()
00552   {
00553     ++i_;
00554     update_();
00555   }
00556 
00557   template <typename S>
00558   inline
00559   void
00560   p_indexed_psite<S>::change_target(const S& newtarget)
00561   {
00562     s_ = & newtarget;
00563     i_ = -1; // Invalidate.
00564   }
00565 
00566   template <typename S>
00567   inline
00568   bool
00569   p_indexed_psite<S>::is_valid() const
00570   {
00571     return s_ != 0 && s_->has(i_);
00572   }
00573 
00574   template <typename S>
00575   inline
00576   const S*
00577   p_indexed_psite<S>::target_() const
00578   {
00579     return s_;
00580   }
00581 
00582   template <typename S>
00583   inline
00584   const mln_element(S)&
00585   p_indexed_psite<S>::subj_()
00586   {
00587     if (is_valid())
00588       mln_invariant(p_ == (*s_)[i_]);
00589     return p_;
00590   }
00591 
00592   template <typename S>
00593   inline
00594   void
00595   p_indexed_psite<S>::update_() const
00596   {
00597     if (is_valid())
00598       p_ = (*s_)[i_];
00599   }
00600 
00601   template <typename S>
00602   inline
00603   p_indexed_psite<S>::operator util::index() const
00604   {
00605     return i_;
00606   }
00607 
00608   template <typename S>
00609   inline
00610   p_indexed_psite<S>::operator int() const
00611   {
00612     return i_;
00613   }
00614 
00615   template <typename S>
00616   inline
00617   p_indexed_psite<S>::operator unsigned() const
00618   {
00619     mln_precondition(i_ >= 0);
00620     return i_;
00621   }
00622 
00623 
00624   // p_indexed_fwd_piter<S>.
00625 
00626   template <typename S>
00627   inline
00628   p_indexed_fwd_piter<S>::p_indexed_fwd_piter()
00629   {
00630   }
00631 
00632   template <typename S>
00633   inline
00634   p_indexed_fwd_piter<S>::p_indexed_fwd_piter(const S& s)
00635   {
00636     this->change_target(s);
00637   }
00638 
00639   template <typename S>
00640   inline
00641   bool
00642   p_indexed_fwd_piter<S>::is_valid_() const
00643   {
00644     mln_invariant(p_.index() >= 0);
00645     return p_.index() < int(s_->nsites());
00646   }
00647 
00648   template <typename S>
00649   inline
00650   void
00651   p_indexed_fwd_piter<S>::invalidate_()
00652   {
00653     p_.change_index(s_->nsites());
00654   }
00655 
00656   template <typename S>
00657   inline
00658   void
00659   p_indexed_fwd_piter<S>::start_()
00660   {
00661     p_.change_index(0);
00662   }
00663 
00664   template <typename S>
00665   inline
00666   void
00667   p_indexed_fwd_piter<S>::next_()
00668   {
00669     p_.inc_index();
00670   }
00671 
00672   template <typename S>
00673   inline
00674   int
00675   p_indexed_fwd_piter<S>::index() const
00676   {
00677     return p_.index();
00678   }
00679 
00680 
00681   // p_indexed_bkd_piter<S>.
00682 
00683   template <typename S>
00684   inline
00685   p_indexed_bkd_piter<S>::p_indexed_bkd_piter()
00686   {
00687   }
00688 
00689   template <typename S>
00690   inline
00691   p_indexed_bkd_piter<S>::p_indexed_bkd_piter(const S& s)
00692   {
00693     this->change_target(s);
00694   }
00695 
00696   template <typename S>
00697   inline
00698   bool
00699   p_indexed_bkd_piter<S>::is_valid_() const
00700   {
00701     mln_invariant(p_.index() < int(s_->nsites()));
00702     return p_.index() >= 0;
00703   }
00704 
00705   template <typename S>
00706   inline
00707   void
00708   p_indexed_bkd_piter<S>::invalidate_()
00709   {
00710     p_.change_index(-1);
00711   }
00712 
00713   template <typename S>
00714   inline
00715   void
00716   p_indexed_bkd_piter<S>::start_()
00717   {
00718     p_.change_index(s_->nsites() - 1);
00719   }
00720 
00721   template <typename S>
00722   inline
00723   void
00724   p_indexed_bkd_piter<S>::next_()
00725   {
00726     p_.dec_index();
00727   }
00728 
00729   template <typename S>
00730   inline
00731   int
00732   p_indexed_bkd_piter<S>::index() const
00733   {
00734     return p_.index();
00735   }
00736 
00737 
00738   // Procedures
00739 
00740   template <typename P, typename S>
00741   int index_of_in(const P&, const S&)
00742   {
00743     return -1;
00744   }
00745 
00746   template <typename S>
00747   int index_of_in(const p_indexed_psite<S>& p, const S& s)
00748   {
00749     if ((void*)(p.target_()) == (void*)(&s))
00750         return p.index();
00751       else
00752         return index_of_in(p.unproxy_(), s);
00753   }
00754 
00755   template <typename S, typename A>
00756   int index_of_in(const p_indexed_psite<S>& p, const A& a)
00757   {
00758     return index_of_in(p.unproxy_(), a);
00759   }
00760 
00761   template <typename S, typename A>
00762   inline
00763   int
00764   index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr)
00765   {
00766     return index_of_in(p.unproxy_(), arr);
00767   }
00768 
00769   template <typename S, typename A>
00770   inline
00771   int
00772   index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr)
00773   {
00774     return index_of_in(p.unproxy_(), arr);
00775   }
00776 
00777 # endif // ! MLN_INCLUDE_ONLY
00778 
00779 } // end of namespace mln
00780 
00781 
00782 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH

Generated on Fri Oct 19 2012 04:16:08 for Milena (Olena) by  doxygen 1.7.1