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

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

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