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

p_array.hh

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

Generated on Tue Oct 4 2011 15:24:08 for Milena (Olena) by  doxygen 1.7.1