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