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

p_double.hh

00001 // Copyright (C) 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_DOUBLE_HH
00027 # define MLN_CORE_SITE_SET_P_DOUBLE_HH
00028 
00038 # include <mln/core/internal/pseudo_site_base.hh>
00039 # include <mln/core/internal/site_set_iterator_base.hh>
00040 
00041 
00042 namespace mln
00043 {
00044 
00045   // p_double_psite<S,Sp>
00046 
00047   template <typename S, typename Sp>
00048   class p_double_psite : public internal::pseudo_site_base_< const mln_psite(Sp)&,
00049                                                              p_double_psite<S,Sp> >
00050   {
00051   public:
00052 
00053     p_double_psite();
00054 
00055     // Target associated type.
00056     typedef S target;
00057 
00058     const S* target_() const;
00059 
00060     void change_target(const S& newtarget);
00061 
00062     bool is_valid() const;
00063     
00064     unsigned index() const;
00065     const mln_psite(Sp)& p() const;
00066 
00067     void change_i(unsigned i);
00068 
00069     void change_p(const mln_psite(Sp)& p);
00070 
00071     // As a Proxy:
00072     const mln_psite(Sp)& subj_();
00073 
00074   private:
00075 
00076     const target* s_;
00077     mutable unsigned i_;
00078     mutable mln_psite(Sp) p_;
00079   };
00080 
00081 
00082 
00083   // p_double_piter<S,I1,I2>
00084 
00085   template <typename S, typename I1, typename I2>
00086   class p_double_piter
00087     :
00088     public internal::site_set_iterator_base< S,
00089                                              p_double_piter<S,I1,I2> >
00090   {
00091     typedef p_double_piter<S,I1,I2> self_;
00092     typedef internal::site_set_iterator_base<S,self_> super_;
00093   public:
00094 
00096     p_double_piter();
00097 
00099     p_double_piter(const S& s);
00100 
00102     void change_target(const S& newtarget);
00103 
00105     bool is_valid_() const;
00106 
00108     void invalidate_();
00109 
00111     void start_();
00112 
00114     void next_();
00115 
00116   protected:
00117     using super_::p_;
00118     using super_::s_;
00119 
00120   private:
00121     I1 i1_;
00122     I2 i2_;
00123 
00124     // Progress to the next valid state if it exists.
00125     void progress_();
00126 
00127   };
00128 
00129 
00130 
00131 # ifndef MLN_INCLUDE_ONLY
00132 
00133 
00134   // p_double_psite<S,Sp>
00135 
00136   template <typename S, typename Sp>
00137   inline
00138   p_double_psite<S,Sp>::p_double_psite()
00139   {
00140   }
00141 
00142   template <typename S, typename Sp>
00143   inline
00144   const mln_psite(Sp)&
00145   p_double_psite<S,Sp>::subj_()
00146   {
00147     return p_;
00148   }
00149   
00150   template <typename S, typename Sp>
00151   inline
00152   const S*
00153   p_double_psite<S,Sp>::target_() const
00154   {
00155     return s_;
00156   }
00157 
00158   template <typename S, typename Sp>
00159   inline
00160   void
00161   p_double_psite<S,Sp>::change_target(const S& s)
00162   {
00163     s_ = & s;
00164   }
00165 
00166   template <typename S, typename Sp>
00167   inline
00168   bool
00169   p_double_psite<S,Sp>::is_valid() const
00170   {
00171     return s_ != 0 && p_.is_valid();
00172   }
00173 
00174   template <typename S, typename Sp>
00175   inline
00176   unsigned
00177   p_double_psite<S,Sp>::index() const
00178   {
00179     return i_;
00180   }
00181 
00182   template <typename S, typename Sp>
00183   inline
00184   const mln_psite(Sp)&
00185   p_double_psite<S,Sp>::p() const
00186   {
00187     return p_;
00188   }
00189 
00190   template <typename S, typename Sp>
00191   inline
00192   void
00193   p_double_psite<S,Sp>::change_i(unsigned i)
00194   {
00195     i_ = i;
00196   }
00197   
00198   template <typename S, typename Sp>
00199   inline
00200   void
00201   p_double_psite<S,Sp>::change_p(const mln_psite(Sp)& p)
00202   {
00203     p_ = p;
00204   }
00205 
00206 
00207   // p_double_piter<S,I1,I2>
00208 
00209   template <typename S, typename I1, typename I2>
00210   inline
00211   p_double_piter<S,I1,I2>::p_double_piter()
00212   {
00213   }
00214 
00215   template <typename S, typename I1, typename I2>
00216   inline
00217   p_double_piter<S,I1,I2>::p_double_piter(const S& s)
00218   {
00219     this->change_target(s);
00220   }
00221 
00222   template <typename S, typename I1, typename I2>
00223   inline
00224   void
00225   p_double_piter<S,I1,I2>::change_target(const S& newtarget)
00226   {
00227     this->super_::change_target(newtarget);
00228     i1_.change_target(newtarget.set_1_());
00229     invalidate_();
00230   }
00231 
00232   template <typename S, typename I1, typename I2>
00233   inline
00234   bool
00235   p_double_piter<S,I1,I2>::is_valid_() const
00236   {
00237     return i2_.is_valid();
00238   }
00239 
00240   template <typename S, typename I1, typename I2>
00241   inline
00242   void
00243   p_double_piter<S,I1,I2>::invalidate_()
00244   {
00245     i2_.invalidate();
00246   }
00247 
00248   template <typename S, typename I1, typename I2>
00249   inline
00250   void
00251   p_double_piter<S,I1,I2>::start_()
00252   {
00253     i1_.start();
00254     if (i1_.is_valid())
00255       {
00256         i2_.change_target(s_->set_2_(i1_));
00257         i2_.start();
00258         if (! i2_.is_valid())
00259           progress_();
00260         else
00261           {
00262             p_.change_i(i1_.index_());
00263             p_.change_p(i2_);
00264           }
00265       }
00266     else
00267       i2_.invalidate();
00268     mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
00269   }
00270 
00271   template <typename S, typename I1, typename I2>
00272   inline
00273   void
00274   p_double_piter<S,I1,I2>::next_()
00275   {
00276     i2_.next();
00277     if (! i2_.is_valid())
00278       progress_();
00279     else
00280       p_.change_p(i2_);
00281     mln_postcondition(implies(i2_.is_valid(), i1_.is_valid()));
00282   }
00283 
00284   template <typename S, typename I1, typename I2>
00285   inline
00286   void
00287   p_double_piter<S,I1,I2>::progress_()
00288   {
00289     // This routine is general; it does not make the assumption that
00290     // the site set type features is_empty().
00291     while (! i2_.is_valid() && i1_.is_valid())
00292       {
00293         i1_.next();
00294         if (! i1_.is_valid())
00295           {
00296             // End of iterations.
00297             i2_.invalidate(); // Safety.
00298             return;
00299           }
00300         i2_.change_target(s_->set_2_(i1_));
00301         i2_.start();
00302       }
00303     if (i2_.is_valid())
00304       {
00305         p_.change_i(i1_.index_());
00306         p_.change_p(i2_);
00307       }
00308   }
00309 
00310 # endif // ! MLN_INCLUDE_ONLY
00311 
00312 } // end of namespace mln
00313 
00314 
00315 #endif // ! MLN_CORE_SITE_SET_P_DOUBLE_HH

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