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

algebraic_face.hh

00001 // Copyright (C) 2008, 2009, 2010 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_TOPO_ALGEBRAIC_FACE_HH
00028 # define MLN_TOPO_ALGEBRAIC_FACE_HH
00029 
00033 
00034 #include <mln/topo/face.hh>
00035 #include <mln/topo/algebraic_n_face.hh>
00036 
00037 
00038 namespace mln
00039 {
00040 
00041   namespace topo
00042   {
00043 
00044     // Forward declarations.
00045     template <unsigned D> class complex;
00046     template <unsigned N, unsigned D> class n_face;
00047     template <unsigned N, unsigned D> class face_data;
00048 
00049 
00050     /*-------.
00051     | Face.  |
00052     `-------*/
00053 
00059     template <unsigned D>
00060     class algebraic_face : public face<D>
00061     {
00062       typedef face<D> super_;
00063 
00064     public:
00065       // The type of the complex this handle points to.
00066       typedef complex<D> complex_type;
00067 
00069       algebraic_face();
00071       algebraic_face(complex<D>& complex, unsigned n, unsigned face_id,
00072                      bool sign);
00074       algebraic_face(const face<D>& f, bool sign);
00075 
00077       template <unsigned N>
00078       algebraic_face(const algebraic_n_face<N, D>& f);
00079 
00083       bool sign() const;
00085       void set_sign(bool sign);
00087 
00088     private:
00090       bool sign_;
00091     };
00092 
00093 
00095     template <unsigned D>
00096     algebraic_face<D>
00097     make_algebraic_face(const face<D>& f, bool sign);
00098 
00099 
00102     template <unsigned D>
00103     algebraic_face<D>
00104     operator-(const face<D>& f);
00105 
00106     template <unsigned D>
00107     algebraic_face<D>
00108     operator-(const algebraic_face<D>& f);
00110 
00111 
00114 
00119     template <unsigned D>
00120     bool operator==(const algebraic_face<D>& lhs,
00121                     const algebraic_face<D>& rhs);
00122 
00127     template <unsigned D>
00128     bool operator!=(const algebraic_face<D>& lhs,
00129                     const algebraic_face<D>& rhs);
00130 
00139     template <unsigned D>
00140     bool operator< (const algebraic_face<D>& lhs,
00141                     const algebraic_face<D>& rhs);
00142 
00144 
00145 
00147     template <unsigned D>
00148     std::ostream&
00149     operator<<(std::ostream& ostr, const algebraic_face<D>& f);
00150 
00151 
00152 
00153 # ifndef MLN_INCLUDE_ONLY
00154 
00155     template <unsigned D>
00156     inline
00157     algebraic_face<D>::algebraic_face()
00158       : super_(), sign_(true)
00159     {
00160     }
00161 
00162     template <unsigned D>
00163     inline
00164     algebraic_face<D>::algebraic_face(complex<D>& c, unsigned n,
00165                                       unsigned face_id, bool sign)
00166       : super_(c, n, face_id), sign_(sign)
00167     {
00168       // Ensure N is compatible with D.
00169       mln_precondition(n <= D);
00170     }
00171 
00172     template <unsigned D>
00173     inline
00174     algebraic_face<D>::algebraic_face(const face<D>& f, bool sign)
00175       : super_(f), sign_(sign)
00176     {
00177       // Ensure N is compatible with D.
00178       mln_precondition(f.n() <= D);
00179     }
00180 
00181     template <unsigned D>
00182     template <unsigned N>
00183     inline
00184     algebraic_face<D>::algebraic_face(const algebraic_n_face<N, D>& f)
00185       : super_(f), sign_(f.sign())
00186     {
00187       // Ensure N is compatible with D.
00188       metal::bool_< N <= D >::check();
00189     }
00190 
00191 
00192     template <unsigned D>
00193     inline
00194     bool
00195     algebraic_face<D>::sign() const
00196     {
00197       return sign_;
00198     }
00199 
00200     template <unsigned D>
00201     inline
00202     void
00203     algebraic_face<D>::set_sign(bool sign)
00204     {
00205       sign_ = sign;
00206     }
00207 
00208 
00209     template <unsigned D>
00210     algebraic_face<D>
00211     make_algebraic_face(const face<D>& f, bool sign)
00212     {
00213       return algebraic_face<D>(f, sign);
00214     }
00215 
00216 
00217     template <unsigned D>
00218     algebraic_face<D>
00219     operator-(const face<D>& f)
00220     {
00221       return algebraic_face<D>(f, false);
00222     }
00223 
00224     template <unsigned D>
00225     algebraic_face<D>
00226     operator-(const algebraic_face<D>& f)
00227     {
00228       algebraic_face<D> f2(f);
00229       f2.set_sign(!f.sign());
00230       return f2;
00231     }
00232 
00233 
00234     template <unsigned D>
00235     inline
00236     bool
00237     operator==(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00238     {
00239       // Ensure LHS and RHS belong to the same complex.
00240       mln_precondition(lhs.cplx() == rhs.cplx());
00241       return
00242         lhs.n() == rhs.n() &&
00243         lhs.face_id() == rhs.face_id() &&
00244         lhs.sign() == rhs.sign();
00245     }
00246 
00247     template <unsigned D>
00248     inline
00249     bool
00250     operator!=(const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00251     {
00252       // Ensure LHS and RHS belong to the same complex.
00253       mln_precondition(lhs.cplx() == rhs.cplx());
00254       return !(lhs == rhs);
00255     }
00256 
00257     template <unsigned D>
00258     inline
00259     bool
00260     operator< (const algebraic_face<D>& lhs, const algebraic_face<D>& rhs)
00261     {
00262       // Ensure LHS and RHS belong to the same complex.
00263       mln_precondition(lhs.cplx() == rhs.cplx());
00264       // Ensure LHS and RHS have the same dimension.
00265       mln_precondition(lhs.n() == rhs.n());
00266       return lhs.face_id() < rhs.face_id();
00267     }
00268 
00269 
00270     template <unsigned D>
00271     inline
00272     std::ostream&
00273     operator<<(std::ostream& ostr, const algebraic_face<D>& f)
00274     {
00275       return
00276         ostr << "(cplx = " << f.cplx().addr() << ", dim = " << f.n()
00277              << ", id = " << f.face_id() << ", sign = " << f.sign()<< ')';
00278     }
00279 
00280 
00281     /*-----------------------------------------------.
00282     | Helpers for face<D>::lower_dim_adj_faces() and |
00283     | face<D>::higher_dim_adj_faces().               |
00284     `-----------------------------------------------*/
00285 
00286     /* FIXME: This is way too complicated; should disappear when the
00287        implementation of complexes is simplified (see
00288        https://trac.lrde.org/olena/ticket/168).  */
00289 
00290     namespace internal
00291     {
00292 
00293       template <unsigned N, unsigned D>
00294       std::vector< algebraic_face<D> > 
00295       lower_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00296       {
00297         metal::bool_< (N <= D) >::check();
00298         metal::bool_< (N > 1) >::check();
00299 
00300         if (face.n() == N)
00301           {
00302             face_data<N, D>& data = face.template data<N>();
00303             std::vector< algebraic_n_face<N - 1, D> > lower_dim_faces =
00304               data.lower_dim_faces_;
00305             std::vector< topo::algebraic_face<D> > result;
00306             for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator f =
00307                    lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00308               result.push_back(*f);
00309             return result;
00310           }
00311         else
00312           return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00313       }
00314 
00315       template <unsigned D>
00316       std::vector< algebraic_face<D> > 
00317       lower_dim_adj_faces_if_dim_matches_<1, D>::operator()(const face<D>& face)
00318       {
00321         mln_precondition(face.n() == 1);
00322         face_data<1, D>& data = face.template data<1>();
00323         std::vector< algebraic_n_face<0, D> > lower_dim_faces =
00324           data.lower_dim_faces_;
00325         std::vector< topo::algebraic_face<D> > result;
00326         for (typename std::vector< algebraic_n_face<0, D> >::const_iterator f =
00327                lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f)
00328           result.push_back(*f);
00329         return result;
00330       }
00331 
00332       template <unsigned N, unsigned D>
00333       std::vector< algebraic_face<D> > 
00334       higher_dim_adj_faces_if_dim_matches_<N, D>::operator()(const face<D>& face)
00335       {
00336         metal::bool_< (N < D) >::check();
00337 
00338         if (face.n() == N)
00339           {
00340             face_data<N, D>& data = face.template data<N>();
00341             std::vector< algebraic_n_face<N + 1, D> > higher_dim_faces =
00342               data.higher_dim_faces_;
00343             std::vector< topo::algebraic_face<D> > result;
00344             for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator f =
00345                    higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00346               result.push_back(*f);
00347             return result;
00348           }
00349         else
00350           return
00351             internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face);
00352       }
00353 
00354       template <unsigned D>
00355       std::vector< algebraic_face<D> > 
00356       higher_dim_adj_faces_if_dim_matches_<0, D>::operator()(const face<D>& face)
00357       {
00360         mln_precondition(face.n() == 0);
00361         face_data<0, D>& data = face.template data<0>();
00362         std::vector< algebraic_n_face<1, D> > higher_dim_faces =
00363           data.higher_dim_faces_;
00364         std::vector< topo::algebraic_face<D> > result;
00365         for (typename std::vector< algebraic_n_face<1, D> >::const_iterator f =
00366                higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f)
00367           result.push_back(*f);
00368         return result;
00369       }
00370 
00371     } // end of namespace mln::topo::internal
00372 
00373 
00374 # endif // ! MLN_INCLUDE_ONLY
00375 
00376   } // end of namespace mln::topo
00377 
00378 } // end of namespace mln
00379 
00380 #endif // ! MLN_TOPO_ALGEBRAIC_FACE_HH

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