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

complex_psite.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_SITE_SET_COMPLEX_PSITE_HH
00027 # define MLN_CORE_SITE_SET_COMPLEX_PSITE_HH
00028 
00032 
00033 # include <mln/core/internal/pseudo_site_base.hh>
00034 
00035 # include <mln/topo/complex.hh>
00036 
00037 // FIXME: There's a circular dependency issue between complex_psite
00038 // and p_complex (likewise for faces_psite and p_faces): they have to
00039 // know their interfaces one another.  I have disabled some
00040 // preconditions and invariants to have the code compile, but we must
00041 // find a real solution.
00042 
00043 // FIXME: Factor complex_psite and faces_psite?
00044 
00045 // FIXME: Rename complex_psite as p_complex_psite, and move this file to
00046 // core/site_set.
00047 
00048 
00049 namespace mln
00050 {
00051   // Forward declaration.
00052   template <unsigned D, typename G> class p_complex;
00053 
00054 
00059   template <unsigned D, typename G>
00060   class complex_psite
00061     : public internal::pseudo_site_base_< const mln_site(G)&, complex_psite<D, G> >
00062   {
00063   public:
00064     // This associated type is important to know that this particular
00065     // pseudo site knows the site set it refers to.
00066     typedef p_complex<D, G> target;
00067 
00068     typedef p_complex<D, G> target_t; // To please g++-2.95.
00069 
00070     // FIXME: Document.
00073     complex_psite();
00075     complex_psite(const p_complex<D, G>& pc,
00076                   const topo::face<D>& face);
00077     complex_psite(const p_complex<D, G>& pc, unsigned n, unsigned face_id);
00079 
00083     bool is_valid() const;
00085     void invalidate();
00087 
00093     const target& site_set() const;
00094 
00096     const target* target_() const;
00098     void change_target(const target& new_target);
00100 
00104     const mln_site(G)& subj_();
00106 
00110     const topo::face<D>& face() const;
00111 
00113     unsigned n() const;
00115     unsigned face_id() const;
00117 
00118   private:
00122     void update_();
00123     // The site corresponding to this psite.
00124     mln_site(G) p_;
00126 
00127     /* FIXME: Attributes pc_ and face_ share a common information: the
00128        address of their complex.
00129 
00130        This is both a loss of space and time (we must ensure
00131        synchronization), but this design issue is not trivial: we
00132        actually introduced (any-)face handles to pack together the
00133        location information (n, face_id) with the support (the
00134        complex), to avoid what we did with graphs --- where location
00135        (edge id or vertex id) is separated from the support (the
00136        graph).
00137 
00138        Think about it, and adjust faces_psite as well.  */
00139   private:
00143     const target* pc_;
00145     topo::face<D> face_;
00147   };
00148 
00149 
00152   /* FIXME: Shouldn't those comparisons be part of a much general
00153      mechanism?  */
00154 
00159   /* FIXME: We probably want to relax this precondition: p_complex
00160      equality is too strong; prefer complex equality.  */
00161   template <unsigned D, typename G>
00162   bool
00163   operator==(const complex_psite<D, G>& lhs,
00164              const complex_psite<D, G>& rhs);
00165 
00170   /* FIXME: We probably want to relax this precondition: p_complex
00171      equality is too strong; prefer complex equality.  */
00172   template <unsigned D, typename G>
00173   bool
00174   operator!=(const complex_psite<D, G>& lhs,
00175              const complex_psite<D, G>& rhs);
00176 
00183   /* FIXME: We probably want to relax this precondition: p_complex
00184      equality is too strong; prefer complex equality.  */
00185   template <unsigned D, typename G>
00186   bool
00187   operator< (const complex_psite<D, G>& lhs,
00188              const complex_psite<D, G>& rhs);
00190 
00191 
00192   template <unsigned D, typename G>
00193   inline
00194   std::ostream&
00195   operator<<(std::ostream& ostr, const complex_psite<D, G>& p);
00196 
00197 
00198 
00199 # ifndef MLN_INCLUDE_ONLY
00200 
00201   template <unsigned D, typename G>
00202   inline
00203   complex_psite<D, G>::complex_psite()
00204     : pc_(0)
00205   {
00206     invalidate();
00207   }
00208 
00209   template <unsigned D, typename G>
00210   inline
00211   complex_psite<D, G>::complex_psite(const p_complex<D, G>& pc,
00212                                      const topo::face<D>& face)
00213     : pc_(&pc),
00214       face_(face)
00215   {
00216     // Check arguments consistency.
00217     // FIXME: Re-enable when the cyclic dependencies are fixed.
00218 #if 0
00219     mln_precondition(pc.cplx() == face.cplx());
00220 #endif
00221     if (is_valid())
00222       update_();
00223   }
00224 
00225   template <unsigned D, typename G>
00226   inline
00227   complex_psite<D, G>::complex_psite(const p_complex<D, G>& pc,
00228                                      unsigned n, unsigned face_id)
00229     : pc_(&pc),
00230       face_(pc.cplx(), n, face_id)  
00231   {
00232     if (is_valid())
00233       update_();
00234   }
00235 
00236   template <unsigned D, typename G>
00237   inline
00238   bool
00239   complex_psite<D, G>::is_valid() const
00240   {
00241     // FIXME: Re-enable when the cyclic dependencies are fixed.
00242 #if 0
00243     mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
00244 #endif
00245     return face_.is_valid();
00246   }
00247 
00248   template <unsigned D, typename G>
00249   inline
00250   void
00251   complex_psite<D, G>::invalidate()
00252   {
00253     return face_.invalidate();
00254   }
00255 
00256   template <unsigned D, typename G>
00257   inline
00258   const p_complex<D, G>&
00259   complex_psite<D, G>::site_set() const
00260   {
00261     mln_precondition(target_());
00262     return *target_();
00263   }
00264 
00265   template <unsigned D, typename G>
00266   inline
00267   const p_complex<D, G>*
00268   complex_psite<D, G>::target_() const
00269   {
00270     // FIXME: Re-enable when the cyclic dependencies are fixed.
00271 #if 0
00272     mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
00273 #endif
00274     return pc_;
00275   }
00276 
00277   template <unsigned D, typename G>
00278   inline
00279   void
00280   complex_psite<D, G>::change_target(const target& new_target)
00281   {
00282     // Update both pc_ and face_.
00283     pc_ = &new_target;
00284     face_.set_cplx(new_target.cplx());
00285     invalidate();
00286   }
00287 
00288   // FIXME: Write or extend a test to exercise this method (when the
00289   // handling of G is done, i.e., when update_ is complete).
00290   template <unsigned D, typename G>
00291   inline
00292   const mln_site(G)&
00293   complex_psite<D, G>::subj_()
00294   {
00295     return p_;
00296   }
00297 
00298   template <unsigned D, typename G>
00299   inline
00300   const topo::face<D>&
00301   complex_psite<D, G>::face() const
00302   {
00303     return face_;
00304   }
00305 
00306   template <unsigned D, typename G>
00307   inline
00308   unsigned
00309   complex_psite<D, G>::n() const
00310   {
00311     return face_.n();
00312   }
00313 
00314   template <unsigned D, typename G>
00315   inline
00316   unsigned
00317   complex_psite<D, G>::face_id() const
00318   {
00319     return face_.face_id();
00320   }
00321 
00322   template <unsigned D, typename G>
00323   inline
00324   void
00325   complex_psite<D, G>::update_()
00326   {
00327     mln_precondition(is_valid());
00328     // FIXME: Re-enable when the cyclic dependencies are fixed.
00329 #if 0
00330     mln_invariant(!pc_ || pc_.cplx() == face_.cplx());
00331 #endif
00332     // FIXME: Simplify? (I.e., add accessors to shorten the following
00333     // line?)
00334     p_ = site_set().geom()(face_);
00335   }
00336 
00337 
00338   /*--------------.
00339   | Comparisons.  |
00340   `--------------*/
00341 
00342   template <unsigned D, typename G>
00343   bool
00344   operator==(const complex_psite<D, G>& lhs,
00345              const complex_psite<D, G>& rhs)
00346   {
00347     mln_precondition(&lhs.site_set() == &rhs.site_set());
00348     return lhs.face() == rhs.face();
00349   }
00350 
00351   template <unsigned D, typename G>
00352   bool
00353   operator!=(const complex_psite<D, G>& lhs,
00354              const complex_psite<D, G>& rhs)
00355   {
00356     mln_precondition(&lhs.site_set() == &rhs.site_set());
00357     return lhs.face() != rhs.face();
00358   }
00359 
00360   template <unsigned D, typename G>
00361   bool
00362   operator< (const complex_psite<D, G>& lhs,
00363              const complex_psite<D, G>& rhs)
00364   {
00365     mln_precondition(&lhs.site_set() == &rhs.site_set());
00366     return lhs.face() < rhs.face();
00367   }
00368 
00369 
00370   /*------------------.
00371   | Pretty-printing.  |
00372   `------------------*/
00373 
00374   template <unsigned D, typename G>
00375   inline
00376   std::ostream&
00377   operator<<(std::ostream& ostr, const complex_psite<D, G>& p)
00378   {
00379     return ostr << p.face();
00380   }
00381 
00382 # endif // ! MLN_INCLUDE_ONLY
00383 
00384 } // end of mln
00385 
00386 #endif // ! MLN_CORE_SITE_SET_COMPLEX_PSITE_HH

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