00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
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   
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     
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     
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   
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     
00125     void progress_();
00126 
00127   };
00128 
00129 
00130 
00131 # ifndef MLN_INCLUDE_ONLY
00132 
00133 
00134   
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   
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     
00290     
00291     while (! i2_.is_valid() && i1_.is_valid())
00292       {
00293         i1_.next();
00294         if (! i1_.is_valid())
00295           {
00296             
00297             i2_.invalidate(); 
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 } 
00313 
00314 
00315 #endif // ! MLN_CORE_SITE_SET_P_DOUBLE_HH