2438: Add accesses to adjacent faces to mln::topo::face<D>.

* mln/topo/face.hh (mln::topo::face<D>::lower_dim_adj_faces) (mln::topo::face<D>::higher_dim_adj_faces): New. (mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D>) (mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D>): New classes. * mln/topo/face_data.hh (mln::topo::internal::lower_dim_faces_data_mixin<N, D>): Allow mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D> to access to private data. (mln::topo::internal::higher_dim_faces_data_mixin<N, D>): Allow mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D> to access to private data. * tests/topo/complex.cc: Exercise accesses to adjacent faces. --- milena/ChangeLog | 20 +++++++ milena/mln/topo/face.hh | 121 ++++++++++++++++++++++++++++++++++++++++++ milena/mln/topo/face_data.hh | 9 +++ milena/tests/topo/complex.cc | 25 +++++++++ 4 files changed, 175 insertions(+), 0 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 42ea6ad..a376900 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,25 @@ 2008-09-30 Roland Levillain <roland@lrde.epita.fr> + Add accesses to adjacent faces to mln::topo::face<D>. + + * mln/topo/face.hh + (mln::topo::face<D>::lower_dim_adj_faces) + (mln::topo::face<D>::higher_dim_adj_faces): + New. + (mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D>) + (mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D>): + New classes. + * mln/topo/face_data.hh + (mln::topo::internal::lower_dim_faces_data_mixin<N, D>): Allow + mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D> to + access to private data. + (mln::topo::internal::higher_dim_faces_data_mixin<N, D>): Allow + mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D> to + access to private data. + * tests/topo/complex.cc: Exercise accesses to adjacent faces. + +2008-09-30 Roland Levillain <roland@lrde.epita.fr> + * tests/topo/complex.cc: Fix diagram in documentation. 2008-09-30 Roland Levillain <roland@lrde.epita.fr> diff --git a/milena/mln/topo/face.hh b/milena/mln/topo/face.hh index 0d32c33..c485697 100644 --- a/milena/mln/topo/face.hh +++ b/milena/mln/topo/face.hh @@ -96,6 +96,13 @@ namespace mln /// Return the mln::topo::face_data pointed by this handle. template <unsigned N> face_data<N, D>& data() const; + + // FIXME: To be overhauled. + // FIXME: Why no `const' here? + /// Return an array of face handles pointing to adjacent (n-1)-faces. + std::vector< face<D> > lower_dim_adj_faces(); + /// Return an array of face handles pointing to adjacent (n+1)-faces. + std::vector< face<D> > higher_dim_adj_faces(); /// \} private: @@ -251,6 +258,120 @@ namespace mln } + // FIXME: This is way too complicated. + namespace internal + { + template <unsigned N, unsigned D> + struct lower_dim_adj_faces_if_dim_matches_ + { + std::vector< face<D> > operator()(face<D>& face) + { + metal::bool_< (N <= D) >::check(); + metal::bool_< (N > 1) >::check(); + + if (face.n() == N) + { + face_data<N, D>& data = face.template data<N>(); + std::vector< n_face<N - 1, D> > lower_dim_faces = + data.lower_dim_faces_; + std::vector< topo::face<D> > result; + for (typename std::vector< n_face<N - 1, D> >::const_iterator f = + lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f) + result.push_back(*f); + return result; + } + else + return internal::lower_dim_adj_faces_if_dim_matches_<N - 1, D>()(face); + } + }; + + template <unsigned D> + struct lower_dim_adj_faces_if_dim_matches_<1, D> + { + std::vector< face<D> > operator()(face<D>& face) + { + /// If we reached this function, then the dimension of FACE + /// has to be 1. + mln_precondition(face.n() == 1); + face_data<1, D>& data = face.template data<1>(); + std::vector< n_face<0, D> > lower_dim_faces = data.lower_dim_faces_; + std::vector< topo::face<D> > result; + for (typename std::vector< n_face<0, D> >::const_iterator f = + lower_dim_faces.begin(); f != lower_dim_faces.end(); ++f) + result.push_back(*f); + return result; + } + }; + + template <unsigned N, unsigned D> + struct higher_dim_adj_faces_if_dim_matches_ + { + std::vector< face<D> > operator()(face<D>& face) + { + metal::bool_< (N < D) >::check(); + + if (face.n() == N) + { + face_data<N, D>& data = face.template data<N>(); + std::vector< n_face<N + 1, D> > higher_dim_faces = + data.higher_dim_faces_; + std::vector< topo::face<D> > result; + for (typename std::vector< n_face<N + 1, D> >::const_iterator f = + higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f) + result.push_back(*f); + return result; + } + else + return + internal::higher_dim_adj_faces_if_dim_matches_<N - 1, D>()(face); + } + }; + + template <unsigned D> + struct higher_dim_adj_faces_if_dim_matches_<0, D> + { + std::vector< face<D> > operator()(face<D>& face) + { + /// If we reached this function, then the dimension of face + /// has to be D - 1. + mln_precondition(face.n() == 0); + face_data<0, D>& data = face.template data<0>(); + std::vector< n_face<1, D> > higher_dim_faces = + data.higher_dim_faces_; + std::vector< topo::face<D> > result; + for (typename std::vector< n_face<1, D> >::const_iterator f = + higher_dim_faces.begin(); f != higher_dim_faces.end(); ++f) + result.push_back(*f); + return result; + } + }; + } + + template <unsigned D> + inline + std::vector< face<D> > + face<D>::lower_dim_adj_faces() + { + // FIXME: Warning: might prevent any attempt to build a complex<0>. + metal::bool_< D != 0 >::check(); + + mln_precondition(n_ > 0); + return internal::lower_dim_adj_faces_if_dim_matches_<D, D>()(*this); + } + + template <unsigned D> + inline + std::vector< face<D> > + face<D>::higher_dim_adj_faces() + { + // FIXME: Warning: might prevent any attempt to build a complex<0>. + metal::bool_< D != 0 >::check(); + + mln_precondition(n_ < D); + return internal::higher_dim_adj_faces_if_dim_matches_<D - 1, D>()(*this); + } + + template <unsigned D> inline bool diff --git a/milena/mln/topo/face_data.hh b/milena/mln/topo/face_data.hh index 7c94ddd..28d425e 100644 --- a/milena/mln/topo/face_data.hh +++ b/milena/mln/topo/face_data.hh @@ -51,6 +51,11 @@ namespace mln { template <unsigned N, unsigned D> struct lower_dim_faces_set_mixin; template <unsigned N, unsigned D> struct higher_dim_faces_set_mixin; + + template <unsigned N, unsigned D> + struct lower_dim_adj_faces_if_dim_matches_; + template <unsigned N, unsigned D> + struct higher_dim_adj_faces_if_dim_matches_; } // Forward declarations (internal). @@ -109,6 +114,8 @@ namespace mln void connect_lower_dim_face (const n_face<N - 1, D>& f); private: friend class mln::topo::internal::lower_dim_faces_set_mixin<N, D>; + friend class mln::topo::internal::lower_dim_adj_faces_if_dim_matches_<N, D>; + // FIXME: Rename as lower_dim_adj_faces_? std::vector< n_face<N - 1, D> > lower_dim_faces_; }; @@ -119,6 +126,8 @@ namespace mln void connect_higher_dim_face(const n_face<N + 1, D>& f); private: friend class mln::topo::internal::higher_dim_faces_set_mixin<N, D>; + friend class mln::topo::internal::higher_dim_adj_faces_if_dim_matches_<N, D>; + // FIXME: Rename as higher_dim_adj_faces_? std::vector< n_face<N + 1, D> > higher_dim_faces_; }; /// \} diff --git a/milena/tests/topo/complex.cc b/milena/tests/topo/complex.cc index d4f824a..349921c 100644 --- a/milena/tests/topo/complex.cc +++ b/milena/tests/topo/complex.cc @@ -28,6 +28,8 @@ /// \file tests/topo/complex.cc /// \brief Test of mln::complex. +#include <algorithm> +#include <iterator> #include <iostream> #include <mln/topo/complex.hh> @@ -114,6 +116,8 @@ int main() // Get the face data from (``static'') face handle E0. const topo::face_data<1, D>& face1 = e0.data(); + /* FIXME: Rename AF (everywhere) as `any-face handles' have been + renamed to `face'. */ // Any-face handle. topo::face<D> af(e0); // Get the face data from (``dynamic'') face handle AF. @@ -121,6 +125,27 @@ int main() mln_assertion(&face1 == &face2); + /*-----------------. + | Adjacent faces. | + `-----------------*/ + + // Adjacent lower-dimension faces of AF. + std::vector< topo::face<D> > af_lower_dim_adj_faces = + af.lower_dim_adj_faces(); + std::cout << "lower-dimension faces adjacent to " << af << ":" << std::endl; + std::copy (af_lower_dim_adj_faces.begin(), af_lower_dim_adj_faces.end(), + std::ostream_iterator< topo::face<D> > (std::cout, "\n")); + std::cout << std::endl; + + // Adjacent higher-dimension faces of AF. + std::vector< topo::face<D> > af_higher_dim_adj_faces = + af.higher_dim_adj_faces(); + std::cout << "higher-dimension faces adjacent to " << af << ":" << std::endl; + std::copy (af_higher_dim_adj_faces.begin(), af_higher_dim_adj_faces.end(), + std::ostream_iterator< topo::face<D> > (std::cout, "\n")); + std::cout << std::endl; + + /*------------. | Iteration. | `------------*/ -- 1.6.0.1
participants (1)
-
Roland Levillain