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