27 #ifndef MLN_TOPO_COMPLEX_HH
28 # define MLN_TOPO_COMPLEX_HH
41 # include <mln/metal/bool.hh>
43 # include <mln/util/tracked_ptr.hh>
45 # include <mln/topo/face_data.hh>
46 # include <mln/topo/algebraic_face.hh>
47 # include <mln/topo/algebraic_n_face.hh>
48 # include <mln/topo/n_faces_set.hh>
50 # include <mln/topo/complex_iterators.hh>
60 template <
unsigned N,
unsigned D>
class n_faces_set;
61 template <
unsigned D>
class face_fwd_iter;
62 template <
unsigned D>
class face_bkd_iter;
65 template <
unsigned N,
unsigned D>
class faces_fwd_iter_;
66 template <
unsigned N,
unsigned D>
class faces_bkd_iter_;
75 template <
unsigned N,
unsigned D>
76 struct faces_set_mixin;
102 template <
unsigned N>
118 template <
unsigned N>
119 n_face<N + 1, D>
add_face(
const n_faces_set<N, D>& adjacent_faces);
131 template <
unsigned N>
151 void print(std::ostream& ostr)
const;
153 template <
unsigned N>
161 const void*
addr()
const;
167 template <
unsigned D_>
168 friend bool operator==(
const complex<D_>& lhs,
const complex<D_>&
rhs);
172 template <
unsigned N,
unsigned D_>
friend class n_face;
173 template <
unsigned D_>
friend class face;
175 template <
unsigned N>
178 template <
unsigned N>
199 template <
typename BinaryFunction,
typename T>
200 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
203 template <
typename UnaryFunction>
204 typename UnaryFunction::result_type
205 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
214 template <
unsigned N>
221 template <
unsigned D>
227 template <
unsigned D>
229 operator<<(std::ostream& ostr, const complex<D>& c);
300 template <
unsigned N,
unsigned D>
struct lower_dim_faces_set_mixin;
301 template <
unsigned N,
unsigned D>
struct higher_dim_faces_set_mixin;
310 template <
unsigned N,
unsigned D>
struct faces_set_mixin;
317 template <
unsigned N,
unsigned D>
327 void print(std::ostream& ostr)
const;
337 template <
typename BinaryFunction,
typename T>
338 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
341 template <
typename UnaryFunction>
342 typename UnaryFunction::result_type
351 template <
unsigned D>
360 void print(std::ostream& ostr)
const;
368 template <
typename BinaryFunction,
typename T>
369 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
372 template <
typename UnaryFunction>
373 typename UnaryFunction::result_type
382 template <
unsigned D>
390 void print(std::ostream& ostr)
const;
398 template <
typename BinaryFunction,
typename T>
399 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
402 template <
typename UnaryFunction>
403 typename UnaryFunction::result_type
420 void print(std::ostream& ostr)
const;
428 template <
typename BinaryFunction,
typename T>
429 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
432 template <
typename UnaryFunction>
433 typename UnaryFunction::result_type
448 template <
unsigned D>
462 template <
unsigned N,
unsigned D>
468 template <
unsigned N,
unsigned D>
479 # ifndef MLN_INCLUDE_ONLY
485 template <
unsigned D>
489 : data_(new internal::complex_data<D>())
493 template <
unsigned D>
496 complex<D>::add_face()
500 std::vector< face_data<0, D> >& faces_0 =
501 static_cast< internal::faces_set_mixin<0, D>&
>(*data_).faces_;
504 faces_0.push_back(face_data<0, D>());
505 unsigned id = nfaces_of_static_dim<0>() - 1;
506 return n_face<0, D>(*
this,
id);
509 template <
unsigned D>
510 template <
unsigned N>
513 complex<D>::add_face(
const n_faces_set<N, D>& adjacent_faces)
515 typedef typename std::vector< algebraic_n_face<N, D> >::const_iterator
520 for (iter_t a = adjacent_faces.faces().begin();
521 a != adjacent_faces.faces().end(); ++a)
523 mln_precondition(a->cplx() == *
this);
524 mln_precondition(a->is_valid());
527 face_data<N + 1, D> f;
530 std::vector< face_data<N + 1, D> >& faces_n_plus_1 =
531 static_cast< internal::faces_set_mixin<N + 1, D>&
>(*data_).faces_;
534 faces_n_plus_1.push_back(f);
535 unsigned id = nfaces_of_static_dim<N + 1>() - 1;
537 n_face<N + 1, D> fh(*
this,
id);
539 for (iter_t a = adjacent_faces.faces().begin();
540 a != adjacent_faces.faces().end(); ++a)
570 template <
typename T,
typename Container>
571 T operator()(
const T& x,
const Container& c)
const
590 typedef std::size_t result_type;
592 template <
typename Container>
593 typename Container::size_type operator()(
const Container& c)
const
606 template <
unsigned D>
609 complex<D>::nfaces()
const
611 return fold_left_(internal::add_size(), 0);
614 template <
unsigned D>
615 template <
unsigned N>
618 complex<D>::nfaces_of_static_dim()
const
622 const std::vector< face_data<N, D> >& faces_n =
623 static_cast< const internal::faces_set_mixin<N, D>&
>(*data_).faces_;
624 return faces_n.size();
632 template <
unsigned D>
635 complex<D>::nfaces_of_dim(
unsigned n)
const
638 mln_precondition(n <= D);
639 return apply_if_dim_matches_(n, internal::get_size());
647 template <
unsigned D>
648 template <
unsigned N>
651 complex<D>::face_data_(
unsigned face_id)
655 std::vector< face_data<N, D> >& faces_n =
656 static_cast< internal::faces_set_mixin<N, D>&
>(*data_).faces_;
657 return faces_n[face_id];
660 template <
unsigned D>
661 template <
unsigned N>
664 complex<D>::face_data_(
unsigned face_id)
const
668 const std::vector< face_data<N, D> >& faces_n =
669 static_cast< const internal::faces_set_mixin<N, D>&
>(*data_).faces_;
670 return faces_n[face_id];
673 template <
unsigned D>
674 template <
unsigned N>
677 complex<D>::connect_(
const algebraic_n_face<N, D>& f1,
678 const n_face<N + 1, D>& f2)
681 metal::bool_< N <= D >::check();
688 f2.data().connect_lower_dim_face(f1);
696 template <
unsigned D>
701 return lhs.data_.ptr_ == rhs.data_.ptr_;
709 template <
unsigned D>
712 operator<<(std::ostream& ostr, const complex<D>& c)
718 template <
unsigned D>
721 complex<D>::print(std::ostream& ostr)
const
725 static_cast< const internal::faces_set_mixin<D, D>&
>(*data_).print_rec_asc(ostr);
728 template <
unsigned D>
729 template <
unsigned N>
732 complex<D>::print_faces(std::ostream& ostr)
const
735 metal::bool_< N <= D >::check();
739 static_cast< const internal::faces_set_mixin<N, D>&
>(*data_).print(ostr);
742 template <
unsigned D>
745 complex<D>::addr()
const
754 template <
unsigned N,
unsigned D>
757 faces_set_mixin<N, D>::print_rec_asc(std::ostream& ostr)
const
759 faces_set_mixin<N - 1, D>::print_rec_asc(ostr);
763 template <
unsigned D>
771 template <
unsigned D>
788 template <
unsigned N,
unsigned D>
791 faces_set_mixin<N, D>::print(std::ostream& ostr)
const
793 ostr <<
"Faces of dimension " << N
794 <<
" and their ajacent faces of dimension "
796 << N + 1 << std::endl;
797 for (
unsigned f = 0; f < faces_.size(); ++f)
799 ostr <<
" " << f <<
": dim " << N - 1 <<
": { ";
800 lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
801 ostr <<
"}, dim " << N + 1 <<
": { ";
802 higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
803 ostr <<
"}" << std::endl;
807 template <
unsigned D>
812 const unsigned N = 0;
813 ostr <<
"Faces of dimension " << N
814 <<
" and their ajacent faces of dimension "
815 << N + 1 << std::endl;
816 for (
unsigned f = 0; f < faces_.size(); ++f)
818 ostr <<
" " << f <<
": dim " << N + 1 <<
": { ";
819 higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
820 ostr <<
"}" << std::endl;
824 template <
unsigned D>
829 const unsigned N = D;
830 ostr <<
"Faces of dimension " << N
831 <<
" and their ajacent faces of dimension "
832 << N - 1 << std::endl;
833 for (
unsigned f = 0; f < faces_.size(); ++f)
835 ostr <<
" " << f <<
": dim " << N - 1 <<
": { ";
836 lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
837 ostr <<
"}" << std::endl;
845 const unsigned N = 0;
846 ostr <<
"Faces of dimension " << N << std::endl;
847 for (
unsigned f = 0; f < faces_.size(); ++f)
848 ostr <<
" " << f << std::endl;
852 template <
unsigned N,
unsigned D>
855 lower_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
858 for (
typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator l =
859 f.lower_dim_faces_.begin(); l != f.lower_dim_faces_.end(); ++l)
860 ostr << l->face_id() <<
" ";
863 template <
unsigned N,
unsigned D>
866 higher_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
869 for (
typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator h =
870 f.higher_dim_faces_.begin(); h != f.higher_dim_faces_.end(); ++h)
871 ostr << h->face_id() <<
" ";
885 template <
unsigned D>
886 template <
typename BinaryFunction,
typename T>
889 complex<D>::fold_left_(
const BinaryFunction& f,
const T& accu)
const
893 return static_cast< const internal::faces_set_mixin<D, D>&
>(*data_).fold_left_(f, accu);
901 template <
unsigned D>
902 template <
typename BinaryFunction,
typename T>
910 return static_cast< const faces_set_mixin<D - 1, D
>& >(*this).fold_left_(f, f(accu, faces_));
913 template <
unsigned N,
unsigned D>
914 template <
typename BinaryFunction,
typename T>
917 faces_set_mixin<N, D>::fold_left_(
const BinaryFunction& f,
922 return static_cast< const faces_set_mixin<N - 1, D
>& >(*this).fold_left_(f, f(accu, faces_));
925 template <
unsigned D>
926 template <
typename BinaryFunction,
typename T>
932 return f(accu, faces_);
935 template <
typename BinaryFunction,
typename T>
941 return f(accu, faces_);
951 template <
unsigned D>
952 template <
typename UnaryFunction>
954 typename UnaryFunction::result_type
955 complex<D>::apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const
958 mln_precondition(n <= D);
961 return static_cast< const internal::faces_set_mixin<D, D>&
>(*data_).apply_if_dim_matches_(n, f);
969 template <
unsigned D>
970 template <
typename UnaryFunction>
972 typename UnaryFunction::result_type
974 const UnaryFunction& f)
const
977 mln_precondition(n <= D);
980 faces_set_mixin<D - 1, D>::apply_if_dim_matches_(n, f);
983 template <
unsigned N,
unsigned D>
984 template <
typename UnaryFunction>
986 typename UnaryFunction::result_type
987 faces_set_mixin<N, D>::apply_if_dim_matches_(
unsigned n,
988 const UnaryFunction& f)
const
991 mln_precondition(n <= D);
994 faces_set_mixin<N - 1, D>::apply_if_dim_matches_(n, f);
997 template <
unsigned D>
998 template <
typename UnaryFunction>
1000 typename UnaryFunction::result_type
1002 const UnaryFunction& f)
const
1005 mln_precondition(n == 0);
1011 template <
typename UnaryFunction>
1013 typename UnaryFunction::result_type
1015 const UnaryFunction& f)
const
1018 mln_precondition(n == 0);
1026 # endif // ! MLN_INCLUDE_ONLY
1032 #endif // ! MLN_TOPO_COMPLEX_HH