IMP  2.0.1
The Integrative Modeling Platform
kernel/Refiner.h
Go to the documentation of this file.
1 /**
2  * \file IMP/kernel/Refiner.h
3  * \brief Refine a particle into a list of particles.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  */
7 
8 #ifndef IMPKERNEL_REFINER_H
9 #define IMPKERNEL_REFINER_H
10 
11 #include <IMP/kernel/kernel_config.h>
12 #include "base_types.h"
13 #include "Particle.h"
14 #include "VersionInfo.h"
15 #include "RefCounted.h"
16 #include "internal/IndexingIterator.h"
18 #include "input_output_macros.h"
19 
20 IMPKERNEL_BEGIN_NAMESPACE
21 
22 class Particle;
24 
25 //! Abstract class to implement hierarchical methods.
26 /** The job of this class is to take a single particle and, if
27  appropriate, return a list of particles. These lists can
28  reflect existing relationships, such as the
29  IMP::core::LeavesRefiner or arbitrary relationships set up
30  for a particular purpose, such as IMP::core::TableRefiner.
31 
32  Implementors should see IMP_REFINER().
33 */
34 class IMPKERNELEXPORT Refiner : public IMP::base::Object
35 {
36  struct Accessor;
37 public:
38  Refiner(std::string name="Refiner %1%");
39  //! Return true if this refiner can refine that particle
40  /** This should not throw, so be careful what fields are touched.
41  */
42  virtual bool get_can_refine(Particle *) const {return false;}
43 
44  //! Refine the passed particle into a set of particles.
45  /** As a precondition can_refine_particle(a) should be true.
46  */
47  virtual const ParticlesTemp get_refined(Particle *a) const=0;
48  //! Get the ith refined particle.
49  /** As a precondition can_refine_particle(a) should be true.
50  */
51  virtual Particle* get_refined(Particle *a, unsigned int i) const =0;
52 
53  /** As a precondition can_refine_particle(a) should be true.
54  */
55  virtual unsigned int get_number_of_refined(Particle *a) const =0;
56 
57 #ifndef SWIG
58  /** @name Iterating through the set of refined particles
59 
60  Using iterators can be more efficient than using the bulk
61  get_refined(), however it is not necessarily so.
62  @{
63  */
64  typedef internal::IndexingIterator<Accessor> RefinedIterator;
65  RefinedIterator refined_begin(Particle *a) const;
66  RefinedIterator refined_end(Particle *a) const;
67  /** @} */
68 #endif
69 
71 };
72 //! a collection of Refiner objects
74 
75 #if !defined(SWIG) && !defined(IMP_DOXYGEN)
76 struct Refiner::Accessor {
77  // can't reference count since swig memory management is broken
78  Particle* p_;
79  const Refiner* r_;
80  Accessor(Particle *p, const Refiner *r): p_(p), r_(r) {}
81  Accessor(){}
82  typedef Particle *result_type;
83  Particle *operator()(unsigned int i) const {
84  return r_->get_refined(p_, i);
85  }
86  bool operator==(const Accessor &o) const {
87  return p_==o.p_ && r_==o.r_;
88  }
89 };
90 #endif
91 
92 inline Refiner::RefinedIterator Refiner::refined_begin(Particle *a) const {
93  return RefinedIterator(Accessor(a, this), 0);
94 }
95 inline Refiner::RefinedIterator Refiner::refined_end(Particle *a) const {
96  return RefinedIterator(Accessor(a, this), get_number_of_refined(a));
97 }
98 
99 IMPKERNEL_END_NAMESPACE
100 
101 #endif /* IMPKERNEL_REFINER_H */