* 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(a)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(a)lrde.epita.fr>
+
* tests/topo/complex.cc: Fix diagram in documentation.
2008-09-30 Roland Levillain <roland(a)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