Milena (Olena)
User documentation 2.0a Id
|
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