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

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

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