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

p_run.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_RUN_HH
00027 # define MLN_CORE_SITE_SET_P_RUN_HH
00028 
00034 
00035 # include <mln/core/internal/site_set_base.hh>
00036 # include <mln/core/site_set/box.hh>
00037 # include <mln/core/internal/pseudo_site_base.hh>
00038 # include <mln/util/index.hh>
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   // Forward declarations.
00045   template <typename P> class p_run;
00046   template <typename P> class p_run_psite;
00047   template <typename P> class p_run_fwd_piter_;
00048   template <typename P> class p_run_bkd_piter_;
00049 
00050   // We do not use here the p_indexed* classes to gain efficiency.
00051 
00052 
00053   namespace trait
00054   {
00055 
00056     template <typename P>
00057     struct site_set_< p_run<P> >
00058     {
00059       typedef trait::site_set::nsites::known   nsites;
00060       typedef trait::site_set::bbox::straight  bbox;
00061       typedef trait::site_set::contents::fixed contents;
00062       typedef trait::site_set::arity::unique   arity;
00063     };
00064 
00065     template <typename P>
00066     struct set_precise_unary_< op::ord, p_run<P> >
00067     {
00068       typedef set_precise_unary_< op::ord, p_run<P> > ret; // Itself.
00069       bool strict(const p_run<P>& lhs, const p_run<P>& rhs) const;
00070     };
00071 
00072   } // end of namespace trait
00073 
00074 
00075 
00079 
00085   template <typename P>
00086   class p_run : public internal::site_set_base_< P, p_run<P> >
00087   {
00088   public:
00089 
00091     typedef P element;
00092 
00093 
00095     typedef p_run_psite<P> psite;
00096 
00098     typedef p_run_fwd_piter_<P> fwd_piter;
00099 
00101     typedef p_run_bkd_piter_<P> bkd_piter;
00102 
00104     typedef fwd_piter piter;
00105 
00106 
00108     p_run();
00109 
00111     p_run(const P& start, unsigned short len);
00112 
00114     p_run(const P& start, const P& end);
00115 
00117     void init(const P& start, unsigned short len);
00118 
00119 
00121     bool has(const psite& p) const;
00122 
00124     bool has(const P& p) const;
00125 
00127     bool has_index(unsigned short i) const;
00128 
00130     unsigned nsites() const;
00131 
00133     unsigned short length() const;
00134 
00136     P operator[](unsigned short i) const;
00137 
00139     const P& start() const;
00140 
00142     P end() const;
00143 
00145     bool is_valid() const;
00146 
00147 
00149     typedef mln::box<P> q_box;
00150 
00152     mln::box<P> bbox() const;
00153 
00154 
00156     std::size_t memory_size() const;
00157 
00158   protected:
00159 
00161     P start_;
00162 
00164     unsigned len_;
00165   };
00166 
00167 
00168   template <typename P>
00169   std::ostream& operator<<(std::ostream& ostr, const p_run<P>& r);
00170 
00171 
00172 
00173   // p_run_psite<P>
00174 
00175   template <typename P>
00176   class p_run_psite : public internal::pseudo_site_base_< const P&,
00177                                                           p_run_psite<P> >
00178   {
00179     typedef p_run_psite<P> self;
00180     typedef internal::pseudo_site_base_<const P&, self> super;
00181 
00182   public:
00183 
00184     // This associated type is important to know that this particular
00185     // pseudo site knows the site set it refers to.
00186     typedef p_run<P> target;
00187 
00188     // As a Proxy:
00189     const P& subj_();
00190 
00191     p_run_psite();
00192 
00193     p_run_psite(const p_run<P>& run, int i);
00194 
00195     int index() const;
00196 
00197     void change_index(int i);
00198     void inc_index();
00199     void dec_index();
00200 
00201     const p_run<P>* target_() const;
00202     void change_target(const p_run<P>& new_target);
00203 
00204     bool is_valid() const;
00205 
00206     operator util::index() const;
00207 
00208     const p_run<P>& run() const;
00209 
00210   private:
00211 
00212     const p_run<P>* run_;
00213     int i_;
00214     mutable P p_;
00215   };
00216 
00217 
00218 
00219 # ifndef MLN_INCLUDE_ONLY
00220 
00221   template <typename P>
00222   inline
00223   p_run<P>::p_run()
00224   {
00225     len_ = 0;
00226   }
00227 
00228   template <typename P>
00229   inline
00230   p_run<P>::p_run(const P& start, unsigned short len)
00231   {
00232     mln_precondition(len != 0);
00233     init(start, len);
00234   }
00235 
00236   template <typename P>
00237   inline
00238   p_run<P>::p_run(const P& start, const P& end)
00239     : start_(start)
00240   {
00241     mln_precondition(cut_(end) == cut_(start));
00242     mln_precondition(end.last_coord() >= start.last_coord());
00243     len_ = end.last_coord() - start.last_coord() + 1;
00244   }
00245 
00246   template <typename P>
00247   inline
00248   void
00249   p_run<P>::init(const P& start, unsigned short len)
00250   {
00251     mln_precondition(len != 0);
00252     start_ = start;
00253     len_ = len;
00254   }
00255 
00256   template <typename P>
00257   inline
00258   bool
00259   p_run<P>::is_valid() const
00260   {
00261     return len_ != 0;
00262   }
00263 
00264   template <typename P>
00265   inline
00266   mln::box<P>
00267   p_run<P>::bbox() const
00268   {
00269     mln::box<P> b(this->start_, this->end());
00270     return b;
00271   }
00272 
00273   template <typename P>
00274   inline
00275   bool
00276   p_run<P>::has(const psite& p) const
00277   {
00278     mln_precondition(p.target_() == this); // FIXME: Refine.
00279     if (p.index() < 0 || unsigned(p.index()) >= len_)
00280       return false;
00281     // The type of rhs below is mln_site(p_run<P>).
00282     mln_invariant(p.to_site() == (*this)[p.index()]);
00283     return true;
00284   }
00285 
00286   template <typename P>
00287   inline
00288   bool
00289   p_run<P>::has(const P& p) const
00290   {
00291     mln_precondition(is_valid());
00292     if (cut_(p) != cut_(start_))
00293       return false;
00294     return
00295       p.last_coord() >= start_.last_coord() &&
00296       p.last_coord() <  start_.last_coord() + len_;
00297   }
00298 
00299   template <typename P>
00300   inline
00301   bool
00302   p_run<P>::has_index(unsigned short i) const
00303   {
00304     return i < len_;
00305   }
00306 
00307   template <typename P>
00308   inline
00309   unsigned
00310   p_run<P>::nsites() const
00311   {
00312     mln_precondition(is_valid());
00313     return len_;
00314   }
00315 
00316   template <typename P>
00317   inline
00318   unsigned short
00319   p_run<P>::length() const
00320   {
00321     mln_precondition(is_valid());
00322     return len_;
00323   }
00324 
00325   template <typename P>
00326   inline
00327   P
00328   p_run<P>::operator[](unsigned short i) const
00329   {
00330     mln_precondition(is_valid());
00331     mln_precondition(i < len_);
00332     P p = start_;
00333     p.last_coord() += i;
00334     return p;
00335   }
00336 
00337   template <typename P>
00338   inline
00339   const P&
00340   p_run<P>::start() const
00341   {
00342     return start_;
00343   }
00344 
00345   template <typename P>
00346   inline
00347   P
00348   p_run<P>::end() const
00349   {
00350     P p = start_;
00351     p.last_coord() += len_ - 1;
00352     return p;
00353   }
00354 
00355   template <typename P>
00356   inline
00357   std::size_t
00358   p_run<P>::memory_size() const
00359   {
00360     return sizeof(*this);
00361   }
00362 
00363   template <typename P>
00364   std::ostream& operator<<(std::ostream& ostr, const p_run<P>& r)
00365   {
00366     ostr << '(' << r.start() << ", " << r.length() << ')';
00367     return ostr;
00368   }
00369 
00370 
00371 
00372   // p_run_psite<P>
00373 
00374   template <typename P>
00375   inline
00376   p_run_psite<P>::p_run_psite()
00377     : run_(0),
00378       i_(0)
00379   {
00380   }
00381 
00382   template <typename P>
00383   inline
00384   p_run_psite<P>::p_run_psite(const p_run<P>& run, int i)
00385     : run_(&run),
00386       i_(i)
00387   {
00388     p_ = run.start();
00389     p_.last_coord() += i_;
00390   }
00391 
00392   template <typename P>
00393   inline
00394   bool
00395   p_run_psite<P>::is_valid() const
00396   {
00397     return run_ != 0 && run_->has_index(i_);
00398   }
00399 
00400   template <typename P>
00401   inline
00402   int
00403   p_run_psite<P>::index() const
00404   {
00405     return i_;
00406   }
00407 
00408   template <typename P>
00409   inline
00410   void
00411   p_run_psite<P>::change_index(int i)
00412   {
00413     p_.last_coord() += (i - i_);
00414     i_ = i;
00415   }
00416 
00417   template <typename P>
00418   inline
00419   void
00420   p_run_psite<P>::dec_index()
00421   {
00422     --i_;
00423     p_.last_coord() -= 1;
00424   }
00425 
00426   template <typename P>
00427   inline
00428   void
00429   p_run_psite<P>::inc_index()
00430   {
00431     ++i_;
00432     p_.last_coord() += 1;
00433   }
00434 
00435   template <typename P>
00436   inline
00437   const p_run<P>*
00438   p_run_psite<P>::target_() const
00439   {
00440     return run_;
00441   }
00442 
00443   template <typename P>
00444   inline
00445   void
00446   p_run_psite<P>::change_target(const p_run<P>& new_target)
00447   {
00448     run_ = & new_target;
00449     i_ = 0;
00450     p_ = run_->start();
00451   }
00452 
00453   template <typename P>
00454   inline
00455   const P&
00456   p_run_psite<P>::subj_()
00457   {
00458     return p_;
00459   }
00460 
00461   template <typename P>
00462   inline
00463   p_run_psite<P>::operator util::index() const
00464   {
00465     return i_;
00466   }
00467 
00468   template <typename P>
00469   inline
00470   const p_run<P>&
00471   p_run_psite<P>::run() const
00472   {
00473     mln_precondition(run_ != 0);
00474     return *run_;
00475   }
00476 
00477   namespace trait
00478   {
00479 
00480     template <typename P>
00481     inline
00482     bool
00483     set_precise_unary_< op::ord, p_run<P> >::strict(const p_run<P>& lhs, const p_run<P>& rhs) const
00484     {
00485       return util::ord_strict(lhs.start(), rhs.start());
00486     }
00487 
00488   } // end of namespace trait
00489 
00490 # endif // ! MLN_INCLUDE_ONLY
00491 
00492 } // end of namespace mln
00493 
00494 
00495 # include <mln/core/site_set/p_run_piter.hh>
00496 
00497 
00498 #endif // ! MLN_CORE_SITE_SET_P_RUN_HH

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