9 #ifndef IMPCORE_HIERARCHY_H
10 #define IMPCORE_HIERARCHY_H
12 #include <IMP/core/core_config.h>
13 #include "internal/hierarchy_helpers.h"
20 #include <IMP/internal/utility.h>
22 #include <boost/tuple/tuple.hpp>
28 IMPCORE_BEGIN_NAMESPACE
61 return parent_ == o.parent_;
87 get_default_traits());
93 =Hierarchy::get_default_traits()) {
102 const Particles &children,
104 =Hierarchy::get_default_traits()) {
107 for (
unsigned int i=0; i< children.size(); ++i) {
108 vs[i]=children[i]->get_index();
111 h.get_particle_index());
114 h.get_particle_index(),
123 =Hierarchy::get_default_traits()){
130 if (
get_model()->get_has_attribute(get_decorator_traits()
132 get_particle_index())) {
135 get_particle_index());
142 unsigned int get_number_of_children()
const {
143 if (
get_model()->get_has_attribute(get_traits().get_children_key(),
144 get_particle_index())) {
146 get_particle_index()).size();
151 Hierarchy get_child(
unsigned int i)
const {
153 "Invalid child requested");
155 get_model()->get_attribute(get_traits().get_children_key(),
156 get_particle_index())[i],
159 GenericHierarchies get_children()
const {
160 GenericHierarchies ret(get_number_of_children());
161 for (
unsigned int i=0; i< ret.size(); ++i) {
162 ret[i]= get_child(i);
166 void remove_child(
unsigned int i) {
168 "Invalid child requested");
169 Hierarchy c= get_child(i);
171 =
get_model()->access_attribute(get_traits().get_children_key(),
172 get_particle_index());
173 pis.erase(pis.begin()+i);
175 c.get_particle_index());
177 void remove_child(Hierarchy h) {
178 remove_child(h.get_child_index());
180 void clear_children() {
182 =
get_model()->access_attribute(get_traits().get_children_key(),
183 get_particle_index());
184 for (
unsigned int i=0; i< pis.size(); ++i) {
189 get_particle_index());
191 void add_child(Hierarchy h)
const {
192 if (
get_model()->get_has_attribute(get_traits().get_children_key(),
193 get_particle_index())) {
194 get_model()->access_attribute(get_traits().get_children_key(),
195 get_particle_index())
196 .push_back(h.get_particle_index());
199 get_particle_index(),
200 ParticleIndexes(1, h.get_particle_index()));
203 h.get_particle_index(), get_particle_index());
205 void add_child_at(Hierarchy h,
unsigned int pos) {
208 if (
get_model()->get_has_attribute(get_traits().get_children_key(),
209 get_particle_index())) {
211 =
get_model()->access_attribute(get_traits().get_children_key(),
212 get_particle_index());
213 pis.insert(pis.begin()+pos, h.get_particle_index());
216 get_particle_index(),
217 ParticleIndexes(1, h.get_particle_index()));
220 h.get_particle_index(), get_particle_index());
222 int get_child_index()
const {
223 if (!get_parent())
return -1;
227 get_particle_index());
228 const ParticleIndexes &pis
231 return std::find(pis.begin(), pis.end(),
232 get_particle_index())-pis.begin();
236 static const HierarchyTraits& get_default_traits();
252 virtual bool operator()(
Hierarchy p) = 0;
267 IMP::OwnerPointer<SingletonModifier> sm_;
279 #if !defined (SWIG) && !defined(IMP_DOXYGEN)
281 template <
class H,
class F,
class Out,
bool Slice=false>
285 Gather(F f, Out out): f_(f), out_(out) {}
286 bool operator()(H p) {
290 if (Slice)
return false;
295 Out get_out()
const {
317 template <
class HD,
class F>
320 std::deque<HD > stack;
324 HD cur= stack.front();
328 for (
int i=cur.get_number_of_children()-1; i>=0; --i) {
329 stack.push_back(cur.get_child(i));
332 }
while (!stack.empty());
342 template <
class HD,
class F>
349 HD cur= stack.back();
353 for (
int i=cur.get_number_of_children()-1; i>=0; --i) {
354 stack.push_back(cur.get_child(i));
357 }
while (!stack.empty());
387 template <
class HD,
class F>
390 typedef std::pair<typename F::result_type, HD> DP;
391 std::deque<DP > stack;
392 stack.push_back(DP(i, d));
395 DP cur= stack.front();
397 typename F::result_type r= f(cur.second.get_particle(), cur.first);
399 for (
int i=cur.second.get_number_of_children()-1; i>=0; --i) {
400 stack.push_back(std::make_pair(r, cur.second.get_child(i)));
402 }
while (!stack.empty());
412 template <
class HD,
class F>
415 typedef std::pair<typename F::result_type, HD> DP;
417 stack.push_back(DP(i, d));
420 DP cur= stack.back();
422 typename F::result_type r=f(cur.second, cur.first);
424 for (
int i=cur.second.get_number_of_children()-1; i>=0; --i) {
425 stack.push_back(DP(r, cur.second.get_child(i)));
427 }
while (!stack.empty());
443 IMP_PRINT_TREE(out,
Hierarchy, h, n.get_number_of_children(),
444 n.get_child, ND(n).show(out));
480 template <
class H,
class Out,
class F>
483 internal::Gather<H, F,Out>
gather(f,out);
485 return gather.get_out();
496 template <
class H,
class Out,
class F>
499 internal::Gather<H, F,Out,true>
gather(f,out);
501 return gather.get_out();
509 template <
class H,
class Out,
class K,
class V>
512 internal::Gather<H, internal::MatchAttribute<K, V>,Out>
513 gather(internal::MatchAttribute<K,V>(k,v),
516 return gather.get_out();
526 template <
class H,
class Out,
class K0,
class V0,
class K1,
class V1>
528 V0 v0, K1 k1, V1 v1, Out out)
530 internal::Gather<H, internal::MatchAttributes<K0, V0, K1, V1>,Out>
531 gather(internal::MatchAttributes<K0,V0, K1, V1>(k0,v0, k1, v1),
534 return gather.get_out();
542 template <
class HD,
class F>
545 if (f(h.get_particle()))
return h;
550 HD cur= stack.back();
553 for (
int i=cur.get_number_of_children()-1; i>=0; --i) {
554 HD hd= cur.get_child(i);
555 if (f(hd.get_particle())) {
561 }
while (!stack.empty());
573 IMPCOREEXPORT GenericHierarchies
579 IMPCOREEXPORT GenericHierarchies
585 IMPCOREEXPORT GenericHierarchies
597 IMPCORE_END_NAMESPACE