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;
99 struct fwd_fiter {
typedef faces_fwd_iter_<N, D> ret; };
101 template <
unsigned N>
102 struct bkd_fiter {
typedef faces_bkd_iter_<N, D> ret; };
117 template <
unsigned N>
118 n_face<N + 1, D>
add_face(
const n_faces_set<N, D>& adjacent_faces);
130 template <
unsigned N>
150 void print(std::ostream& ostr)
const;
152 template <
unsigned N>
160 const void*
addr()
const;
166 template <
unsigned D_>
167 friend bool operator==(
const complex<D_>& lhs,
const complex<D_>& rhs);
171 template <
unsigned N,
unsigned D_>
friend class n_face;
172 template <
unsigned D_>
friend class face;
174 template <
unsigned N>
175 face_data<N, D>& face_data_(
unsigned face_id);
177 template <
unsigned N>
178 const face_data<N, D>& face_data_(
unsigned face_id)
const;
198 template <
typename BinaryFunction,
typename T>
199 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
202 template <
typename UnaryFunction>
203 typename UnaryFunction::result_type
204 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
213 template <
unsigned N>
220 template <
unsigned D>
226 template <
unsigned D>
228 operator<<(std::ostream& ostr, const complex<D>& c);
299 template <
unsigned N,
unsigned D>
struct lower_dim_faces_set_mixin;
300 template <
unsigned N,
unsigned D>
struct higher_dim_faces_set_mixin;
309 template <
unsigned N,
unsigned D>
struct faces_set_mixin;
313 template <
unsigned N,
unsigned D>
314 struct faces_set_mixin :
public faces_set_mixin<N - 1, D>,
315 public lower_dim_faces_set_mixin<N, D>,
316 public higher_dim_faces_set_mixin<N, D>
318 std::vector< face_data<N, D> > faces_;
323 void print(std::ostream& ostr)
const;
326 void print_rec_asc(std::ostream& ostr)
const;
333 template <
typename BinaryFunction,
typename T>
334 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
337 template <
typename UnaryFunction>
338 typename UnaryFunction::result_type
339 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
344 template <
unsigned D>
345 struct faces_set_mixin<D, D> :
public faces_set_mixin<D - 1, D>,
346 public lower_dim_faces_set_mixin<D, D>
348 std::vector< face_data<D, D> > faces_;
353 void print(std::ostream& ostr)
const;
354 void print_rec_asc(std::ostream& ostr)
const;
361 template <
typename BinaryFunction,
typename T>
362 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
365 template <
typename UnaryFunction>
366 typename UnaryFunction::result_type
367 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
372 template <
unsigned D>
373 struct faces_set_mixin<0u, D> :
public higher_dim_faces_set_mixin<0u, D>
375 std::vector< face_data<0u, D> > faces_;
380 void print(std::ostream& ostr)
const;
381 void print_rec_asc(std::ostream& ostr)
const;
388 template <
typename BinaryFunction,
typename T>
389 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
392 template <
typename UnaryFunction>
393 typename UnaryFunction::result_type
394 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
400 struct faces_set_mixin<0u, 0u>
402 std::vector< face_data<0u, 0u> > faces_;
407 void print(std::ostream& ostr)
const;
408 void print_rec_asc(std::ostream& ostr)
const;
415 template <
typename BinaryFunction,
typename T>
416 T fold_left_(
const BinaryFunction& f,
const T& accu)
const;
419 template <
typename UnaryFunction>
420 typename UnaryFunction::result_type
421 apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const;
432 template <
unsigned D>
433 struct complex_data :
public faces_set_mixin<D, D>
446 template <
unsigned N,
unsigned D>
447 struct lower_dim_faces_set_mixin
449 void print(std::ostream& ostr,
const face_data<N, D>& f)
const;
452 template <
unsigned N,
unsigned D>
453 struct higher_dim_faces_set_mixin
455 void print(std::ostream& ostr,
const face_data<N, D>& f)
const;
463 # ifndef MLN_INCLUDE_ONLY
469 template <
unsigned D>
473 : data_(new internal::complex_data<D>())
477 template <
unsigned D>
484 data_->internal::faces_set_mixin<0u, D>::faces_.push_back(face_data<0u, D>());
485 unsigned id = nfaces_of_static_dim<0u>() - 1;
489 template <
unsigned D>
490 template <
unsigned N>
495 typedef typename std::vector< algebraic_n_face<N, D> >::const_iterator
500 for (iter_t a = adjacent_faces.
faces().begin();
501 a != adjacent_faces.
faces().end(); ++a)
503 mln_precondition(a->cplx() == *
this);
504 mln_precondition(a->is_valid());
507 face_data<N + 1, D> f;
510 data_->internal::faces_set_mixin<N + 1, D>::faces_.push_back(f);
511 unsigned id = nfaces_of_static_dim<N + 1>() - 1;
515 for (iter_t a = adjacent_faces.
faces().begin();
516 a != adjacent_faces.
faces().end(); ++a)
543 template <
typename T,
typename Container>
544 T operator()(
const T& x,
const Container& c)
const
560 typedef std::size_t result_type;
562 template <
typename Container>
563 typename Container::size_type operator()(
const Container& c)
const
576 template <
unsigned D>
581 return fold_left_(internal::add_size(), 0);
584 template <
unsigned D>
585 template <
unsigned N>
590 return data_->internal::faces_set_mixin<N, D>::faces_.size();
598 template <
unsigned D>
604 mln_precondition(n <= D);
605 return apply_if_dim_matches_(n, internal::get_size());
613 template <
unsigned D>
614 template <
unsigned N>
619 return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
622 template <
unsigned D>
623 template <
unsigned N>
625 const face_data<N, D>&
626 complex<D>::face_data_(
unsigned face_id)
const
628 return data_->internal::faces_set_mixin<N, D>::faces_[face_id];
631 template <
unsigned D>
632 template <
unsigned N>
635 complex<D>::connect_(
const algebraic_n_face<N, D>& f1,
636 const n_face<N + 1, D>& f2)
639 metal::bool_< N <= D >::check();
646 f2.data().connect_lower_dim_face(f1);
654 template <
unsigned D>
659 return lhs.data_.ptr_ == rhs.data_.ptr_;
667 template <
unsigned D>
670 operator<<(std::ostream& ostr, const complex<D>& c)
676 template <
unsigned D>
681 data_->internal::faces_set_mixin<D, D>::print_rec_asc(ostr);
684 template <
unsigned D>
685 template <
unsigned N>
691 metal::bool_< N <= D >::check();
693 data_->internal::faces_set_mixin<N, D>::print(ostr);
696 template <
unsigned D>
708 template <
unsigned N,
unsigned D>
711 faces_set_mixin<N, D>::print_rec_asc(std::ostream& ostr)
const
713 faces_set_mixin<N - 1, D>::print_rec_asc(ostr);
717 template <
unsigned D>
720 faces_set_mixin<0u, D>::print_rec_asc(std::ostream& ostr)
const
725 template <
unsigned D>
728 faces_set_mixin<D, D>::print_rec_asc(std::ostream& ostr)
const
730 faces_set_mixin<D - 1, D>::print_rec_asc(ostr);
736 faces_set_mixin<0u, 0u>::print_rec_asc(std::ostream& ostr)
const
742 template <
unsigned N,
unsigned D>
745 faces_set_mixin<N, D>::print(std::ostream& ostr)
const
747 ostr <<
"Faces of dimension " << N
748 <<
" and their ajacent faces of dimension "
750 << N + 1 << std::endl;
751 for (
unsigned f = 0; f < faces_.size(); ++f)
753 ostr <<
" " << f <<
": dim " << N - 1 <<
": { ";
754 lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
755 ostr <<
"}, dim " << N + 1 <<
": { ";
756 higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
757 ostr <<
"}" << std::endl;
761 template <
unsigned D>
764 faces_set_mixin<0u, D>::print(std::ostream& ostr)
const
766 const unsigned N = 0u;
767 ostr <<
"Faces of dimension " << N
768 <<
" and their ajacent faces of dimension "
769 << N + 1 << std::endl;
770 for (
unsigned f = 0; f < faces_.size(); ++f)
772 ostr <<
" " << f <<
": dim " << N + 1 <<
": { ";
773 higher_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
774 ostr <<
"}" << std::endl;
778 template <
unsigned D>
781 faces_set_mixin<D, D>::print(std::ostream& ostr)
const
783 const unsigned N = D;
784 ostr <<
"Faces of dimension " << N
785 <<
" and their ajacent faces of dimension "
786 << N - 1 << std::endl;
787 for (
unsigned f = 0; f < faces_.size(); ++f)
789 ostr <<
" " << f <<
": dim " << N - 1 <<
": { ";
790 lower_dim_faces_set_mixin<N, D>::print(ostr, faces_[f]);
791 ostr <<
"}" << std::endl;
797 faces_set_mixin<0u, 0u>::print(std::ostream& ostr)
const
799 const unsigned N = 0u;
800 ostr <<
"Faces of dimension " << N << std::endl;
801 for (
unsigned f = 0; f < faces_.size(); ++f)
802 ostr <<
" " << f << std::endl;
806 template <
unsigned N,
unsigned D>
809 lower_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
810 const face_data<N, D>& f)
const
812 for (
typename std::vector< algebraic_n_face<N - 1, D> >::const_iterator l =
813 f.lower_dim_faces_.begin(); l != f.lower_dim_faces_.end(); ++l)
814 ostr << l->face_id() <<
" ";
817 template <
unsigned N,
unsigned D>
820 higher_dim_faces_set_mixin<N, D>::print(std::ostream& ostr,
821 const face_data<N, D>& f)
const
823 for (
typename std::vector< algebraic_n_face<N + 1, D> >::const_iterator h =
824 f.higher_dim_faces_.begin(); h != f.higher_dim_faces_.end(); ++h)
825 ostr << h->face_id() <<
" ";
839 template <
unsigned D>
840 template <
typename BinaryFunction,
typename T>
843 complex<D>::fold_left_(
const BinaryFunction& f,
const T& accu)
const
845 return data_->internal::faces_set_mixin<D, D>::fold_left_(f, accu);
853 template <
unsigned D>
854 template <
typename BinaryFunction,
typename T>
857 faces_set_mixin<D, D>::fold_left_(
const BinaryFunction& f,
860 return faces_set_mixin<D - 1, D>::fold_left_(f, f(accu, faces_));
863 template <
unsigned N,
unsigned D>
864 template <
typename BinaryFunction,
typename T>
867 faces_set_mixin<N, D>::fold_left_(
const BinaryFunction& f,
870 return faces_set_mixin<N - 1, D>::fold_left_(f, f(accu, faces_));
873 template <
unsigned D>
874 template <
typename BinaryFunction,
typename T>
877 faces_set_mixin<0u, D>::fold_left_(
const BinaryFunction& f,
880 return f(accu, faces_);
883 template <
typename BinaryFunction,
typename T>
886 faces_set_mixin<0u, 0u>::fold_left_(
const BinaryFunction& f,
889 return f(accu, faces_);
899 template <
unsigned D>
900 template <
typename UnaryFunction>
902 typename UnaryFunction::result_type
903 complex<D>::apply_if_dim_matches_(
unsigned n,
const UnaryFunction& f)
const
906 mln_precondition(n <= D);
907 return data_->internal::faces_set_mixin<D, D>::apply_if_dim_matches_(n, f);
915 template <
unsigned D>
916 template <
typename UnaryFunction>
918 typename UnaryFunction::result_type
919 faces_set_mixin<D, D>::apply_if_dim_matches_(
unsigned n,
920 const UnaryFunction& f)
const
923 mln_precondition(n <= D);
926 faces_set_mixin<D - 1, D>::apply_if_dim_matches_(n, f);
929 template <
unsigned N,
unsigned D>
930 template <
typename UnaryFunction>
932 typename UnaryFunction::result_type
933 faces_set_mixin<N, D>::apply_if_dim_matches_(
unsigned n,
934 const UnaryFunction& f)
const
937 mln_precondition(n <= D);
940 faces_set_mixin<N - 1, D>::apply_if_dim_matches_(n, f);
943 template <
unsigned D>
944 template <
typename UnaryFunction>
946 typename UnaryFunction::result_type
947 faces_set_mixin<0u, D>::apply_if_dim_matches_(
unsigned n,
948 const UnaryFunction& f)
const
951 mln_precondition(n == 0);
957 template <
typename UnaryFunction>
959 typename UnaryFunction::result_type
960 faces_set_mixin<0u, 0u>::apply_if_dim_matches_(
unsigned n,
961 const UnaryFunction& f)
const
964 mln_precondition(n == 0);
972 # endif // ! MLN_INCLUDE_ONLY
978 #endif // ! MLN_TOPO_COMPLEX_HH