• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

site_relative_iterator_base.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
00002 // (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
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       // Allows inherited classes to do extra work while centering.
00113       // Default implementation.
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); // May call some extra code.
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       // p might be also updated since it can hold a pointer towards
00212       // the set it designates, so:
00213       if_possible::change_target(p_, s);
00214       // Last:
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       // Default is no-op, meaning "no extra code".
00236     }
00237 
00238 # endif // ! MLN_INCLUDE_ONLY
00239 
00240   } // end of namespace mln::internal
00241 
00242 } // end of namespace mln
00243 
00244 
00245 #endif // ! MLN_CORE_INTERNAL_SITE_RELATIVE_ITERATOR_BASE_HH

Generated on Tue Oct 4 2011 15:24:27 for Milena (Olena) by  doxygen 1.7.1