27 #ifndef MLN_MORPHO_TREE_DATA_HH
28 # define MLN_MORPHO_TREE_DATA_HH
35 # include <mln/morpho/tree/compute_parent.hh>
36 # include <mln/core/site_set/p_array.hh>
37 # include <mln/core/internal/site_set_iterator_base.hh>
38 # include <mln/core/internal/piter_identity.hh>
43 # define mln_up_site_piter(T) typename T::up_site_piter
44 # define mln_dn_site_piter(T) typename T::dn_site_piter
45 # define mln_up_node_piter(T) typename T::up_node_piter
46 # define mln_dn_node_piter(T) typename T::dn_node_piter
47 # define mln_up_leaf_piter(T) typename T::up_leaf_piter
48 # define mln_dn_leaf_piter(T) typename T::dn_leaf_piter
49 # define mln_site_piter(T) typename T::site_piter
50 # define mln_node_piter(T) typename T::node_piter
51 # define mln_leaf_piter(T) typename T::leaf_piter
52 # define mln_depth1st_piter(T) typename T::depth1st_piter
54 # define mln_up_site_piter_(T) T::up_site_piter
55 # define mln_dn_site_piter_(T) T::dn_site_piter
56 # define mln_up_node_piter_(T) T::up_node_piter
57 # define mln_dn_node_piter_(T) T::dn_node_piter
58 # define mln_up_leaf_piter_(T) T::up_leaf_piter
59 # define mln_dn_leaf_piter_(T) T::dn_leaf_piter
60 # define mln_site_piter_(T) T::site_piter
61 # define mln_node_piter_(T) T::node_piter
62 # define mln_leaf_piter_(T) T::leaf_piter
63 # define mln_depth1st_piter_(T) T::depth1st_piter
99 template <
typename I,
typename S>
108 typedef mln_psite(I) psite;
109 typedef mln_site(I) site;
113 typedef p_array<mln_psite(I)> nodes_t;
115 typedef p_array<mln_psite(I)> leaves_t;
118 typedef mln_ch_value(I, mln_psite(I)) parent_t;
121 typedef mln_ch_value(I, nodes_t) children_t;
126 typedef up_site_piter site_piter;
131 typedef up_node_piter node_piter;
136 typedef up_leaf_piter leaf_piter;
142 template <typename N>
143 data(const Image<I>& f,
144 const Site_Set<S>& s,
145 const Neighborhood<N>& nbh);
150 data(const Image<I>& f,
151 const parent_t& parent,
152 const Site_Set<S>& s);
156 mln_rvalue(I) f(const mln_psite(I)& p) const;
163 mln_rvalue(parent_t) parent(const mln_psite(I)& p) const;
164 const parent_t& parent_image() const;
170 mln_rvalue(children_t) children(const mln_psite(I)& p) const;
171 const mln_ch_value(I, nodes_t)& children_image() const;
177 const p_array<mln_psite(I)>& nodes() const;
183 const p_array<mln_psite(I)>& leaves() const;
189 const S& domain() const;
197 bool is_valid() const;
198 bool is_root(const mln_psite(I)& p) const;
199 bool is_a_node(const mln_psite(I)& p) const;
200 bool is_a_non_root_node(const mln_psite(I)& p) const;
201 bool is_a_leaf(const mln_psite(I)& p) const;
205 unsigned nroots() const;
208 void compute_children_();
211 mln_ch_value(I, mln_psite(I)) parent_;
212 mln_ch_value(I, nodes_t) children_;
225 template <typename T>
227 : public mln::internal::piter_identity_< typename T::sites_t::bkd_piter,
231 typedef typename T::sites_t::bkd_piter Pi_;
232 typedef mln::internal::piter_identity_< Pi_, up_site_piter<T> > super_;
235 up_site_piter(
const T& t)
237 this->change_target(t.domain());
240 up_site_piter(
const Pi_& pi)
246 template <
typename T>
248 :
public mln::internal::piter_identity_< typename T::sites_t::fwd_piter,
252 typedef typename T::sites_t::fwd_piter Pi_;
253 typedef mln::internal::piter_identity_< Pi_, dn_site_piter<T> > super_;
256 dn_site_piter(
const T& t)
258 this->change_target(t.domain());
261 dn_site_piter(
const Pi_& pi)
267 template <
typename T>
269 :
public mln::internal::piter_identity_< typename T::nodes_t::fwd_piter,
273 typedef typename T::nodes_t::fwd_piter Pi_;
274 typedef mln::internal::piter_identity_< Pi_, up_node_piter<T> > super_;
277 up_node_piter(
const T& t)
279 this->change_target(t.nodes());
282 up_node_piter(
const Pi_& pi)
288 template <
typename T>
290 :
public mln::internal::piter_identity_< typename T::nodes_t::bkd_piter,
294 typedef typename T::nodes_t::bkd_piter Pi_;
295 typedef mln::internal::piter_identity_< Pi_, dn_node_piter<T> > super_;
298 dn_node_piter(
const T& t)
300 this->change_target(t.nodes());
303 dn_node_piter(
const Pi_& pi)
309 template <
typename T>
311 :
public mln::internal::piter_identity_< typename T::leaves_t::fwd_piter,
315 typedef typename T::leaves_t::fwd_piter Pi_;
316 typedef mln::internal::piter_identity_< Pi_, up_leaf_piter<T> > super_;
319 up_leaf_piter(
const T& t)
321 this->change_target(t.leaves());
324 up_leaf_piter(
const Pi_& pi)
330 template <
typename T>
332 :
public mln::internal::piter_identity_< typename T::leaves_t::bkd_piter,
336 typedef typename T::leaves_t::bkd_piter Pi_;
337 typedef mln::internal::piter_identity_< Pi_, dn_leaf_piter<T> > super_;
340 dn_leaf_piter(
const T& t)
342 this->change_target(t.leaves());
345 dn_leaf_piter(
const Pi_& pi)
351 template <
typename T>
353 :
public mln::internal::site_set_iterator_base< T, depth1st_piter<T> >
356 typedef mln::internal::site_set_iterator_base<T, self_> super_;
364 depth1st_piter(
const T& t);
367 depth1st_piter(
const T& t,
368 const mln_psite(T::function)& p);
371 bool is_valid_()
const;
383 void skip_children();
388 std::deque<mln_psite(T::function)> stack_;
389 const mln_psite(T::function)* root_;
396 template <
typename I,
typename S>
399 operator<< (std::ostream& os, const morpho::tree::data<I, S>& t);
402 # ifndef MLN_INCLUDE_ONLY
410 template <
typename I,
typename S>
413 const mln_ch_value(I, mln_psite(I))& parent,
414 const Site_Set<S>& s)
424 template <
typename I,
typename S>
425 template <
typename N>
428 const Site_Set<S>& s,
429 const Neighborhood<N>& nbh)
434 const N& nbh_ = exact(nbh);
435 parent_ = morpho::tree::compute_parent(f_, nbh_, s_);
440 template <
typename I,
typename S>
449 mln_bkd_piter(S) p(s_);
452 if (f_(parent_(p)) != f_(p))
455 children_(parent_(p)).insert(p);
459 else if (parent_(p) == p)
467 mln_assertion(leaves_.nsites() > 0);
471 template <
typename I,
typename S>
473 mln_rvalue_(mln_ch_value(I, mln_psite(I)))
474 data<I,S>::parent(const mln_psite(I)& p)
const
476 mln_precondition(parent_.domain().has(p));
480 template <
typename I,
typename S>
482 const mln_ch_value(I, mln_psite(I))&
485 mln_precondition(is_valid());
489 template <
typename I,
typename S>
494 return parent_.is_valid();
497 template <
typename I,
typename S>
502 mln_precondition(is_valid());
503 mln_precondition(parent_.domain().has(p));
504 return parent_(p) == p;
508 template <
typename I,
typename S>
513 mln_precondition(is_valid());
514 mln_precondition(parent_.domain().has(p));
515 return parent_(p) == p || f_(parent_(p)) != f_(p);
518 template <
typename I,
typename S>
523 mln_precondition(is_valid());
524 mln_precondition(parent_.domain().has(p));
525 return f_(parent_(p)) != f_(p);
529 template <
typename I,
typename S>
534 mln_precondition(is_valid());
535 mln_precondition(children_.domain().has(p));
536 return children_(p).nsites() == 0;
539 template <
typename I,
typename S>
541 const p_array<mln_psite(I)>&
544 mln_precondition(is_valid());
548 template <
typename I,
typename S>
550 const p_array<mln_psite(I)>&
553 mln_precondition(is_valid());
557 template <
typename I,
typename S>
565 template <
typename I,
typename S>
573 template <
typename I,
typename S>
581 template <
typename I,
typename S>
584 data<I,S>::f(const mln_psite(I)& p)
const
589 template <
typename I,
typename S>
591 mln_rvalue_(mln_ch_value(I, p_array<mln_psite(I)>))
592 data<I,S>::children(const mln_psite(I)& p)
const
594 mln_precondition(is_a_node(p));
598 template <
typename I,
typename S>
600 const mln_ch_value(I, p_array<mln_psite(I)>)&
611 template <
typename T>
618 template <
typename T>
623 this->change_target(t);
626 template <
typename T>
629 const mln_psite(T::function)& p)
632 mln_assertion(t.is_a_node(p));
633 this->change_target(t);
636 template <
typename T>
641 return !stack_.empty();
644 template <
typename T>
652 template <
typename T>
658 stack_.push_back(mln_psite(T::function)());
661 stack_.push_back(*root_);
664 mln_dn_node_piter(T) n(*s_);
666 for (n.start(); n.is_valid() && roots < s_->nroots(); n.next())
677 template <
typename T>
684 if (! this->is_valid())
696 mln_fwd_piter(T::nodes_t) child(s_->children(p_));
701 stack_.push_back(child);
705 template <
typename T>
710 while (stack_.size() != 1 && s_->parent(stack_.back()) == p_)
718 template <
typename I,
typename S>
721 operator<< (std::ostream& os, const morpho::tree::data<I, S>& t)
723 typedef morpho::tree::data<I, S> self_t;
726 typedef p_array<mln_psite(self_t)> A;
728 mln_ch_value(
typename self_t::function, A) content;
729 initialize(content, t.f());
731 os << "Nodes:\tValue:\tPoints" << std::endl;
733 mln_up_site_piter(self_t) p(t);
737 os << p <<
"\t" << t.f(p) <<
"\t" << content(p) << std::endl;
741 content(t.parent(p)).insert(p);
745 typename self_t::depth1st_piter n(t);
746 mln_psite(self_t) old;
748 os << std::endl << "Hierarchy: " << std::endl;
754 for (old = n, n.next(); n.is_valid(); old = n, n.next())
756 if (old == t.parent(n))
759 os << old << std::endl
760 <<
"\t" << t.parent(n) <<
" <- ";
763 os << old << std::endl;
769 # endif // ! MLN_INCLUDE_ONLY
774 #endif // ! MLN_MORPHO_TREE_DATA_HH