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

complex.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_COMPLEX_HH
00028 # define MLN_TOPO_COMPLEX_HH
00029 
00036 
00037 # include <cstddef>
00038 
00039 # include <iosfwd>
00040 
00041 # include <mln/metal/bool.hh>
00042 
00043 # include <mln/util/tracked_ptr.hh>
00044 
00045 # include <mln/topo/face_data.hh>
00046 # include <mln/topo/algebraic_face.hh>
00047 # include <mln/topo/algebraic_n_face.hh>
00048 # include <mln/topo/n_faces_set.hh>
00049 
00050 # include <mln/topo/complex_iterators.hh>
00051 
00052 
00053 namespace mln
00054 {
00055 
00056   namespace topo
00057   {
00058 
00059     // Forward declarations (external).
00060     template <unsigned N, unsigned D> class n_faces_set;
00061     template <unsigned D> class face_fwd_iter;
00062     template <unsigned D> class face_bkd_iter;
00063 // FIXME: Disabled (moved to the attic).
00064 # if 0
00065     template <unsigned N, unsigned D> class faces_fwd_iter_;
00066     template <unsigned N, unsigned D> class faces_bkd_iter_;
00067 #endif
00068 
00069     // Forward declarations (internal).
00070     namespace internal
00071     {
00072       template <unsigned D>
00073       struct complex_data;
00074 
00075       template <unsigned N, unsigned D>
00076       struct faces_set_mixin;
00077     }
00078 
00079 
00080     /*----------.
00081     | Complex.  |
00082     `----------*/
00083 
00085     //
00086     template <unsigned D>
00087     class complex
00088     {
00089     public:
00091       typedef face_fwd_iter<D> fwd_citer;
00093       typedef face_bkd_iter<D> bkd_citer;
00094 
00095 // FIXME: Disabled (moved to the attic).
00096 # if 0
00097 
00098       template <unsigned N>
00099       struct fwd_fiter { typedef faces_fwd_iter_<N, D> ret; };
00101       template <unsigned N>
00102       struct bkd_fiter { typedef faces_bkd_iter_<N, D> ret; };
00103 #endif
00104 
00108       complex();
00109 
00111       n_face<0u, D> add_face();
00112 
00117       template <unsigned N>
00118       n_face<N + 1, D> add_face(const n_faces_set<N, D>& adjacent_faces);
00120 
00127       unsigned nfaces() const;
00128 
00130       template <unsigned N>
00131       unsigned nfaces_of_static_dim() const;
00133 
00144       unsigned nfaces_of_dim(unsigned n) const;
00146 
00150       void print(std::ostream& ostr) const;
00152       template <unsigned N>
00153       void print_faces(std::ostream& ostr) const;
00155 
00160       const void* addr() const;
00161 
00162     private:
00164       util::tracked_ptr< internal::complex_data<D> > data_;
00165 
00166       template <unsigned D_>
00167       friend bool operator==(const complex<D_>& lhs, const complex<D_>& rhs);
00168 
00171       template <unsigned N, unsigned D_> friend class n_face;
00172       template <unsigned D_> friend class face;
00173 
00174       template <unsigned N>
00175       face_data<N, D>& face_data_(unsigned face_id);
00176 
00177       template <unsigned N>
00178       const face_data<N, D>& face_data_(unsigned face_id) const;
00180 
00183       /* FIXME: Use something more constraining than the STL's
00184          UnaryFunction/BinaryFunction.  Use Function or Function_v2v?
00185          Or a new subclass of Function?  */
00186 
00187       /* FIXME: Replace F and ACCU by a Milena accumulator?  */
00188 
00198       template <typename BinaryFunction, typename T>
00199       T fold_left_(const BinaryFunction& f, const T& accu) const;
00200 
00202       template <typename UnaryFunction>
00203       typename UnaryFunction::result_type
00204       apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
00206 
00213       template <unsigned N>
00214       void connect_(const algebraic_n_face<N, D>& f1,
00215                     const n_face<N + 1, D>& f2);
00216     };
00217 
00218 
00220     template <unsigned D>
00221     bool
00222     operator==(const complex<D>& lhs, const complex<D>& rhs);
00223 
00224 
00226     template <unsigned D>
00227     std::ostream&
00228     operator<<(std::ostream& ostr, const complex<D>& c);
00229 
00230 
00231     /*---------------.
00232     | Complex data.  |
00233     `---------------*/
00234 
00289     /*---------------------.
00290     | Faces of a complex.  |
00291     `---------------------*/
00292 
00295     namespace internal
00296     {
00297 
00298       // Forward declarations.
00299       template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin;
00300       template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin;
00301 
00302       // -------------------------------------- //
00303       // mln::topo::internal::faces_set_mixin.  //
00304       // -------------------------------------- //
00305 
00308 
00309       template <unsigned N, unsigned D> struct faces_set_mixin;
00310 
00311 
00313       template <unsigned N, unsigned D>
00314       struct faces_set_mixin : public faces_set_mixin<N - 1, D>,
00315                                public lower_dim_faces_set_mixin<N, D>,
00316                                public higher_dim_faces_set_mixin<N, D>
00317       {
00318         std::vector< face_data<N, D> > faces_;
00319 
00323         void print(std::ostream& ostr) const;
00326         void print_rec_asc(std::ostream& ostr) const;
00328 
00333         template <typename BinaryFunction, typename T>
00334         T fold_left_(const BinaryFunction& f, const T& accu) const;
00337         template <typename UnaryFunction>
00338         typename UnaryFunction::result_type
00339         apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
00341       };
00342 
00344       template <unsigned D>
00345       struct faces_set_mixin<D, D> : public faces_set_mixin<D - 1, D>,
00346                                      public lower_dim_faces_set_mixin<D, D>
00347       {
00348         std::vector< face_data<D, D> > faces_;
00349 
00353         void print(std::ostream& ostr) const;
00354         void print_rec_asc(std::ostream& ostr) const;
00356 
00361         template <typename BinaryFunction, typename T>
00362         T fold_left_(const BinaryFunction& f, const T& accu) const;
00365         template <typename UnaryFunction>
00366         typename UnaryFunction::result_type
00367         apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
00369       };
00370 
00372       template <unsigned D>
00373       struct faces_set_mixin<0u, D> : public higher_dim_faces_set_mixin<0u, D>
00374       {
00375         std::vector< face_data<0u, D> > faces_;
00376 
00380         void print(std::ostream& ostr) const;
00381         void print_rec_asc(std::ostream& ostr) const;
00383 
00388         template <typename BinaryFunction, typename T>
00389         T fold_left_(const BinaryFunction& f, const T& accu) const;
00392         template <typename UnaryFunction>
00393         typename UnaryFunction::result_type
00394         apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
00396       };
00397 
00399       template <>
00400       struct faces_set_mixin<0u, 0u>
00401       {
00402         std::vector< face_data<0u, 0u> > faces_;
00403 
00407         void print(std::ostream& ostr) const;
00408         void print_rec_asc(std::ostream& ostr) const;
00410 
00415         template <typename BinaryFunction, typename T>
00416         T fold_left_(const BinaryFunction& f, const T& accu) const;
00419         template <typename UnaryFunction>
00420         typename UnaryFunction::result_type
00421         apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const;
00423       };
00425 
00426 
00427       // Tech note: g++-2.95 highly prefers to have the complex_data
00428       // class to be defined after the specializations of
00429       // 'faces_set_mixin'.
00430 
00432       template <unsigned D>
00433       struct complex_data : public faces_set_mixin<D, D>
00434       {
00435         // Data is contained in super classes.
00436       };
00437 
00438 
00439       // ------------------------------------------------- //
00440       // mln::topo::internal::lower_dim_faces_set_mixin.   //
00441       // mln::topo::internal::higher_dim_faces_set_mixin.  //
00442       // ------------------------------------------------- //
00443 
00446       template <unsigned N, unsigned D>
00447       struct lower_dim_faces_set_mixin
00448       {
00449         void print(std::ostream& ostr, const face_data<N, D>& f) const;
00450       };
00451 
00452       template <unsigned N, unsigned D>
00453       struct higher_dim_faces_set_mixin
00454       {
00455         void print(std::ostream& ostr, const face_data<N, D>& f) const;
00456       };
00458 
00459     } // end of namespace mln::topo::internal
00460 
00461 
00462 
00463 # ifndef MLN_INCLUDE_ONLY
00464 
00465     /*-----------------------.
00466     | Complex construction.  |
00467     `-----------------------*/
00468 
00469     template <unsigned D>
00470     inline
00471     complex<D>::complex()
00472       // Allocate data for this complex.
00473       : data_(new internal::complex_data<D>())
00474     {
00475     }
00476 
00477     template <unsigned D>
00478     inline
00479     n_face<0u, D>
00480     complex<D>::add_face()
00481     {
00482       /* FIXME: This is not thread-proof (these two lines should
00483          form an atomic section).  */
00484       data_->internal::faces_set_mixin<0u, D>::faces_.push_back(face_data<0u, D>());
00485       unsigned id = nfaces_of_static_dim<0u>() - 1;
00486       return n_face<0u, D>(*this, id);
00487     }
00488 
00489     template <unsigned D>
00490     template <unsigned N>
00491     inline
00492     n_face<N + 1, D>
00493     complex<D>::add_face(const n_faces_set<N, D>& adjacent_faces)
00494     {
00495       typedef typename std::vector< algebraic_n_face<N, D> >::const_iterator
00496         iter_t;
00497 
00498       // Ensure ADJACENT_FACES are already part of the complex.
00499       if (!HAS_NDEBUG)
00500         for (iter_t a = adjacent_faces.faces().begin();
00501              a != adjacent_faces.faces().end(); ++a)
00502           {
00503             mln_precondition(a->cplx() == *this);
00504             mln_precondition(a->is_valid());
00505           }
00506 
00507       face_data<N + 1, D> f;
00508       /* FIXME: This is not thread-proof (these two lines should
00509          form an atomic section).  */
00510       data_->internal::faces_set_mixin<N + 1, D>::faces_.push_back(f);
00511       unsigned id = nfaces_of_static_dim<N + 1>() - 1;
00512 
00513       n_face<N + 1, D> fh(*this, id);
00514       // Connect F and its ADJACENT_FACES.
00515       for (iter_t a = adjacent_faces.faces().begin();
00516            a != adjacent_faces.faces().end(); ++a)
00517         /* Connect
00518            - algebraic n-face *A,
00519            - and an (n+1)-algebraic face based on FH and having the
00520              sign of *A.  */
00521         connect_(*a, fh);
00522       return fh;
00523     }
00524 
00525 
00526     /*-------.
00527     | Misc.  |
00528     `-------*/
00529 
00530     namespace internal
00531     {
00532 
00541       struct add_size
00542       {
00543         template <typename T, typename Container>
00544         T operator()(const T& x, const Container& c) const
00545         {
00546           return x + c.size();
00547         }
00548       };
00549 
00558       struct get_size
00559       {
00560         typedef std::size_t result_type;
00561 
00562         template <typename Container>
00563         typename Container::size_type operator()(const Container& c) const
00564         {
00565           return c.size();
00566         }
00567       };
00568 
00569     } // end of namespace mln::topo::internal
00570 
00571 
00572     /*----------------------.
00573     | Static manipulators.  |
00574     `----------------------*/
00575 
00576     template <unsigned D>
00577     inline
00578     unsigned
00579     complex<D>::nfaces() const
00580     {
00581       return fold_left_(internal::add_size(), 0);
00582     }
00583 
00584     template <unsigned D>
00585     template <unsigned N>
00586     inline
00587     unsigned
00588     complex<D>::nfaces_of_static_dim() const
00589     {
00590       return data_->internal::faces_set_mixin<N, D>::faces_.size();
00591     }
00592 
00593 
00594     /*-----------------------.
00595     | Dynamic manipulators.  |
00596     `-----------------------*/
00597 
00598     template <unsigned D>
00599     inline
00600     unsigned
00601     complex<D>::nfaces_of_dim(unsigned n) const
00602     {
00603       // Ensure N is compatible with D.
00604       mln_precondition(n <= D);
00605       return apply_if_dim_matches_(n, internal::get_size());
00606     }
00607 
00608 
00609     /*-------------------.
00610     | Internal methods.  |
00611     `-------------------*/
00612 
00613     template <unsigned D>
00614     template <unsigned N>
00615     inline
00616     face_data<N, D>&
00617     complex<D>::face_data_(unsigned face_id)
00618     {
00619       return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
00620     }
00621 
00622     template <unsigned D>
00623     template <unsigned N>
00624     inline
00625     const face_data<N, D>&
00626     complex<D>::face_data_(unsigned face_id) const
00627     {
00628       return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
00629     }
00630 
00631     template <unsigned D>
00632     template <unsigned N>
00633     inline
00634     void
00635     complex<D>::connect_(const algebraic_n_face<N, D>& f1,
00636                          const n_face<N + 1, D>& f2)
00637     {
00638       // Ensure N is compatible with D.
00639       metal::bool_< N <= D >::check();
00640 
00641       /* Connect
00642          - F1, an algebraic n-face,
00643          - and AF2, an algebraic (n+1)-face based on F2 and having the
00644            sign of F1.  */
00645       f1.data().connect_higher_dim_face(make_algebraic_n_face(f2, f1.sign()));
00646       f2.data().connect_lower_dim_face(f1);
00647     }
00648 
00649 
00650     /*-------------.
00651     | Comparison.  |
00652     `-------------*/
00653 
00654     template <unsigned D>
00655     inline
00656     bool
00657     operator==(const complex<D>& lhs, const complex<D>& rhs)
00658     {
00659       return lhs.data_.ptr_ == rhs.data_.ptr_;
00660     }
00661 
00662 
00663     /*------------------.
00664     | Pretty-printing.  |
00665     `------------------*/
00666 
00667     template <unsigned D>
00668     inline
00669     std::ostream&
00670     operator<<(std::ostream& ostr, const complex<D>& c)
00671     {
00672       c.print(ostr);
00673       return ostr;
00674     }
00675 
00676     template <unsigned D>
00677     inline
00678     void
00679     complex<D>::print(std::ostream& ostr) const
00680     {
00681       data_->internal::faces_set_mixin<D, D>::print_rec_asc(ostr);
00682     }
00683 
00684     template <unsigned D>
00685     template <unsigned N>
00686     inline
00687     void
00688     complex<D>::print_faces(std::ostream& ostr) const
00689     {
00690       // Ensure N is compatible with D.
00691       metal::bool_< N <= D >::check();
00692 
00693       data_->internal::faces_set_mixin<N, D>::print(ostr);
00694     }
00695 
00696     template <unsigned D>
00697     inline
00698     const void* 
00699     complex<D>::addr() const
00700     {
00701       return data_.ptr_;
00702     }
00703 
00704 
00705     namespace internal
00706     {
00707 
00708       template <unsigned N, unsigned D>
00709       inline
00710       void
00711       faces_set_mixin<N, D>::print_rec_asc(std::ostream& ostr) const
00712       {
00713         faces_set_mixin<N - 1, D>::print_rec_asc(ostr);
00714         print(ostr);
00715       }
00716 
00717       template <unsigned D>
00718       inline
00719       void
00720       faces_set_mixin<0u, D>::print_rec_asc(std::ostream& ostr) const
00721       {
00722         print(ostr);
00723       }
00724 
00725       template <unsigned D>
00726       inline
00727       void
00728       faces_set_mixin<D, D>::print_rec_asc(std::ostream& ostr) const
00729       {
00730         faces_set_mixin<D - 1, D>::print_rec_asc(ostr);
00731         print(ostr);
00732       }
00733 
00734       inline
00735       void
00736       faces_set_mixin<0u, 0u>::print_rec_asc(std::ostream& ostr) const
00737       {
00738         print(ostr);
00739       }
00740 
00741 
00742       template <unsigned N, unsigned D>
00743       inline
00744       void
00745       faces_set_mixin<N, D>::print(std::ostream& ostr) const
00746       {
00747         ostr << "Faces of dimension " << N
00748              << " and their ajacent faces of dimension "
00749              << N - 1 << " and "
00750              << N + 1 << std::endl;
00751         for (unsigned f = 0; f < faces_.size(); ++f)
00752           {
00753             ostr << "  " << f << ":  dim " << N - 1 << ": { ";
00754             lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
00755             ostr << "},  dim " << N + 1 << ": { ";
00756             higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
00757             ostr << "}" << std::endl;
00758           }
00759       }
00760 
00761       template <unsigned D>
00762       inline
00763       void
00764       faces_set_mixin<0u, D>::print(std::ostream& ostr) const
00765       {
00766         const unsigned N = 0u;
00767         ostr << "Faces of dimension " << N
00768              << " and their ajacent faces of dimension "
00769              << N + 1 << std::endl;
00770         for (unsigned f = 0; f < faces_.size(); ++f)
00771           {
00772             ostr << "  " << f << ":  dim " << N + 1 << ": { ";
00773             higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
00774             ostr << "}" << std::endl;
00775           }
00776       }
00777 
00778       template <unsigned D>
00779       inline
00780       void
00781       faces_set_mixin<D, D>::print(std::ostream& ostr) const
00782       {
00783         const unsigned N = D;
00784         ostr << "Faces of dimension " << N
00785              << " and their ajacent faces of dimension "
00786              << N - 1 << std::endl;
00787         for (unsigned f = 0; f < faces_.size(); ++f)
00788           {
00789             ostr << "  " << f << ":  dim " << N - 1 << ": { ";
00790             lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
00791             ostr << "}" << std::endl;
00792           }
00793       }
00794 
00795       inline
00796       void
00797       faces_set_mixin<0u, 0u>::print(std::ostream& ostr) const
00798       {
00799         const unsigned N = 0u;
00800         ostr << "Faces of dimension " << N << std::endl;
00801         for (unsigned f = 0; f < faces_.size(); ++f)
00802           ostr << "  " << f << std::endl;
00803       }
00804 
00805 
00806       template <unsigned N, unsigned D>
00807       inline
00808       void
00809       lower_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
00810                                              const face_data<N, D>& f) const
00811       {
00812         for (typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator l =
00813                f.lower_dim_faces_.begin(); l != f.lower_dim_faces_.end(); ++l)
00814           ostr << l->face_id() << " ";
00815       }
00816 
00817       template <unsigned N, unsigned D>
00818       inline
00819       void
00820       higher_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
00821                                               const face_data<N, D>& f) const
00822       {
00823         for (typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator h =
00824                f.higher_dim_faces_.begin(); h != f.higher_dim_faces_.end(); ++h)
00825           ostr << h->face_id() << " ";
00826       }
00827 
00828     } // end of namespace mln::topo::internal
00829 
00830 
00831     /*-------------------------------.
00832     | Functional meta-manipulators.  |
00833     `-------------------------------*/
00834 
00835     /* ------------------------------- */
00836     /* ``Static Fold Left'' Operator.  */
00837     /* ------------------------------- */
00838 
00839     template <unsigned D>
00840     template <typename BinaryFunction, typename T>
00841     inline
00842     T
00843     complex<D>::fold_left_(const BinaryFunction& f, const T& accu) const
00844     {
00845       return data_->internal::faces_set_mixin<D, D>::fold_left_(f, accu);
00846     }
00847 
00848     namespace internal
00849     {
00850 
00851       // FIXME: Try to factor.
00852 
00853       template <unsigned D>
00854       template <typename BinaryFunction, typename T>
00855       inline
00856       T
00857       faces_set_mixin<D, D>::fold_left_(const BinaryFunction& f,
00858                                         const T& accu) const
00859       {
00860         return faces_set_mixin<D - 1, D>::fold_left_(f, f(accu, faces_));
00861       }
00862 
00863       template <unsigned N, unsigned D>
00864       template <typename BinaryFunction, typename T>
00865       inline
00866       T
00867       faces_set_mixin<N, D>::fold_left_(const BinaryFunction& f,
00868                                         const T& accu) const
00869       {
00870         return faces_set_mixin<N - 1, D>::fold_left_(f, f(accu, faces_));
00871       }
00872 
00873       template <unsigned D>
00874       template <typename BinaryFunction, typename T>
00875       inline
00876       T
00877       faces_set_mixin<0u, D>::fold_left_(const BinaryFunction& f,
00878                                          const T& accu) const
00879       {
00880         return f(accu, faces_);
00881       }
00882 
00883       template <typename BinaryFunction, typename T>
00884       inline
00885       T
00886       faces_set_mixin<0u, 0u>::fold_left_(const BinaryFunction& f,
00887                                           const T& accu) const
00888       {
00889         return f(accu, faces_);
00890       }
00891 
00892     } // end of namespace mln::topo::internal
00893 
00894 
00895     /* ------------------------------------------------ */
00896     /* ``Static Apply-If-Dimension-Matches'' Operator.  */
00897     /* ------------------------------------------------ */
00898 
00899     template <unsigned D>
00900     template <typename UnaryFunction>
00901     inline
00902     typename UnaryFunction::result_type
00903     complex<D>::apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const
00904     {
00905       // Ensure N is compatible with D.
00906       mln_precondition(n <= D);
00907       return data_->internal::faces_set_mixin<D, D>::apply_if_dim_matches_(n, f);
00908     }
00909 
00910     namespace internal
00911     {
00912 
00913       // FIXME: Try to factor.
00914 
00915       template <unsigned D>
00916       template <typename UnaryFunction>
00917       inline
00918       typename UnaryFunction::result_type
00919       faces_set_mixin<D, D>::apply_if_dim_matches_(unsigned n,
00920                                                    const UnaryFunction& f) const
00921       {
00922         // Ensure N and D are compatible.
00923         mln_precondition(n <= D);
00924         return n == D ?
00925           f(faces_) :
00926           faces_set_mixin<D - 1, D>::apply_if_dim_matches_(n, f);
00927       }
00928 
00929       template <unsigned N, unsigned D>
00930       template <typename UnaryFunction>
00931       inline
00932       typename UnaryFunction::result_type
00933       faces_set_mixin<N, D>::apply_if_dim_matches_(unsigned n,
00934                                                    const UnaryFunction& f) const
00935       {
00936         // Ensure N and D are compatible.
00937         mln_precondition(n <= D);
00938         return n == N ?
00939           f(faces_) :
00940           faces_set_mixin<N - 1, D>::apply_if_dim_matches_(n, f);
00941       }
00942 
00943       template <unsigned D>
00944       template <typename UnaryFunction>
00945       inline
00946       typename UnaryFunction::result_type
00947       faces_set_mixin<0u, D>::apply_if_dim_matches_(unsigned n,
00948                                                     const UnaryFunction& f) const
00949       {
00950         // If we reached this method, then N should be 0.
00951         mln_precondition(n == 0);
00952         // Prevent ``unused variable'' warnings when NDEBUG is defined.
00953         (void) n;
00954         return f(faces_);
00955       }
00956 
00957       template <typename UnaryFunction>
00958       inline
00959       typename UnaryFunction::result_type
00960       faces_set_mixin<0u, 0u>::apply_if_dim_matches_(unsigned n,
00961                                                      const UnaryFunction& f) const
00962       {
00963         // If we reached this method, then N should be 0.
00964         mln_precondition(n == 0);
00965         // Prevent ``unused variable'' warnings when NDEBUG is defined.
00966         (void) n;
00967         return f(faces_);
00968       }
00969 
00970     } // end of namespace mln::topo::internal
00971 
00972 # endif // ! MLN_INCLUDE_ONLY
00973 
00974   } // end of namespace mln::topo
00975 
00976 } // end of namespace mln
00977 
00978 #endif // ! MLN_TOPO_COMPLEX_HH

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