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