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