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

graph_psite_base.hh

00001 // Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
00027 # define MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH
00028 
00035 
00036 # include <mln/core/internal/pseudo_site_base.hh>
00037 
00038 
00039 
00040 namespace mln
00041 {
00042 
00043   namespace internal
00044   {
00045 
00046     template <typename S, typename E>
00047     class graph_psite_base : public internal::pseudo_site_base_< const mln_site(S)&,
00048                                                                  E >
00049     {
00050     public:
00051 
00052       // This associated type is important to know that this particular
00053       // pseudo site knows the site set it refers to.
00054       typedef S target;
00055 
00056       // As a Proxy:
00057       const mln_site(S)& subj_();
00058 
00059       typedef typename S::graph_element::id_t id_t;
00060 
00064       void change_target(const S& new_target);
00067       void update_id(unsigned elt_id);
00069 
00073       const S* target_() const; // Hook to the target.
00074 
00076       const S& site_set() const;
00077 
00079       const typename S::graph_t& graph() const;
00080 
00082       id_t id() const;
00083 
00085 
00087       bool is_valid() const;
00089       void invalidate();
00090 
00092       operator unsigned () const;
00093 
00095       operator typename S::graph_element::id_t () const;
00096 
00098       operator const typename S::graph_element&() const;
00099 
00101       const typename S::graph_element& element() const;
00102 
00104       const typename S::graph_element& p_hook_() const;
00105 
00106     protected:
00107 
00109 
00111       graph_psite_base();
00114       graph_psite_base(const S& s);
00118       graph_psite_base(const S& , unsigned id);
00120 
00121       const S* s_;
00122       mln_site(S) site_;
00123       typename S::graph_element elt_;
00124     };
00125 
00126 
00127   /* FIXME: Shouldn't those comparisons be part of a much general
00128      mechanism?  */
00129 
00136   template <typename S, typename E>
00137   bool
00138   operator==(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00139 
00144   template <typename S, typename E>
00145   bool
00146   operator!=(const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00147 
00154   template <typename S, typename E>
00155   bool
00156   operator< (const graph_psite_base<S,E>& lhs, const graph_psite_base<S,E>& rhs);
00158 
00159 
00162   template <typename S, typename P, typename E>
00163   struct subject_impl< const graph_psite_base<S,P>&, E >
00164   {
00165     const S* target_() const;
00166     const S& site_set() const;
00167     const typename S::graph_t& graph() const;
00168     unsigned id() const;
00169     bool is_valid() const;
00170 //    operator unsigned() const;
00171 //    operator const typename S::graph_element&() const;
00172     const typename S::graph_element& element() const;
00173     const typename S::graph_element& p_hook_() const;
00174 
00175     private:
00176     const E& exact_() const;
00177   };
00178 
00179   template <typename S, typename P, typename E>
00180   struct subject_impl<       graph_psite_base<S,P>&, E > :
00181   subject_impl< const graph_psite_base<S,P>&, E >
00182   {
00183     void change_target(const S& new_target);
00184     void update_id(unsigned elt_id);
00185     void invalidate();
00186 
00187     private:
00188     E& exact_();
00189   };
00191 
00192 
00193 
00194 # ifndef MLN_INCLUDE_ONLY
00195 
00196 
00197   template <typename S, typename E>
00198   inline
00199   graph_psite_base<S,E>::graph_psite_base()
00200     : s_(0)
00201   {
00202   }
00203 
00204   template <typename S, typename E>
00205   inline
00206   graph_psite_base<S,E>::graph_psite_base(const S& s)
00207   {
00208     change_target(s);
00209   }
00210 
00211   template <typename S, typename E>
00212   inline
00213   graph_psite_base<S,E>::graph_psite_base(const S& s, unsigned id)
00214   {
00215     change_target(s);
00216     update_id(id);
00217   }
00218 
00219   template <typename S, typename E>
00220   inline
00221   void
00222   graph_psite_base<S,E>::change_target(const S& new_target)
00223   {
00224     s_ = & new_target;
00225     elt_.change_graph(new_target.graph());
00226   }
00227 
00228   template <typename S, typename E>
00229   inline
00230   void
00231   graph_psite_base<S,E>::update_id(unsigned id)
00232   {
00233     mln_precondition(s_ != 0);
00234     elt_.update_id(id);
00235     site_ = s_->function()(elt_.id());
00236   }
00237 
00238   template <typename S, typename E>
00239   inline
00240   const S*
00241   graph_psite_base<S,E>::target_() const
00242   {
00243     return s_;
00244   }
00245 
00246   template <typename S, typename E>
00247   inline
00248   const S&
00249   graph_psite_base<S,E>::site_set() const
00250   {
00251     mln_precondition(s_ != 0);
00252     return *s_;
00253   }
00254 
00255   template <typename S, typename E>
00256   inline
00257   const typename S::graph_t&
00258   graph_psite_base<S,E>::graph() const
00259   {
00260     mln_precondition(s_ != 0);
00261     return s_->graph();
00262   }
00263 
00264   template <typename S, typename E>
00265   inline
00266   typename graph_psite_base<S,E>::id_t
00267   graph_psite_base<S,E>::id() const
00268   {
00269     return elt_.id();
00270   }
00271 
00272   template <typename S, typename E>
00273   inline
00274   bool
00275   graph_psite_base<S,E>::is_valid() const
00276   {
00277     return s_ != 0 && s_->is_valid() && elt_.is_valid();
00278   }
00279 
00280   template <typename S, typename E>
00281   inline
00282   void
00283   graph_psite_base<S,E>::invalidate()
00284   {
00285     s_ = 0;
00286     elt_.invalidate();
00287   }
00288 
00289   template <typename S, typename E>
00290   inline
00291   const mln_site(S)&
00292   graph_psite_base<S,E>::subj_()
00293   {
00294     /*FIXME: we may like to enable the following precondition, however, we
00295     ** can't do that since neighb_*_niters update the psite target after having
00296     ** taken the adress of the subject.
00297     */
00298     // mln_precondition(is_valid());
00299     return site_;
00300   }
00301 
00302   template <typename S, typename E>
00303   inline
00304   graph_psite_base<S,E>::operator unsigned () const
00305   {
00306     mln_precondition(is_valid());
00307     return elt_.id();
00308   }
00309 
00310   template <typename S, typename E>
00311   inline
00312   graph_psite_base<S,E>::operator typename S::graph_element::id_t () const
00313   {
00314     mln_precondition(is_valid());
00315     return elt_.id();
00316   }
00317 
00318   template <typename S, typename E>
00319   inline
00320   graph_psite_base<S,E>::operator const typename S::graph_element&() const
00321   {
00322     //mln_precondition(is_valid());
00323     return elt_;
00324   }
00325 
00326   template <typename S, typename E>
00327   inline
00328   const typename S::graph_element&
00329   graph_psite_base<S,E>::element() const
00330   {
00331     /*FIXME: we may like to enable the following precondition, however, we
00332     ** can't do that since neighb_*_niters update the psite target after having
00333     ** taken the adress of the subject.
00334     */
00335     // mln_precondition(is_valid());
00336     return elt_;
00337   }
00338 
00339   template <typename S, typename E>
00340   inline
00341   const typename S::graph_element&
00342   graph_psite_base<S,E>::p_hook_() const
00343   {
00344     return elt_;
00345   }
00346 
00347 
00348   template <typename S, typename P, typename E>
00349   inline
00350   const E&
00351   subject_impl< const graph_psite_base<S,P>&, E >::exact_() const
00352   {
00353     return internal::force_exact<const E>(*this);
00354   }
00355 
00356   template <typename S, typename P, typename E>
00357   inline
00358   const S*
00359   subject_impl< const graph_psite_base<S,P>&, E >::target_() const
00360   {
00361     return exact_().get_subject().target();
00362   }
00363 
00364   template <typename S, typename P, typename E>
00365   inline
00366   const S&
00367   subject_impl< const graph_psite_base<S,P>&, E >::site_set() const
00368   {
00369     return exact_().get_subject().site_set();
00370   }
00371 
00372 
00373   template <typename S, typename P, typename E>
00374   inline
00375   const typename S::graph_t&
00376   subject_impl< const graph_psite_base<S,P>&, E >::graph() const
00377   {
00378     return exact_().get_subject().graph();
00379   }
00380 
00381   template <typename S, typename P, typename E>
00382   inline
00383   unsigned
00384   subject_impl< const graph_psite_base<S,P>&, E >::id() const
00385   {
00386     return exact_().get_subject().id();
00387   };
00388 
00389   template <typename S, typename P, typename E>
00390   inline
00391   bool
00392   subject_impl< const graph_psite_base<S,P>&, E >::is_valid() const
00393   {
00394     return exact_().get_subject().is_valid();
00395   }
00396 
00397   template <typename S, typename P, typename E>
00398   inline
00399   const typename S::graph_element&
00400   subject_impl< const graph_psite_base<S,P>&, E >::element() const
00401   {
00402     return exact_().get_subject().element();
00403   }
00404 
00405   template <typename S, typename P, typename E>
00406   inline
00407   const typename S::graph_element&
00408   subject_impl< const graph_psite_base<S,P>&, E >::p_hook_() const
00409   {
00410     return exact_().get_subject().p_hook_();
00411   }
00412 
00413 
00414   template <typename S, typename P, typename E>
00415   inline
00416   E&
00417   subject_impl< graph_psite_base<S,P>&, E >::exact_()
00418   {
00419     return internal::force_exact<E>(*this);
00420   }
00421 
00422   template <typename S, typename P, typename E>
00423   inline
00424   void
00425   subject_impl<       graph_psite_base<S,P>&, E >::change_target(const S& new_target)
00426   {
00427     exact_().get_subject().change_target(new_target);
00428   }
00429 
00430   template <typename S, typename P, typename E>
00431   inline
00432   void
00433   subject_impl<       graph_psite_base<S,P>&, E >::update_id(unsigned id)
00434   {
00435     exact_().get_subject().update_id(id);
00436   };
00437 
00438   template <typename S, typename P, typename E>
00439   inline
00440   void
00441   subject_impl< graph_psite_base<S,P>&, E >::invalidate()
00442   {
00443     exact_().get_subject().invalidate();
00444   }
00445 
00446 # endif // ! MLN_INCLUDE_ONLY
00447 
00448 } // end of namespace internal
00449 
00450   } // end of namespace mln
00451 
00452 
00453 #endif // ! MLN_CORE_INTERNAL_GRAPH_PSITE_BASE_HH

Generated on Thu Sep 8 2011 18:31:53 for Milena (Olena) by  doxygen 1.7.1