• 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 
00148 
00150     const P& operator[](unsigned i) const;
00151 
00153     P& operator[](unsigned i);
00154 
00156     const P& operator[](const util::index& i) const;
00157     // FIXME: Is-it useful?  (redundant with 'int'?)
00158 
00159 
00161     std::size_t memory_size() const;
00162 
00164     const std::vector<P>& std_vector() const;
00165 
00167     std::vector<P>& hook_std_vector_();
00168 
00169   protected:
00170 
00171     std::vector<P> vect_;
00172   };
00173 
00174 
00175 
00178   template <typename S>
00179   class p_indexed_psite : public internal::pseudo_site_base_< const mln_element(S)&,
00180                                                               p_indexed_psite<S> >
00181   {
00182   public:
00183 
00184     typedef mln_element(S) element;
00185 
00186     // This associated type is important to know that this particular
00187     // pseudo site knows the site set it refers to.
00188     typedef S target;
00189 
00190     typedef S target_t; // To please g++-2.95.
00191     // Also read the 'todo' in mln/core/concept/pseudo_site.hh.
00192 
00193     // As a Proxy:
00194     const element& subj_();
00195 
00196     // As Itself.
00197 
00198     p_indexed_psite();
00199 
00200     p_indexed_psite(const S& s, int i);
00201 
00202     const util::index& index() const;
00203 
00204     void change_index(int i);
00205     void inc_index();
00206     void dec_index();
00207 
00208     const S* target_() const;
00209     void change_target(const S& newtarget);
00210 
00211     bool is_valid() const;
00212 
00213     operator util::index() const;
00214     operator int() const;      // To interoperate, e.g., with fun::i2v expecting an int. 
00215     operator unsigned() const; // To avoid ambiguity when an unsigned is expected.
00216 
00217     void update_() const;
00218 
00219   private:
00220 
00221     const S* s_;
00222     util::index i_;
00223     mutable element p_;
00224   };
00225 
00226 
00227 
00229 
00230   template <typename S>
00231   class p_indexed_fwd_piter
00232     :
00233     public internal::site_set_iterator_base< S,
00234                                              p_indexed_fwd_piter<S> >
00235   {
00236     typedef p_indexed_fwd_piter<S> self;
00237     typedef internal::site_set_iterator_base<S, self> super;
00238 
00239   public:
00240 
00242     p_indexed_fwd_piter();
00243 
00245     p_indexed_fwd_piter(const S& s);
00246 
00248     bool is_valid_() const;
00249 
00251     void invalidate_();
00252 
00254     void start_();
00255 
00257     void next_();
00258 
00260     int index() const;
00261 
00262   protected:
00263     using super::p_;
00264     using super::s_;
00265   };
00266 
00267 
00268 
00270 
00271   template <typename S>
00272   class p_indexed_bkd_piter
00273     :
00274     public internal::site_set_iterator_base< S,
00275                                              p_indexed_bkd_piter<S> >
00276   {
00277     typedef p_indexed_bkd_piter<S> self;
00278     typedef internal::site_set_iterator_base<S, self> super;
00279 
00280   public:
00281 
00283     p_indexed_bkd_piter();
00284 
00286     p_indexed_bkd_piter(const S& s);
00287 
00289     bool is_valid_() const;
00290 
00292     void invalidate_();
00293 
00295     void start_();
00296 
00298     void next_();
00299 
00301     int index() const;
00302 
00303   protected:
00304     using super::p_;
00305     using super::s_;
00306   };
00307 
00308 
00309 
00310   // Procedures.
00311 
00312   template <typename P, typename S>
00313   int index_of_in(const P&, const S&);
00314 
00315   template <typename S>
00316   int index_of_in(const p_indexed_psite<S>& p, const S& s);
00317 
00318   template <typename S, typename A>
00319   int index_of_in(const p_indexed_psite<S>& p, const A& a);
00320 
00321   template <typename S, typename A>
00322   int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr);
00323 
00324   template <typename S, typename A>
00325   int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr);
00326 
00327 
00328 
00329 # ifndef MLN_INCLUDE_ONLY
00330 
00331 
00332   // p_array<P>
00333 
00334   template <typename P>
00335   inline
00336   p_array<P>::p_array()
00337   {
00338   }
00339 
00340   template <typename P>
00341   inline
00342   p_array<P>::p_array(const std::vector<P>& vect)
00343     : vect_(vect)
00344   {
00345   }
00346 
00347   template <typename P>
00348   inline
00349   void
00350   p_array<P>::reserve(size_type n)
00351   {
00352     vect_.reserve(n);
00353   }
00354 
00355   template <typename P>
00356   inline
00357   bool
00358   p_array<P>::has(const psite& p) const
00359   {
00360     mln_precondition(p.target_() == this); // FIXME: Refine.
00361     if (! has(p.index()))
00362       return false;
00363     // The type of rhs below is mln_site(p_array<P>).
00364     mln_invariant(p == static_cast<P>((*this)[p.index()]));
00365     return true;
00366   }
00367 
00368   template <typename P>
00369   inline
00370   bool
00371   p_array<P>::has(const util::index& i) const
00372   {
00373     return i >= 0 && unsigned(i) < nsites();
00374   }
00375 
00376   template <typename P>
00377   inline
00378   bool
00379   p_array<P>::is_valid() const
00380   {
00381     return true;
00382   }
00383 
00384   template <typename P>
00385   inline
00386   const P&
00387   p_array<P>::operator[](const util::index& i) const
00388   {
00389     mln_precondition(has(i));
00390     return vect_[i];
00391   }
00392 
00393   template <typename P>
00394   inline
00395   unsigned
00396   p_array<P>::nsites() const
00397   {
00398     return vect_.size();
00399   }
00400 
00401   template <typename P>
00402   inline
00403   p_array<P>&
00404   p_array<P>::append(const P& p)
00405   {
00406     vect_.push_back(p);
00407     return *this;
00408   }
00409 
00410   template <typename P>
00411   inline
00412   void
00413   p_array<P>::insert(const P& p)
00414   {
00415     vect_.push_back(p);
00416   }
00417 
00418   template <typename P>
00419   inline
00420   p_array<P>&
00421   p_array<P>::append(const p_array<P>& other)
00422   {
00423     vect_.insert(vect_.end(),
00424                  other.std_vector().begin(),
00425                  other.std_vector().end());
00426     return *this;
00427   }
00428 
00429   template <typename P>
00430   inline
00431   void
00432   p_array<P>::clear()
00433   {
00434     vect_.clear();
00435     mln_postcondition(this->is_empty());
00436   }
00437 
00438   template <typename P>
00439   inline
00440   const P&
00441   p_array<P>::operator[](unsigned i) const
00442   {
00443     mln_precondition(i < nsites());
00444     return vect_[i];
00445   }
00446 
00447   template <typename P>
00448   inline
00449   P&
00450   p_array<P>::operator[](unsigned i)
00451   {
00452     mln_precondition(i < nsites());
00453     return vect_[i];
00454   }
00455 
00456   template <typename P>
00457   inline
00458   void
00459   p_array<P>::change(const psite& p, const P& new_p)
00460   {
00461     mln_precondition(has(p));
00462     vect_[p.index()] = new_p;
00463   }
00464 
00465   template <typename P>
00466   inline
00467   std::size_t
00468   p_array<P>::memory_size() const
00469   {
00470     return sizeof(*this) + nsites() * sizeof(P);
00471   }
00472 
00473   template <typename P>
00474   inline
00475   const std::vector<P>&
00476   p_array<P>::std_vector() const
00477   {
00478     return vect_;
00479   }
00480 
00481   template <typename P>
00482   inline
00483   std::vector<P>&
00484   p_array<P>::hook_std_vector_()
00485   {
00486     return vect_;
00487   }
00488 
00489 
00490 
00491   // p_indexed_psite<S>
00492 
00493   template <typename S>
00494   inline
00495   p_indexed_psite<S>::p_indexed_psite()
00496     : s_(0),
00497       i_(0)
00498   {
00499   }
00500 
00501   template <typename S>
00502   inline
00503   p_indexed_psite<S>::p_indexed_psite(const S& s, int i)
00504     : s_(& s),
00505       i_(i)
00506   {
00507     update_();
00508   }
00509 
00510   template <typename S>
00511   inline
00512   const util::index&
00513   p_indexed_psite<S>::index() const
00514   {
00515     return i_;
00516   }
00517 
00518   template <typename S>
00519   inline
00520   void
00521   p_indexed_psite<S>::change_index(int i)
00522   {
00523     i_ = i;
00524     update_();
00525   }
00526 
00527   template <typename S>
00528   inline
00529   void
00530   p_indexed_psite<S>::dec_index()
00531   {
00532     --i_;
00533     update_();
00534   }
00535 
00536   template <typename S>
00537   inline
00538   void
00539   p_indexed_psite<S>::inc_index()
00540   {
00541     ++i_;
00542     update_();
00543   }
00544 
00545   template <typename S>
00546   inline
00547   void
00548   p_indexed_psite<S>::change_target(const S& newtarget)
00549   {
00550     s_ = & newtarget;
00551     i_ = -1; // Invalidate.
00552   }
00553 
00554   template <typename S>
00555   inline
00556   bool
00557   p_indexed_psite<S>::is_valid() const
00558   {
00559     return s_ != 0 && s_->has(i_);
00560   }
00561 
00562   template <typename S>
00563   inline
00564   const S*
00565   p_indexed_psite<S>::target_() const
00566   {
00567     return s_;
00568   }
00569 
00570   template <typename S>
00571   inline
00572   const mln_element(S)&
00573   p_indexed_psite<S>::subj_()
00574   {
00575     if (is_valid())
00576       mln_invariant(p_ == (*s_)[i_]);
00577     return p_;
00578   }
00579 
00580   template <typename S>
00581   inline
00582   void
00583   p_indexed_psite<S>::update_() const
00584   {
00585     if (is_valid())
00586       p_ = (*s_)[i_];
00587   }
00588 
00589   template <typename S>
00590   inline
00591   p_indexed_psite<S>::operator util::index() const
00592   {
00593     return i_;
00594   }
00595 
00596   template <typename S>
00597   inline
00598   p_indexed_psite<S>::operator int() const
00599   {
00600     return i_;
00601   }
00602 
00603   template <typename S>
00604   inline
00605   p_indexed_psite<S>::operator unsigned() const
00606   {
00607     mln_precondition(i_ >= 0);
00608     return i_;
00609   }
00610 
00611 
00612   // p_indexed_fwd_piter<S>.
00613 
00614   template <typename S>
00615   inline
00616   p_indexed_fwd_piter<S>::p_indexed_fwd_piter()
00617   {
00618   }
00619 
00620   template <typename S>
00621   inline
00622   p_indexed_fwd_piter<S>::p_indexed_fwd_piter(const S& s)
00623   {
00624     this->change_target(s);
00625   }
00626 
00627   template <typename S>
00628   inline
00629   bool
00630   p_indexed_fwd_piter<S>::is_valid_() const
00631   {
00632     mln_invariant(p_.index() >= 0);
00633     return p_.index() < int(s_->nsites());
00634   }
00635 
00636   template <typename S>
00637   inline
00638   void
00639   p_indexed_fwd_piter<S>::invalidate_()
00640   {
00641     p_.change_index(s_->nsites());
00642   }
00643 
00644   template <typename S>
00645   inline
00646   void
00647   p_indexed_fwd_piter<S>::start_()
00648   {
00649     p_.change_index(0);
00650   }
00651 
00652   template <typename S>
00653   inline
00654   void
00655   p_indexed_fwd_piter<S>::next_()
00656   {
00657     p_.inc_index();
00658   }
00659 
00660   template <typename S>
00661   inline
00662   int
00663   p_indexed_fwd_piter<S>::index() const
00664   {
00665     return p_.index();
00666   }
00667 
00668 
00669   // p_indexed_bkd_piter<S>.
00670 
00671   template <typename S>
00672   inline
00673   p_indexed_bkd_piter<S>::p_indexed_bkd_piter()
00674   {
00675   }
00676 
00677   template <typename S>
00678   inline
00679   p_indexed_bkd_piter<S>::p_indexed_bkd_piter(const S& s)
00680   {
00681     this->change_target(s);
00682   }
00683 
00684   template <typename S>
00685   inline
00686   bool
00687   p_indexed_bkd_piter<S>::is_valid_() const
00688   {
00689     mln_invariant(p_.index() < int(s_->nsites()));
00690     return p_.index() >= 0;
00691   }
00692 
00693   template <typename S>
00694   inline
00695   void
00696   p_indexed_bkd_piter<S>::invalidate_()
00697   {
00698     p_.change_index(-1);
00699   }
00700 
00701   template <typename S>
00702   inline
00703   void
00704   p_indexed_bkd_piter<S>::start_()
00705   {
00706     p_.change_index(s_->nsites() - 1);
00707   }
00708 
00709   template <typename S>
00710   inline
00711   void
00712   p_indexed_bkd_piter<S>::next_()
00713   {
00714     p_.dec_index();
00715   }
00716 
00717   template <typename S>
00718   inline
00719   int
00720   p_indexed_bkd_piter<S>::index() const
00721   {
00722     return p_.index();
00723   }
00724 
00725 
00726   // Procedures
00727 
00728   template <typename P, typename S>
00729   int index_of_in(const P&, const S&)
00730   {
00731     return -1;
00732   }
00733 
00734   template <typename S>
00735   int index_of_in(const p_indexed_psite<S>& p, const S& s)
00736   {
00737     if ((void*)(p.target_()) == (void*)(&s))
00738         return p.index();
00739       else
00740         return index_of_in(p.unproxy_(), s);
00741   }
00742 
00743   template <typename S, typename A>
00744   int index_of_in(const p_indexed_psite<S>& p, const A& a)
00745   {
00746     return index_of_in(p.unproxy_(), a);
00747   }
00748 
00749   template <typename S, typename A>
00750   inline
00751   int
00752   index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr)
00753   {
00754     return index_of_in(p.unproxy_(), arr);
00755   }
00756 
00757   template <typename S, typename A>
00758   inline
00759   int
00760   index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr)
00761   {
00762     return index_of_in(p.unproxy_(), arr);
00763   }
00764 
00765 # endif // ! MLN_INCLUDE_ONLY
00766 
00767 } // end of namespace mln
00768 
00769 
00770 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH

Generated on Thu Sep 8 2011 18:32:11 for Milena (Olena) by  doxygen 1.7.1