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_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH
00028 # define MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH
00029 
00037 
00038 
00039 # include <vector>
00040 # include <mln/core/internal/site_iterator_base.hh>
00041 # include <mln/metal/converts_to.hh>
00042 
00043 
00044 namespace mln
00045 {
00046 
00047   namespace internal
00048   {
00049 
00060     template <typename S, typename E, typename C = mln_psite(S)>
00061     class site_relative_iterator_base : public site_iterator_base< S, E >
00062     {
00063     public:
00064 
00066       site_relative_iterator_base();
00067 
00068       template <typename P>
00069       void center_at(const P& c);
00070 
00072       void start_();
00073 
00075       void next_();
00076 
00079       const S& site_set() const;
00080 
00082       const C& center() const;
00083 
00089       const mln_psite(S)& subj_();
00090 
00092       const mln_psite(S)& p_hook_() const;
00093 
00095       void change_target(const S& s);
00096 
00102       E& update();
00103 
00104     protected:
00105 
00108       const C* c_;
00109 
00110     private:
00111 
00112       
00113       
00114       template <typename P>
00115       void center_at_(const P& c);
00116 
00118       mln_psite(S) p_;
00119     };
00120 
00121 
00122 
00123 # ifndef MLN_INCLUDE_ONLY
00124 
00125     template <typename S, typename E, typename C>
00126     inline
00127     site_relative_iterator_base<S,E,C>::site_relative_iterator_base()
00128       : c_(0)
00129     {
00130       void (E::*m1)() = & E::do_start_;
00131       m1 = 0;
00132       void (E::*m2)() = & E::do_next_;
00133       m2 = 0;
00134       mln_psite(S) (E::*m3)() const = & E::compute_p_;
00135       m3 = 0;
00136     }
00137 
00138     template <typename S, typename E, typename C>
00139     template <typename P>
00140     inline
00141     void
00142     site_relative_iterator_base<S,E,C>::center_at(const P& c)
00143     {
00144       mlc_converts_to(P, const C&)::check();
00145       c_ = & static_cast< const C& >(c);
00146       exact(this)->center_at_(c); 
00147       this->invalidate();
00148     }
00149 
00150     template <typename S, typename E, typename C>
00151     inline
00152     void
00153     site_relative_iterator_base<S,E,C>::start_()
00154     {
00155       exact(this)->do_start_();
00156       if (this->is_valid())
00157         p_ = exact(this)->compute_p_();
00158     }
00159 
00160     template <typename S, typename E, typename C>
00161     inline
00162     void
00163     site_relative_iterator_base<S,E,C>::next_()
00164     {
00165       exact(this)->do_next_();
00166       if (this->is_valid())
00167         p_ = exact(this)->compute_p_();
00168     }
00169 
00170     template <typename S, typename E, typename C>
00171     inline
00172     const C&
00173     site_relative_iterator_base<S,E,C>::center() const
00174     {
00175       mln_precondition(c_ != 0);
00176       return *c_;
00177     }
00178 
00179     template <typename S, typename E, typename C>
00180     inline
00181     const S&
00182     site_relative_iterator_base<S,E,C>::site_set() const
00183     {
00184       mln_precondition(this->s_ != 0);
00185       return *this->s_;
00186     }
00187 
00188     template <typename S, typename E, typename C>
00189     inline
00190     const mln_psite(S)&
00191     site_relative_iterator_base<S,E,C>::subj_()
00192     {
00193       mln_assertion(exact(this)->compute_p_() == p_);
00194       return p_;
00195     }
00196 
00197     template <typename S, typename E, typename C>
00198     inline
00199     const mln_psite(S)&
00200     site_relative_iterator_base<S,E,C>::p_hook_() const
00201     {
00202       return p_;
00203     }
00204 
00205     template <typename S, typename E, typename C>
00206     inline
00207     void
00208     site_relative_iterator_base<S,E,C>::change_target(const S& s)
00209     {
00210       this->s_ = & s;
00211       
00212       
00213       if_possible::change_target(p_, s);
00214       
00215       this->invalidate();
00216     }
00217 
00218     template <typename S, typename E, typename C>
00219     inline
00220     E&
00221     site_relative_iterator_base<S,E,C>::update()
00222     {
00223       mln_precondition(this->s_ && c_);
00224       p_ = exact(this)->compute_p_();
00225       mln_postcondition(this->is_valid());
00226       return exact(*this);
00227     }
00228 
00229     template <typename S, typename E, typename C>
00230     template <typename P>
00231     inline
00232     void
00233     site_relative_iterator_base<S,E,C>::center_at_(const P&)
00234     {
00235       
00236     }
00237 
00238 # endif // ! MLN_INCLUDE_ONLY
00239 
00240   } 
00241 
00242 } 
00243 
00244 
00245 #endif // ! MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH