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

faces_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_FACES_PSITE_HH
00027 # define MLN_CORE_FACES_PSITE_HH
00028 
00032 
00033 # include <cstdlib>
00034 
00035 # include <mln/core/internal/pseudo_site_base.hh>
00036 
00037 # include <mln/topo/complex.hh>
00038 
00039 // FIXME: Factor complex_psite and faces_psite?
00040 
00041 // FIXME: Rename faces_psite as p_faces_psite, and move this file to
00042 // core/site_set.
00043 
00044 namespace mln
00045 {
00046   // Forward declaration.
00047   template <unsigned N, unsigned D, typename P> class p_faces;
00048 
00049 
00055   template <unsigned N, unsigned D, typename P>
00056   class faces_psite
00057     : public internal::pseudo_site_base_< const P&,
00058                                           faces_psite<N, D, P> >
00059   {
00060   public:
00061     // This associated type is important to know that this particular
00062     // pseudo site knows the site set it refers to.
00063     typedef p_faces<N, D, P> target;
00064 
00067     faces_psite();
00069     faces_psite(const p_faces<N, D, P>& pf, const topo::n_face<N, D>& face);
00070     faces_psite(const p_faces<N, D, P>& pf, unsigned face_id);
00072 
00076     bool is_valid() const;
00078     void invalidate();
00080 
00086     const target& site_set() const;
00087 
00089     const target* target_() const;
00091     void change_target(const target& new_target);
00093 
00097     const P& subj_();
00099 
00103     topo::n_face<N, D> face() const;
00104 
00106     unsigned n() const;
00108     unsigned face_id() const;
00110 
00111   private:
00115     void update_();
00116     // The site corresponding to this psite.
00117     P p_;
00119 
00120     /* FIXME: Attributes pf_ and face_ share a common information: the
00121        address of their complex.
00122 
00123        This is both a loss of space and time (we must ensure
00124        synchronization), but this design issue is not trivial: we
00125        actually introduced the face handles to pack together the
00126        location information (face_id) with the support (the complex),
00127        to avoid what we did with graphs --- where location (edge id or
00128        vertex id) is separated from the support (the graph).
00129 
00130        Think about it, and adjust complex_psite as well.  */
00131   private:
00135     const target* pf_;
00137     topo::n_face<N, D> face_;
00139   };
00140 
00141 
00144   /* FIXME: Shouldn't those comparisons be part of a much general
00145      mechanism?  */
00146 
00151   template <unsigned N, unsigned D, typename P>
00152   bool
00153   operator==(const faces_psite<N, D, P>& lhs,
00154              const faces_psite<N, D, P>& rhs);
00155 
00156 
00161   template <unsigned N, unsigned D, typename P>
00162   bool
00163   operator!=(const faces_psite<N, D, P>& lhs,
00164              const faces_psite<N, D, P>& rhs);
00165 
00172   template <unsigned N, unsigned D, typename P>
00173   bool
00174   operator< (const faces_psite<N, D, P>& lhs,
00175              const faces_psite<N, D, P>& rhs);
00177 
00178 
00179   template <unsigned N, unsigned D, typename P>
00180   inline
00181   std::ostream&
00182   operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p);
00183 
00184 
00185 
00186 # ifndef MLN_INCLUDE_ONLY
00187 
00188   template <unsigned N, unsigned D, typename P>
00189   inline
00190   faces_psite<N, D, P>::faces_psite()
00191     : pf_(0)
00192   {
00193     // Ensure N is compatible with D.
00194     metal::bool_< N <= D >::check();
00195 
00196     invalidate();
00197   }
00198 
00199   template <unsigned N, unsigned D, typename P>
00200   inline
00201   faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
00202                                     const topo::n_face<N, D>& face)
00203     : pf_(&pf),
00204       face_(face)
00205   {
00206     // Ensure N is compatible with D.
00207     metal::bool_< N <= D >::check();
00208     // Check arguments consistency.
00209 //     mln_precondition(pf.cplx() == face.cplx());
00210 
00211     update_();
00212   }
00213 
00214   template <unsigned N, unsigned D, typename P>
00215   inline
00216   faces_psite<N, D, P>::faces_psite(const p_faces<N, D, P>& pf,
00217                                     unsigned face_id)
00218     : pf_(&pf),
00219       face_(pf.cplx(), face_id)
00220   {
00221     // Ensure N is compatible with D.
00222     metal::bool_< N <= D >::check();
00223 
00224     update_();
00225   }
00226 
00227   template <unsigned N, unsigned D, typename P>
00228   inline
00229   bool
00230   faces_psite<N, D, P>::is_valid() const
00231   {
00232 //     mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
00233     return face_.is_valid();
00234   }
00235 
00236   template <unsigned N, unsigned D, typename P>
00237   inline
00238   void
00239   faces_psite<N, D, P>::invalidate()
00240   {
00241     return face_.invalidate();
00242   }
00243 
00244   template <unsigned N, unsigned D, typename P>
00245   inline
00246   const p_faces<N, D, P>&
00247   faces_psite<N, D, P>::site_set() const
00248   {
00249     mln_precondition(target_());
00250     return *target_();
00251   }
00252 
00253   template <unsigned N, unsigned D, typename P>
00254   inline
00255   const p_faces<N, D, P>*
00256   faces_psite<N, D, P>::target_() const
00257   {
00258 //     mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
00259     return pf_;
00260   }
00261 
00262   template <unsigned N, unsigned D, typename P>
00263   inline
00264   void
00265   faces_psite<N, D, P>::change_target(const target& new_target)
00266   {
00267     // Update both pc_ and face_.
00268     pf_ = &new_target;
00269     face_.set_cplx(new_target.cplx());
00270     invalidate();
00271   }
00272 
00273   // FIXME: Write or extend a test to exercise this method (when the
00274   // handling of P is done, i.e., when update_ is complete).
00275   template <unsigned N, unsigned D, typename P>
00276   inline
00277   const P&
00278   faces_psite<N, D, P>::subj_()
00279   {
00280     // FIXME: Member p_ is not updated correctly yet; do not use this
00281     // method for now.
00282     abort();
00283     return p_;
00284   }
00285 
00286   template <unsigned N, unsigned D, typename P>
00287   inline
00288   topo::n_face<N, D>
00289   faces_psite<N, D, P>::face() const
00290   {
00291     return face_;
00292   }
00293 
00294   template <unsigned N, unsigned D, typename P>
00295   inline
00296   unsigned
00297   faces_psite<N, D, P>::n() const
00298   {
00299     return face_.n();
00300   }
00301 
00302   template <unsigned N, unsigned D, typename P>
00303   inline
00304   unsigned
00305   faces_psite<N, D, P>::face_id() const
00306   {
00307     return face_.face_id();
00308   }
00309 
00310   template <unsigned N, unsigned D, typename P>
00311   inline
00312   void
00313   faces_psite<N, D, P>::update_()
00314   {
00315     mln_precondition(is_valid());
00316 //     mln_invariant(!pf_ || pf_.cplx() == face_.cplx());
00317     // FIXME: Implement (update p_).
00318   }
00319 
00320 
00321   /*--------------.
00322   | Comparisons.  |
00323   `--------------*/
00324 
00325   template <unsigned N, unsigned D, typename P>
00326   bool
00327   operator==(const faces_psite<N, D, P>& lhs,
00328              const faces_psite<N, D, P>& rhs)
00329   {
00330     mln_precondition(&lhs.site_set() == &rhs.site_set());
00331     return lhs.face() == rhs.face();
00332   }
00333 
00334   template <unsigned N, unsigned D, typename P>
00335   bool
00336   operator!=(const faces_psite<N, D, P>& lhs,
00337              const faces_psite<N, D, P>& rhs)
00338   {
00339     mln_precondition(&lhs.site_set() == &rhs.site_set());
00340     return lhs.face() != rhs.face();
00341   }
00342 
00343   template <unsigned N, unsigned D, typename P>
00344   bool
00345   operator< (const faces_psite<N, D, P>& lhs,
00346              const faces_psite<N, D, P>& rhs)
00347   {
00348     mln_precondition(&lhs.site_set() == &rhs.site_set());
00349     return lhs.face() < rhs.face();
00350   }
00351 
00352 
00353   /*------------------.
00354   | Pretty-printing.  |
00355   `------------------*/
00356 
00357   template <unsigned N, unsigned D, typename P>
00358   inline
00359   std::ostream&
00360   operator<<(std::ostream& ostr, const faces_psite<N, D, P>& p)
00361   {
00362     return ostr << "(dim = " << p.n() << ", id = " << p.face_id() << ')';
00363   }
00364 
00365 # endif // ! MLN_INCLUDE_ONLY
00366 
00367 } // end of mln
00368 
00369 #endif // ! MLN_CORE_FACES_PSITE_HH

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