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

graph_psite_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_GRAPH_PSITE_BASE_HH
00028 # define MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
00029 
00036 
00037 # include <mln/core/internal/pseudo_site_base.hh>
00038 
00039 
00040 
00041 namespace mln
00042 {
00043 
00044   namespace internal
00045   {
00046 
00047     template <typename S, typename E>
00048     class graph_psite_base : public internal::pseudo_site_base_< const mln_site(S)&,
00049                                                                  E >
00050     {
00051     public:
00052 
00053       // This associated type is important to know that this particular
00054       // pseudo site knows the site set it refers to.
00055       typedef S target;
00056 
00057       // As a Proxy:
00058       const mln_site(S)& subj_();
00059 
00060       typedef typename S::graph_element::id_t id_t;
00061 
00065       void change_target(const S& new_target);
00068       void update_id(unsigned elt_id);
00070 
00074       const S* target_() const; // Hook to the target.
00075 
00077       const S& site_set() const;
00078 
00080       const typename S::graph_t& graph() const;
00081 
00083       id_t id() const;
00084 
00086 
00088       bool is_valid() const;
00090       void invalidate();
00091 
00093       operator unsigned () const;
00094 
00096       operator typename S::graph_element::id_t () const;
00097 
00099       operator const typename S::graph_element&() const;
00100 
00102       const typename S::graph_element& element() const;
00103 
00105       const typename S::graph_element& p_hook_() const;
00106 
00107     protected:
00108 
00110 
00112       graph_psite_base();
00115       graph_psite_base(const S& s);
00119       graph_psite_base(const S& , unsigned id);
00121 
00122       const S* s_;
00123       mln_site(S) site_;
00124       typename S::graph_element elt_;
00125     };
00126 
00127 
00128     /* FIXME: Shouldn't those comparisons be part of a much general
00129        mechanism?  */
00130 
00137     template <typename S, typename E>
00138     bool
00139     operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00140 
00145     template <typename S, typename E>
00146     bool
00147     operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00148 
00155     template <typename S, typename E>
00156     bool
00157     operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00159 
00160 
00163     template <typename S, typename P, typename E>
00164     struct subject_impl< const graph_psite_base<S,P>&, E >
00165     {
00166       const S* target_() const;
00167       const S& site_set() const;
00168       const typename S::graph_t& graph() const;
00169       unsigned id() const;
00170       bool is_valid() const;
00171       //    operator unsigned() const;
00172       //    operator const typename S::graph_element&() const;
00173       const typename S::graph_element& element() const;
00174       const typename S::graph_element& p_hook_() const;
00175 
00176     private:
00177       const E& exact_() const;
00178     };
00179 
00180     template <typename S, typename P, typename E>
00181     struct subject_impl<       graph_psite_base<S,P>&, E > :
00182       subject_impl< const graph_psite_base<S,P>&, E >
00183     {
00184       void change_target(const S& new_target);
00185       void update_id(unsigned elt_id);
00186       void invalidate();
00187 
00188     private:
00189       E& exact_();
00190     };
00192 
00193 
00194 
00195 # ifndef MLN_INCLUDE_ONLY
00196 
00197 
00198     template <typename S, typename E>
00199     inline
00200     graph_psite_base<S,E>::graph_psite_base()
00201       : s_(0)
00202     {
00203     }
00204 
00205     template <typename S, typename E>
00206     inline
00207     graph_psite_base<S,E>::graph_psite_base(const S& s)
00208     {
00209       change_target(s);
00210     }
00211 
00212     template <typename S, typename E>
00213     inline
00214     graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
00215     {
00216       change_target(s);
00217       update_id(id);
00218     }
00219 
00220     // The lines below are dedicated/local to this file.
00221     template <typename E, typename S, typename G>
00222     inline
00223     void local_change_graph(E& elt_, S& site_, const G& g)
00224     {
00225       (void) site_;
00226       elt_.change_graph(g);
00227     }
00228     template <typename E, typename G>
00229     inline
00230     void local_change_graph(E& elt_, E& site_, const G& g)
00231     {
00232       elt_.change_graph(g);
00233       site_.change_graph(g);
00234     }
00235     // End of local stuff.
00236 
00237     template <typename S, typename E>
00238     inline
00239     void
00240     graph_psite_base<S,E>::change_target(const S& new_target)
00241     {
00242       s_ = & new_target;
00243       local_change_graph(elt_, site_, new_target.graph());
00244     }
00245 
00246     template <typename S, typename E>
00247     inline
00248     void
00249     graph_psite_base<S,E>::update_id(unsigned id)
00250     {
00251       mln_precondition(s_ != 0);
00252       elt_.update_id(id);
00253       site_ = s_->function()(elt_.id());
00254     }
00255 
00256     template <typename S, typename E>
00257     inline
00258     const S*
00259     graph_psite_base<S,E>::target_() const
00260     {
00261       return s_;
00262     }
00263 
00264     template <typename S, typename E>
00265     inline
00266     const S&
00267     graph_psite_base<S,E>::site_set() const
00268     {
00269       mln_precondition(s_ != 0);
00270       return *s_;
00271     }
00272 
00273     template <typename S, typename E>
00274     inline
00275     const typename S::graph_t&
00276     graph_psite_base<S,E>::graph() const
00277     {
00278       mln_precondition(s_ != 0);
00279       return s_->graph();
00280     }
00281 
00282     template <typename S, typename E>
00283     inline
00284     typename graph_psite_base<S,E>::id_t
00285     graph_psite_base<S,E>::id() const
00286     {
00287       return elt_.id();
00288     }
00289 
00290     template <typename S, typename E>
00291     inline
00292     bool
00293     graph_psite_base<S,E>::is_valid() const
00294     {
00295       return s_ != 0 && s_->is_valid() && elt_.is_valid();
00296     }
00297 
00298     template <typename S, typename E>
00299     inline
00300     void
00301     graph_psite_base<S,E>::invalidate()
00302     {
00303       s_ = 0;
00304       elt_.invalidate();
00305     }
00306 
00307     template <typename S, typename E>
00308     inline
00309     const mln_site(S)&
00310     graph_psite_base<S,E>::subj_()
00311     {
00312       /*FIXME: we may like to enable the following precondition, however, we
00313       ** can't do that since neighb_*_niters update the psite target after having
00314       ** taken the adress of the subject.
00315       */
00316       // mln_precondition(is_valid());
00317       return site_;
00318     }
00319 
00320     template <typename S, typename E>
00321     inline
00322     graph_psite_base<S,E>::operator unsigned () const
00323     {
00324       mln_precondition(is_valid());
00325       return elt_.id();
00326     }
00327 
00328     template <typename S, typename E>
00329     inline
00330     graph_psite_base<S,E>::operator typename S::graph_element::id_t () const
00331     {
00332       mln_precondition(is_valid());
00333       return elt_.id();
00334     }
00335 
00336     template <typename S, typename E>
00337     inline
00338     graph_psite_base<S,E>::operator const typename S::graph_element&() const
00339     {
00340       //mln_precondition(is_valid());
00341       return elt_;
00342     }
00343 
00344     template <typename S, typename E>
00345     inline
00346     const typename S::graph_element&
00347     graph_psite_base<S,E>::element() const
00348     {
00349       /*FIXME: we may like to enable the following precondition, however, we
00350       ** can't do that since neighb_*_niters update the psite target after having
00351       ** taken the adress of the subject.
00352       */
00353       // mln_precondition(is_valid());
00354       return elt_;
00355     }
00356 
00357     template <typename S, typename E>
00358     inline
00359     const typename S::graph_element&
00360     graph_psite_base<S,E>::p_hook_() const
00361     {
00362       return elt_;
00363     }
00364 
00365 
00366     template <typename S, typename P, typename E>
00367     inline
00368     const E&
00369     subject_impl< const graph_psite_base<S,P>&, E >::exact_() const
00370     {
00371       return internal::force_exact<const E>(*this);
00372     }
00373 
00374     template <typename S, typename P, typename E>
00375     inline
00376     const S*
00377     subject_impl< const graph_psite_base<S,P>&, E >::target_() const
00378     {
00379       return exact_().get_subject().target();
00380     }
00381 
00382     template <typename S, typename P, typename E>
00383     inline
00384     const S&
00385     subject_impl< const graph_psite_base<S,P>&, E >::site_set() const
00386     {
00387       return exact_().get_subject().site_set();
00388     }
00389 
00390 
00391     template <typename S, typename P, typename E>
00392     inline
00393     const typename S::graph_t&
00394     subject_impl< const graph_psite_base<S,P>&, E >::graph() const
00395     {
00396       return exact_().get_subject().graph();
00397     }
00398 
00399     template <typename S, typename P, typename E>
00400     inline
00401     unsigned
00402     subject_impl< const graph_psite_base<S,P>&, E >::id() const
00403     {
00404       return exact_().get_subject().id();
00405     };
00406 
00407     template <typename S, typename P, typename E>
00408     inline
00409     bool
00410     subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const
00411     {
00412       return exact_().get_subject().is_valid();
00413     }
00414 
00415     template <typename S, typename P, typename E>
00416     inline
00417     const typename S::graph_element&
00418     subject_impl< const graph_psite_base<S,P>&, E >::element() const
00419     {
00420       return exact_().get_subject().element();
00421     }
00422 
00423     template <typename S, typename P, typename E>
00424     inline
00425     const typename S::graph_element&
00426     subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const
00427     {
00428       return exact_().get_subject().p_hook_();
00429     }
00430 
00431 
00432     template <typename S, typename P, typename E>
00433     inline
00434     E&
00435     subject_impl<       graph_psite_base<S,P>&, E >::exact_()
00436     {
00437       return internal::force_exact<E>(*this);
00438     }
00439 
00440     template <typename S, typename P, typename E>
00441     inline
00442     void
00443     subject_impl<       graph_psite_base<S,P>&, E >::change_target(const S& new_target)
00444     {
00445       exact_().get_subject().change_target(new_target);
00446     }
00447 
00448     template <typename S, typename P, typename E>
00449     inline
00450     void
00451     subject_impl<       graph_psite_base<S,P>&, E >::update_id(unsigned id)
00452     {
00453       exact_().get_subject().update_id(id);
00454     };
00455 
00456     template <typename S, typename P, typename E>
00457     inline
00458     void
00459     subject_impl<       graph_psite_base<S,P>&, E >::invalidate()
00460     {
00461       exact_().get_subject().invalidate();
00462     }
00463 
00464 # endif // ! MLN_INCLUDE_ONLY
00465 
00466   } // end of namespace internal
00467 
00468 } // end of namespace mln
00469 
00470 
00471 #endif // ! MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH

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