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_ARRAY_HH
00027 # define MLN_CORE_SITE_SET_P_ARRAY_HH
00028
00039
00040 # include <vector>
00041
00042 # include <mln/core/internal/site_set_base.hh>
00043 # include <mln/core/internal/site_set_iterator_base.hh>
00044 # include <mln/core/internal/pseudo_site_base.hh>
00045 # include <mln/util/index.hh>
00046
00047
00048 namespace mln
00049 {
00050
00051
00052 template <typename P> class p_array;
00053
00054 template <typename S> class p_indexed_psite;
00055 template <typename S> struct p_indexed_fwd_piter;
00056 template <typename S> struct p_indexed_bkd_piter;
00057
00058
00059
00060 namespace trait
00061 {
00062
00063 template <typename P>
00064 struct site_set_< p_array<P> >
00065 {
00066 typedef trait::site_set::nsites::known nsites;
00067 typedef trait::site_set::bbox::unknown bbox;
00068 typedef trait::site_set::contents::growing contents;
00069 typedef trait::site_set::arity::multiple arity;
00070 };
00071
00072 }
00073
00074
00075
00081
00082 template <typename P>
00083 class p_array : public internal::site_set_base_< P, p_array<P> >
00084 {
00085 typedef p_array<P> self_;
00086 public:
00087 typedef typename std::vector<P>::size_type size_type;
00088
00090 typedef P element;
00091
00093 typedef p_indexed_psite<self_> psite;
00094
00096 typedef p_indexed_fwd_piter<self_> fwd_piter;
00097
00099 typedef p_indexed_bkd_piter<self_> bkd_piter;
00100
00102 typedef fwd_piter piter;
00103
00104
00106 p_array();
00107
00109 p_array(const std::vector<P>& vect);
00110
00111
00113 void reserve(size_type n);
00114
00115
00117 bool has(const psite& p) const;
00118
00120 bool has(const util::index& i) const;
00121
00123 bool is_valid() const;
00124
00125
00127 void change(const psite& p, const P& new_p);
00128
00130 unsigned nsites() const;
00131
00132
00134 p_array<P>& append(const P& p);
00135
00137 p_array<P>& append(const p_array<P>& other);
00138
00140 typedef P i_element;
00141
00143 void insert(const P& p);
00144
00146 void clear();
00147
00149 void resize(size_t size);
00150
00151
00153 const P& operator[](unsigned i) const;
00154
00156 P& operator[](unsigned i);
00157
00159 const P& operator[](const util::index& i) const;
00160
00161
00162
00164 std::size_t memory_size() const;
00165
00167 const std::vector<P>& std_vector() const;
00168
00170 std::vector<P>& hook_std_vector_();
00171
00172 protected:
00173
00174 std::vector<P> vect_;
00175 };
00176
00177
00178
00181 template <typename S>
00182 class p_indexed_psite : public internal::pseudo_site_base_< const mln_element(S)&,
00183 p_indexed_psite<S> >
00184 {
00185 public:
00186
00187 typedef mln_element(S) element;
00188
00189
00190
00191 typedef S target;
00192
00193 typedef S target_t;
00194
00195
00196
00197 const element& subj_();
00198
00199
00200
00201 p_indexed_psite();
00202
00203 p_indexed_psite(const S& s, int i);
00204
00205 const util::index& index() const;
00206
00207 void change_index(int i);
00208 void inc_index();
00209 void dec_index();
00210
00211 const S* target_() const;
00212 void change_target(const S& newtarget);
00213
00214 bool is_valid() const;
00215
00216 operator util::index() const;
00217 operator int() const;
00218 operator unsigned() const;
00219
00220 void update_() const;
00221
00222 private:
00223
00224 const S* s_;
00225 util::index i_;
00226 mutable element p_;
00227 };
00228
00229
00230
00232
00233 template <typename S>
00234 class p_indexed_fwd_piter
00235 :
00236 public internal::site_set_iterator_base< S,
00237 p_indexed_fwd_piter<S> >
00238 {
00239 typedef p_indexed_fwd_piter<S> self;
00240 typedef internal::site_set_iterator_base<S, self> super;
00241
00242 public:
00243
00245 p_indexed_fwd_piter();
00246
00248 p_indexed_fwd_piter(const S& s);
00249
00251 bool is_valid_() const;
00252
00254 void invalidate_();
00255
00257 void start_();
00258
00260 void next_();
00261
00263 int index() const;
00264
00265 protected:
00266 using super::p_;
00267 using super::s_;
00268 };
00269
00270
00271
00273
00274 template <typename S>
00275 class p_indexed_bkd_piter
00276 :
00277 public internal::site_set_iterator_base< S,
00278 p_indexed_bkd_piter<S> >
00279 {
00280 typedef p_indexed_bkd_piter<S> self;
00281 typedef internal::site_set_iterator_base<S, self> super;
00282
00283 public:
00284
00286 p_indexed_bkd_piter();
00287
00289 p_indexed_bkd_piter(const S& s);
00290
00292 bool is_valid_() const;
00293
00295 void invalidate_();
00296
00298 void start_();
00299
00301 void next_();
00302
00304 int index() const;
00305
00306 protected:
00307 using super::p_;
00308 using super::s_;
00309 };
00310
00311
00312
00313
00314
00315 template <typename P, typename S>
00316 int index_of_in(const P&, const S&);
00317
00318 template <typename S>
00319 int index_of_in(const p_indexed_psite<S>& p, const S& s);
00320
00321 template <typename S, typename A>
00322 int index_of_in(const p_indexed_psite<S>& p, const A& a);
00323
00324 template <typename S, typename A>
00325 int index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr);
00326
00327 template <typename S, typename A>
00328 int index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr);
00329
00330
00331
00332 # ifndef MLN_INCLUDE_ONLY
00333
00334
00335
00336
00337 template <typename P>
00338 inline
00339 p_array<P>::p_array()
00340 {
00341 }
00342
00343 template <typename P>
00344 inline
00345 p_array<P>::p_array(const std::vector<P>& vect)
00346 : vect_(vect)
00347 {
00348 }
00349
00350 template <typename P>
00351 inline
00352 void
00353 p_array<P>::reserve(size_type n)
00354 {
00355 vect_.reserve(n);
00356 }
00357
00358 template <typename P>
00359 inline
00360 bool
00361 p_array<P>::has(const psite& p) const
00362 {
00363 mln_precondition(p.target_() == this);
00364 if (! has(p.index()))
00365 return false;
00366
00367 mln_invariant(p == static_cast<P>((*this)[p.index()]));
00368 return true;
00369 }
00370
00371 template <typename P>
00372 inline
00373 bool
00374 p_array<P>::has(const util::index& i) const
00375 {
00376 return i >= 0 && unsigned(i) < nsites();
00377 }
00378
00379 template <typename P>
00380 inline
00381 bool
00382 p_array<P>::is_valid() const
00383 {
00384 return true;
00385 }
00386
00387 template <typename P>
00388 inline
00389 const P&
00390 p_array<P>::operator[](const util::index& i) const
00391 {
00392 mln_precondition(has(i));
00393 return vect_[i];
00394 }
00395
00396 template <typename P>
00397 inline
00398 unsigned
00399 p_array<P>::nsites() const
00400 {
00401 return vect_.size();
00402 }
00403
00404 template <typename P>
00405 inline
00406 p_array<P>&
00407 p_array<P>::append(const P& p)
00408 {
00409 vect_.push_back(p);
00410 return *this;
00411 }
00412
00413 template <typename P>
00414 inline
00415 void
00416 p_array<P>::insert(const P& p)
00417 {
00418 vect_.push_back(p);
00419 }
00420
00421 template <typename P>
00422 inline
00423 p_array<P>&
00424 p_array<P>::append(const p_array<P>& other)
00425 {
00426 vect_.insert(vect_.end(),
00427 other.std_vector().begin(),
00428 other.std_vector().end());
00429 return *this;
00430 }
00431
00432 template <typename P>
00433 inline
00434 void
00435 p_array<P>::clear()
00436 {
00437 vect_.clear();
00438 mln_postcondition(this->is_empty());
00439 }
00440
00441 template <typename P>
00442 inline
00443 void
00444 p_array<P>::resize(size_t size)
00445 {
00446 mln_precondition(size >= 0);
00447 vect_.resize(size);
00448 }
00449
00450 template <typename P>
00451 inline
00452 const P&
00453 p_array<P>::operator[](unsigned i) const
00454 {
00455 mln_precondition(i < nsites());
00456 return vect_[i];
00457 }
00458
00459 template <typename P>
00460 inline
00461 P&
00462 p_array<P>::operator[](unsigned i)
00463 {
00464 mln_precondition(i < nsites());
00465 return vect_[i];
00466 }
00467
00468 template <typename P>
00469 inline
00470 void
00471 p_array<P>::change(const psite& p, const P& new_p)
00472 {
00473 mln_precondition(has(p));
00474 vect_[p.index()] = new_p;
00475 }
00476
00477 template <typename P>
00478 inline
00479 std::size_t
00480 p_array<P>::memory_size() const
00481 {
00482 return sizeof(*this) + nsites() * sizeof(P);
00483 }
00484
00485 template <typename P>
00486 inline
00487 const std::vector<P>&
00488 p_array<P>::std_vector() const
00489 {
00490 return vect_;
00491 }
00492
00493 template <typename P>
00494 inline
00495 std::vector<P>&
00496 p_array<P>::hook_std_vector_()
00497 {
00498 return vect_;
00499 }
00500
00501
00502
00503
00504
00505 template <typename S>
00506 inline
00507 p_indexed_psite<S>::p_indexed_psite()
00508 : s_(0),
00509 i_(0)
00510 {
00511 }
00512
00513 template <typename S>
00514 inline
00515 p_indexed_psite<S>::p_indexed_psite(const S& s, int i)
00516 : s_(& s),
00517 i_(i)
00518 {
00519 update_();
00520 }
00521
00522 template <typename S>
00523 inline
00524 const util::index&
00525 p_indexed_psite<S>::index() const
00526 {
00527 return i_;
00528 }
00529
00530 template <typename S>
00531 inline
00532 void
00533 p_indexed_psite<S>::change_index(int i)
00534 {
00535 i_ = i;
00536 update_();
00537 }
00538
00539 template <typename S>
00540 inline
00541 void
00542 p_indexed_psite<S>::dec_index()
00543 {
00544 --i_;
00545 update_();
00546 }
00547
00548 template <typename S>
00549 inline
00550 void
00551 p_indexed_psite<S>::inc_index()
00552 {
00553 ++i_;
00554 update_();
00555 }
00556
00557 template <typename S>
00558 inline
00559 void
00560 p_indexed_psite<S>::change_target(const S& newtarget)
00561 {
00562 s_ = & newtarget;
00563 i_ = -1;
00564 }
00565
00566 template <typename S>
00567 inline
00568 bool
00569 p_indexed_psite<S>::is_valid() const
00570 {
00571 return s_ != 0 && s_->has(i_);
00572 }
00573
00574 template <typename S>
00575 inline
00576 const S*
00577 p_indexed_psite<S>::target_() const
00578 {
00579 return s_;
00580 }
00581
00582 template <typename S>
00583 inline
00584 const mln_element(S)&
00585 p_indexed_psite<S>::subj_()
00586 {
00587 if (is_valid())
00588 mln_invariant(p_ == (*s_)[i_]);
00589 return p_;
00590 }
00591
00592 template <typename S>
00593 inline
00594 void
00595 p_indexed_psite<S>::update_() const
00596 {
00597 if (is_valid())
00598 p_ = (*s_)[i_];
00599 }
00600
00601 template <typename S>
00602 inline
00603 p_indexed_psite<S>::operator util::index() const
00604 {
00605 return i_;
00606 }
00607
00608 template <typename S>
00609 inline
00610 p_indexed_psite<S>::operator int() const
00611 {
00612 return i_;
00613 }
00614
00615 template <typename S>
00616 inline
00617 p_indexed_psite<S>::operator unsigned() const
00618 {
00619 mln_precondition(i_ >= 0);
00620 return i_;
00621 }
00622
00623
00624
00625
00626 template <typename S>
00627 inline
00628 p_indexed_fwd_piter<S>::p_indexed_fwd_piter()
00629 {
00630 }
00631
00632 template <typename S>
00633 inline
00634 p_indexed_fwd_piter<S>::p_indexed_fwd_piter(const S& s)
00635 {
00636 this->change_target(s);
00637 }
00638
00639 template <typename S>
00640 inline
00641 bool
00642 p_indexed_fwd_piter<S>::is_valid_() const
00643 {
00644 mln_invariant(p_.index() >= 0);
00645 return p_.index() < int(s_->nsites());
00646 }
00647
00648 template <typename S>
00649 inline
00650 void
00651 p_indexed_fwd_piter<S>::invalidate_()
00652 {
00653 p_.change_index(s_->nsites());
00654 }
00655
00656 template <typename S>
00657 inline
00658 void
00659 p_indexed_fwd_piter<S>::start_()
00660 {
00661 p_.change_index(0);
00662 }
00663
00664 template <typename S>
00665 inline
00666 void
00667 p_indexed_fwd_piter<S>::next_()
00668 {
00669 p_.inc_index();
00670 }
00671
00672 template <typename S>
00673 inline
00674 int
00675 p_indexed_fwd_piter<S>::index() const
00676 {
00677 return p_.index();
00678 }
00679
00680
00681
00682
00683 template <typename S>
00684 inline
00685 p_indexed_bkd_piter<S>::p_indexed_bkd_piter()
00686 {
00687 }
00688
00689 template <typename S>
00690 inline
00691 p_indexed_bkd_piter<S>::p_indexed_bkd_piter(const S& s)
00692 {
00693 this->change_target(s);
00694 }
00695
00696 template <typename S>
00697 inline
00698 bool
00699 p_indexed_bkd_piter<S>::is_valid_() const
00700 {
00701 mln_invariant(p_.index() < int(s_->nsites()));
00702 return p_.index() >= 0;
00703 }
00704
00705 template <typename S>
00706 inline
00707 void
00708 p_indexed_bkd_piter<S>::invalidate_()
00709 {
00710 p_.change_index(-1);
00711 }
00712
00713 template <typename S>
00714 inline
00715 void
00716 p_indexed_bkd_piter<S>::start_()
00717 {
00718 p_.change_index(s_->nsites() - 1);
00719 }
00720
00721 template <typename S>
00722 inline
00723 void
00724 p_indexed_bkd_piter<S>::next_()
00725 {
00726 p_.dec_index();
00727 }
00728
00729 template <typename S>
00730 inline
00731 int
00732 p_indexed_bkd_piter<S>::index() const
00733 {
00734 return p_.index();
00735 }
00736
00737
00738
00739
00740 template <typename P, typename S>
00741 int index_of_in(const P&, const S&)
00742 {
00743 return -1;
00744 }
00745
00746 template <typename S>
00747 int index_of_in(const p_indexed_psite<S>& p, const S& s)
00748 {
00749 if ((void*)(p.target_()) == (void*)(&s))
00750 return p.index();
00751 else
00752 return index_of_in(p.unproxy_(), s);
00753 }
00754
00755 template <typename S, typename A>
00756 int index_of_in(const p_indexed_psite<S>& p, const A& a)
00757 {
00758 return index_of_in(p.unproxy_(), a);
00759 }
00760
00761 template <typename S, typename A>
00762 inline
00763 int
00764 index_of_in(const p_indexed_fwd_piter<S>& p, const A& arr)
00765 {
00766 return index_of_in(p.unproxy_(), arr);
00767 }
00768
00769 template <typename S, typename A>
00770 inline
00771 int
00772 index_of_in(const p_indexed_bkd_piter<S>& p, const A& arr)
00773 {
00774 return index_of_in(p.unproxy_(), arr);
00775 }
00776
00777 # endif // ! MLN_INCLUDE_ONLY
00778
00779 }
00780
00781
00782 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH