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