Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2007, 2008, 2009, 2010, 2011 EPITA Research and 00002 // Development Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_CORE_SITE_SET_P_ARRAY_HH 00028 # define MLN_CORE_SITE_SET_P_ARRAY_HH 00029 00040 00041 # include <vector> 00042 00043 # include <mln/core/internal/site_set_base.hh> 00044 # include <mln/core/internal/site_set_iterator_base.hh> 00045 # include <mln/core/internal/pseudo_site_base.hh> 00046 # include <mln/util/index.hh> 00047 00048 00049 namespace mln 00050 { 00051 00052 // Forward declarations. 00053 template <typename P> class p_array; 00054 00055 template <typename S> class p_indexed_psite; 00056 template <typename S> class p_indexed_fwd_piter; 00057 template <typename S> class p_indexed_bkd_piter; 00058 00059 00060 00061 namespace trait 00062 { 00063 00064 template <typename P> 00065 struct site_set_< p_array<P> > 00066 { 00067 typedef trait::site_set::nsites::known nsites; 00068 typedef trait::site_set::bbox::unknown bbox; 00069 typedef trait::site_set::contents::growing contents; 00070 typedef trait::site_set::arity::multiple arity; 00071 }; 00072 00073 } // end of namespace trait 00074 00075 00076 00082 // 00083 template <typename P> 00084 class p_array : public internal::site_set_base_< P, p_array<P> > 00085 { 00086 typedef p_array<P> self_; 00087 public: 00088 typedef typename std::vector<P>::size_type size_type; 00089 00091 typedef P element; 00092 00094 typedef p_indexed_psite<self_> psite; 00095 00097 typedef p_indexed_fwd_piter<self_> fwd_piter; 00098 00100 typedef p_indexed_bkd_piter<self_> bkd_piter; 00101 00103 typedef fwd_piter piter; 00104 00105 00107 p_array(); 00108 00110 p_array(const std::vector<P>& vect); 00111 00112 00114 void reserve(size_type n); 00115 00116 00118 bool has(const psite& p) const; 00119 00121 bool has(const util::index& i) const; 00122 00124 bool is_valid() const; 00125 00126 00128 void change(const psite& p, const P& new_p); 00129 00131 unsigned nsites() const; 00132 00133 00135 p_array<P>& append(const P& p); 00136 00138 p_array<P>& append(const p_array<P>& other); 00139 00141 typedef P i_element; 00142 00144 void insert(const P& p); 00145 00147 void clear(); 00148 00150 void resize(size_t size); 00151 00152 00154 const P& operator[](unsigned i) const; 00155 00157 P& operator[](unsigned i); 00158 00160 const P& operator[](const util::index& i) const; 00161 // FIXME: Is-it useful? (redundant with 'int'?) 00162 00163 00165 std::size_t memory_size() const; 00166 00168 const std::vector<P>& std_vector() const; 00169 00171 std::vector<P>& hook_std_vector_(); 00172 00173 protected: 00174 00175 std::vector<P> vect_; 00176 }; 00177 00178 00179 00182 template <typename S> 00183 class p_indexed_psite : public internal::pseudo_site_base_< const mln_element(S)&, 00184 p_indexed_psite<S> > 00185 { 00186 public: 00187 00188 typedef mln_element(S) element; 00189 00190 // This associated type is important to know that this particular 00191 // pseudo site knows the site set it refers to. 00192 typedef S target; 00193 00194 typedef S target_t; // To please g++-2.95. 00195 // Also read the 'todo' in mln/core/concept/pseudo_site.hh. 00196 00197 // As a Proxy: 00198 const element& subj_(); 00199 00200 // As Itself. 00201 00202 p_indexed_psite(); 00203 00204 p_indexed_psite(const S& s, int i); 00205 00206 const util::index& index() const; 00207 00208 void change_index(int i); 00209 void inc_index(); 00210 void dec_index(); 00211 00212 const S* target_() const; 00213 void change_target(const S& newtarget); 00214 00215 bool is_valid() const; 00216 00217 operator util::index() const; 00218 operator int() const; // To interoperate, e.g., with fun::i2v expecting an int. 00219 operator unsigned() const; // To avoid ambiguity when an unsigned is expected. 00220 00221 void update_() const; 00222 00223 private: 00224 00225 const S* s_; 00226 util::index i_; 00227 mutable element p_; 00228 }; 00229 00230 00231 00233 00234 template <typename S> 00235 class p_indexed_fwd_piter 00236 : 00237 public internal::site_set_iterator_base< S, 00238 p_indexed_fwd_piter<S> > 00239 { 00240 typedef p_indexed_fwd_piter<S> self; 00241 typedef internal::site_set_iterator_base<S, self> super; 00242 00243 public: 00244 00246 p_indexed_fwd_piter(); 00247 00249 p_indexed_fwd_piter(const S& s); 00250 00252 bool is_valid_() const; 00253 00255 void invalidate_(); 00256 00258 void start_(); 00259 00261 void next_(); 00262 00264 int index() const; 00265 00266 protected: 00267 using super::p_; 00268 using super::s_; 00269 }; 00270 00271 00272 00274 00275 template <typename S> 00276 class p_indexed_bkd_piter 00277 : 00278 public internal::site_set_iterator_base< S, 00279 p_indexed_bkd_piter<S> > 00280 { 00281 typedef p_indexed_bkd_piter<S> self; 00282 typedef internal::site_set_iterator_base<S, self> super; 00283 00284 public: 00285 00287 p_indexed_bkd_piter(); 00288 00290 p_indexed_bkd_piter(const S& s); 00291 00293 bool is_valid_() const; 00294 00296 void invalidate_(); 00297 00299 void start_(); 00300 00302 void next_(); 00303 00305 int index() const; 00306 00307 protected: 00308 using super::p_; 00309 using super::s_; 00310 }; 00311 00312 00313 00314 // Procedures. 00315 00316 template <typename P, typename S> 00317 int index_of_in(const P&, const S&); 00318 00319 template <typename S> 00320 int index_of_in(const p_indexed_psite<S>& p, const S& s); 00321 00322 template <typename S, typename A> 00323 int index_of_in(const p_indexed_psite<S>& p, const A& a); 00324 00325 template <typename S, typename A> 00326 int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr); 00327 00328 template <typename S, typename A> 00329 int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr); 00330 00331 00332 00333 # ifndef MLN_INCLUDE_ONLY 00334 00335 00336 // p_array<P> 00337 00338 template <typename P> 00339 inline 00340 p_array<P>::p_array() 00341 { 00342 } 00343 00344 template <typename P> 00345 inline 00346 p_array<P>::p_array(const std::vector<P>& vect) 00347 : vect_(vect) 00348 { 00349 } 00350 00351 template <typename P> 00352 inline 00353 void 00354 p_array<P>::reserve(size_type n) 00355 { 00356 vect_.reserve(n); 00357 } 00358 00359 template <typename P> 00360 inline 00361 bool 00362 p_array<P>::has(const psite& p) const 00363 { 00364 mln_precondition(p.target_() == this); // FIXME: Refine. 00365 if (! has(p.index())) 00366 return false; 00367 // The type of rhs below is mln_site(p_array<P>). 00368 mln_invariant(p == static_cast<P>((*this)[p.index()])); 00369 return true; 00370 } 00371 00372 template <typename P> 00373 inline 00374 bool 00375 p_array<P>::has(const util::index& i) const 00376 { 00377 return i >= 0 && unsigned(i) < nsites(); 00378 } 00379 00380 template <typename P> 00381 inline 00382 bool 00383 p_array<P>::is_valid() const 00384 { 00385 return true; 00386 } 00387 00388 template <typename P> 00389 inline 00390 const P& 00391 p_array<P>::operator[](const util::index& i) const 00392 { 00393 mln_precondition(has(i)); 00394 return vect_[i]; 00395 } 00396 00397 template <typename P> 00398 inline 00399 unsigned 00400 p_array<P>::nsites() const 00401 { 00402 return vect_.size(); 00403 } 00404 00405 template <typename P> 00406 inline 00407 p_array<P>& 00408 p_array<P>::append(const P& p) 00409 { 00410 vect_.push_back(p); 00411 return *this; 00412 } 00413 00414 template <typename P> 00415 inline 00416 void 00417 p_array<P>::insert(const P& p) 00418 { 00419 vect_.push_back(p); 00420 } 00421 00422 template <typename P> 00423 inline 00424 p_array<P>& 00425 p_array<P>::append(const p_array<P>& other) 00426 { 00427 vect_.insert(vect_.end(), 00428 other.std_vector().begin(), 00429 other.std_vector().end()); 00430 return *this; 00431 } 00432 00433 template <typename P> 00434 inline 00435 void 00436 p_array<P>::clear() 00437 { 00438 vect_.clear(); 00439 mln_postcondition(this->is_empty()); 00440 } 00441 00442 template <typename P> 00443 inline 00444 void 00445 p_array<P>::resize(size_t size) 00446 { 00447 mln_precondition(size >= 0); 00448 vect_.resize(size); 00449 } 00450 00451 template <typename P> 00452 inline 00453 const P& 00454 p_array<P>::operator[](unsigned i) const 00455 { 00456 mln_precondition(i < nsites()); 00457 return vect_[i]; 00458 } 00459 00460 template <typename P> 00461 inline 00462 P& 00463 p_array<P>::operator[](unsigned i) 00464 { 00465 mln_precondition(i < nsites()); 00466 return vect_[i]; 00467 } 00468 00469 template <typename P> 00470 inline 00471 void 00472 p_array<P>::change(const psite& p, const P& new_p) 00473 { 00474 mln_precondition(has(p)); 00475 vect_[p.index()] = new_p; 00476 } 00477 00478 template <typename P> 00479 inline 00480 std::size_t 00481 p_array<P>::memory_size() const 00482 { 00483 return sizeof(*this) + nsites() * sizeof(P); 00484 } 00485 00486 template <typename P> 00487 inline 00488 const std::vector<P>& 00489 p_array<P>::std_vector() const 00490 { 00491 return vect_; 00492 } 00493 00494 template <typename P> 00495 inline 00496 std::vector<P>& 00497 p_array<P>::hook_std_vector_() 00498 { 00499 return vect_; 00500 } 00501 00502 00503 00504 // p_indexed_psite<S> 00505 00506 template <typename S> 00507 inline 00508 p_indexed_psite<S>::p_indexed_psite() 00509 : s_(0), 00510 i_(0) 00511 { 00512 } 00513 00514 template <typename S> 00515 inline 00516 p_indexed_psite<S>::p_indexed_psite(const S& s, int i) 00517 : s_(& s), 00518 i_(i) 00519 { 00520 update_(); 00521 } 00522 00523 template <typename S> 00524 inline 00525 const util::index& 00526 p_indexed_psite<S>::index() const 00527 { 00528 return i_; 00529 } 00530 00531 template <typename S> 00532 inline 00533 void 00534 p_indexed_psite<S>::change_index(int i) 00535 { 00536 i_ = i; 00537 update_(); 00538 } 00539 00540 template <typename S> 00541 inline 00542 void 00543 p_indexed_psite<S>::dec_index() 00544 { 00545 --i_; 00546 update_(); 00547 } 00548 00549 template <typename S> 00550 inline 00551 void 00552 p_indexed_psite<S>::inc_index() 00553 { 00554 ++i_; 00555 update_(); 00556 } 00557 00558 template <typename S> 00559 inline 00560 void 00561 p_indexed_psite<S>::change_target(const S& newtarget) 00562 { 00563 s_ = & newtarget; 00564 i_ = -1; // Invalidate. 00565 } 00566 00567 template <typename S> 00568 inline 00569 bool 00570 p_indexed_psite<S>::is_valid() const 00571 { 00572 return s_ != 0 && s_->has(i_); 00573 } 00574 00575 template <typename S> 00576 inline 00577 const S* 00578 p_indexed_psite<S>::target_() const 00579 { 00580 return s_; 00581 } 00582 00583 template <typename S> 00584 inline 00585 const mln_element(S)& 00586 p_indexed_psite<S>::subj_() 00587 { 00588 if (is_valid()) 00589 mln_invariant(p_ == (*s_)[i_]); 00590 return p_; 00591 } 00592 00593 template <typename S> 00594 inline 00595 void 00596 p_indexed_psite<S>::update_() const 00597 { 00598 if (is_valid()) 00599 p_ = (*s_)[i_]; 00600 } 00601 00602 template <typename S> 00603 inline 00604 p_indexed_psite<S>::operator util::index() const 00605 { 00606 return i_; 00607 } 00608 00609 template <typename S> 00610 inline 00611 p_indexed_psite<S>::operator int() const 00612 { 00613 return i_; 00614 } 00615 00616 template <typename S> 00617 inline 00618 p_indexed_psite<S>::operator unsigned() const 00619 { 00620 mln_precondition(i_ >= 0); 00621 return i_; 00622 } 00623 00624 00625 // p_indexed_fwd_piter<S>. 00626 00627 template <typename S> 00628 inline 00629 p_indexed_fwd_piter<S>::p_indexed_fwd_piter() 00630 { 00631 } 00632 00633 template <typename S> 00634 inline 00635 p_indexed_fwd_piter<S>::p_indexed_fwd_piter(const S& s) 00636 { 00637 this->change_target(s); 00638 } 00639 00640 template <typename S> 00641 inline 00642 bool 00643 p_indexed_fwd_piter<S>::is_valid_() const 00644 { 00645 mln_invariant(p_.index() >= 0); 00646 return p_.index() < int(s_->nsites()); 00647 } 00648 00649 template <typename S> 00650 inline 00651 void 00652 p_indexed_fwd_piter<S>::invalidate_() 00653 { 00654 p_.change_index(s_->nsites()); 00655 } 00656 00657 template <typename S> 00658 inline 00659 void 00660 p_indexed_fwd_piter<S>::start_() 00661 { 00662 p_.change_index(0); 00663 } 00664 00665 template <typename S> 00666 inline 00667 void 00668 p_indexed_fwd_piter<S>::next_() 00669 { 00670 p_.inc_index(); 00671 } 00672 00673 template <typename S> 00674 inline 00675 int 00676 p_indexed_fwd_piter<S>::index() const 00677 { 00678 return p_.index(); 00679 } 00680 00681 00682 // p_indexed_bkd_piter<S>. 00683 00684 template <typename S> 00685 inline 00686 p_indexed_bkd_piter<S>::p_indexed_bkd_piter() 00687 { 00688 } 00689 00690 template <typename S> 00691 inline 00692 p_indexed_bkd_piter<S>::p_indexed_bkd_piter(const S& s) 00693 { 00694 this->change_target(s); 00695 } 00696 00697 template <typename S> 00698 inline 00699 bool 00700 p_indexed_bkd_piter<S>::is_valid_() const 00701 { 00702 mln_invariant(p_.index() < int(s_->nsites())); 00703 return p_.index() >= 0; 00704 } 00705 00706 template <typename S> 00707 inline 00708 void 00709 p_indexed_bkd_piter<S>::invalidate_() 00710 { 00711 p_.change_index(-1); 00712 } 00713 00714 template <typename S> 00715 inline 00716 void 00717 p_indexed_bkd_piter<S>::start_() 00718 { 00719 p_.change_index(s_->nsites() - 1); 00720 } 00721 00722 template <typename S> 00723 inline 00724 void 00725 p_indexed_bkd_piter<S>::next_() 00726 { 00727 p_.dec_index(); 00728 } 00729 00730 template <typename S> 00731 inline 00732 int 00733 p_indexed_bkd_piter<S>::index() const 00734 { 00735 return p_.index(); 00736 } 00737 00738 00739 // Procedures 00740 00741 template <typename P, typename S> 00742 int index_of_in(const P&, const S&) 00743 { 00744 return -1; 00745 } 00746 00747 template <typename S> 00748 int index_of_in(const p_indexed_psite<S>& p, const S& s) 00749 { 00750 if ((void*)(p.target_()) == (void*)(&s)) 00751 return p.index(); 00752 else 00753 return index_of_in(p.unproxy_(), s); 00754 } 00755 00756 template <typename S, typename A> 00757 int index_of_in(const p_indexed_psite<S>& p, const A& a) 00758 { 00759 return index_of_in(p.unproxy_(), a); 00760 } 00761 00762 template <typename S, typename A> 00763 inline 00764 int 00765 index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr) 00766 { 00767 return index_of_in(p.unproxy_(), arr); 00768 } 00769 00770 template <typename S, typename A> 00771 inline 00772 int 00773 index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr) 00774 { 00775 return index_of_in(p.unproxy_(), arr); 00776 } 00777 00778 # endif // ! MLN_INCLUDE_ONLY 00779 00780 } // end of namespace mln 00781 00782 00783 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH