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
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
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 }
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
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
00191
00192 typedef S target;
00193
00194 typedef S target_t;
00195
00196
00197
00198 const element& subj_();
00199
00200
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;
00219 operator unsigned() const;
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
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
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);
00365 if (! has(p.index()))
00366 return false;
00367
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
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;
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
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
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
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 }
00781
00782
00783 #endif // ! MLN_CORE_SITE_SET_P_ARRAY_HH