CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
EventHypothesisLooper.h
Go to the documentation of this file.
1 #ifndef DataFormats_EventHypothesis_interface_EventHypothesisLooper_h
2 #define DataFormats_EventHypothesis_interface_EventHypothesisLooper_h
3 
6 #include <algorithm>
7 
8 namespace pat {
9  namespace eventhypothesis {
10  template <typename T>
12  public:
13  const T *get(const reco::Candidate *ptr);
14  void clearCache() { isPtrCached_ = false; }
15  bool typeOk(const reco::Candidate *ptr) {
16  doPtr(ptr);
17  return cachePtr_ != 0;
18  }
19 
20  private:
21  void doPtr(const reco::Candidate *ptr);
23  const T *cachePtr_;
24  };
25  template <typename T>
27  if (!isPtrCached_) {
28  cachePtr_ = dynamic_cast<const T *>(ptr);
29  isPtrCached_ = true;
30  }
31  }
32  template <typename T>
34  doPtr(ptr);
35  if ((ptr != nullptr) && (cachePtr_ == nullptr))
36  throw cms::Exception("Type Checking")
37  << "You can't convert a " << typeid(*ptr).name() << " to a " << typeid(T).name() << "\n"
38  << "note: you can use c++filt command to convert the above in human readable types.\n";
39  return cachePtr_;
40  }
41 
42  template <>
44  const reco::Candidate *get(const reco::Candidate *ptr) { return ptr; }
45  void clearCache() {}
46  bool typeOk(const reco::Candidate *ptr) { return true; }
47  };
48 
49  template <typename T>
50  class Looper {
51  public:
54  Looper(const EventHypothesis &eh, const ParticleFilter &filter);
55 
58  Looper(const EventHypothesis &eh, const ParticleFilter *filter);
62  ~Looper() {}
63 
65  const T &operator*() const { return ptr_.get(iter_->second.get()); }
67  const T *operator->() const { return ptr_.get(iter_->second.get()); }
69  const T *get() const { return ptr_.get(iter_->second.get()); }
70 
72  bool isTypeOk() const { return ptr_.typeOk(iter_->second.get()); }
73 
75  const std::string &role() const { return iter_->first; }
77  const CandRefType &ref() const { return iter_->second; }
79  const reco::Candidate &cand() const { return *iter_->second; }
80 
82  size_t globalIndex() { return iter_ - eh_.begin(); }
84  size_t index() const { return num_; }
86  size_t size() const {
87  if (total_ < 0)
88  realSize();
89  return total_;
90  }
91 
93  Looper &operator++();
95  Looper &operator--();
97  Looper &skip(int delta);
100  Looper &reset(int item = 0);
101 
104  operator bool() const;
105 
107  template <typename T2>
108  bool operator==(const Looper<T2> &other) const {
109  return iter_ == other.iter_;
110  }
111  template <typename T2>
112  bool operator!=(const Looper<T2> &other) const {
113  return iter_ != other.iter_;
114  }
115  template <typename T2>
116  bool operator<=(const Looper<T2> &other) const {
117  return iter_ <= other.iter_;
118  }
119  template <typename T2>
120  bool operator>=(const Looper<T2> &other) const {
121  return iter_ >= other.iter_;
122  }
123  template <typename T2>
124  bool operator<(const Looper<T2> &other) const {
125  return iter_ < other.iter_;
126  }
127  template <typename T2>
128  bool operator>(const Looper<T2> &other) const {
129  return iter_ > other.iter_;
130  }
131 
132  private:
133  struct null_deleter {
134  void operator()(void const *) const {}
135  };
137 
138  void first();
139  void realSize() const;
140  bool assertOk() const;
141 
145  int num_;
146  mutable int total_; // mutable as it is not computed unless needed
148  };
150 
151  template <typename T>
153  : eh_(eh), filter_(ParticleFilterPtr(&filter, typename Looper<T>::null_deleter())), total_(-1) {
154  first();
155  }
156 
157  template <typename T>
158  Looper<T>::Looper(const EventHypothesis &eh, const ParticleFilter *filter) : eh_(eh), filter_(filter), total_(-1) {
159  first();
160  }
161 
162  template <typename T>
164  : eh_(eh), filter_(filter), total_(-1) {
165  first();
166  }
167 
168  template <typename T>
169  bool Looper<T>::assertOk() const {
170  assert(iter_ <= eh_.end());
171  assert((iter_ + 1) >= eh_.begin());
172  assert((iter_ < eh_.begin()) || (iter_ == eh_.end()) || ((*filter_)(*iter_)));
173  return true;
174  }
175 
176  template <typename T>
178  ptr_.clearCache();
179  assert(assertOk());
180  if (iter_ == eh_.end())
181  return *this;
182  do {
183  ++iter_;
184  if (iter_ == eh_.end())
185  break;
186  if ((*filter_)(*iter_)) {
187  assert(assertOk());
188  ++num_;
189  return *this;
190  }
191  } while (true);
192  assert(assertOk());
193  return *this;
194  }
195  template <typename T>
197  ptr_.clearCache();
198  assert(assertOk());
199  if (num_ < 0)
200  return *this;
201  do {
202  --iter_;
203  if (iter_ < eh_.begin()) {
204  num_ = -1;
205  break;
206  }
207  if ((*filter_)(*iter_)) {
208  assert(assertOk());
209  --num_;
210  return *this;
211  }
212  } while (true);
213  assert(assertOk());
214  return *this;
215  }
216 
217  template <typename T>
219  assert(assertOk());
220  std::advance(this, delta);
221  assert(assertOk());
222  return *this;
223  }
224 
225  template <typename T>
227  assert(assertOk());
228  if (item >= 0) {
229  first();
230  std::advance(this, item);
231  } else {
232  num_ = item + 1;
233  iter_ = eh_.end();
234  std::advance(this, item);
235  }
236  assert(assertOk());
237  return *this;
238  }
239 
240  template <typename T>
242  num_ = 0;
243  iter_ = eh_.begin();
244  ptr_.clearCache();
245  for (; iter_ != eh_.end(); ++iter_) {
246  if ((*filter_)(*iter_))
247  break;
248  }
249  assert(assertOk());
250  }
251 
252  template <typename T>
253  Looper<T>::operator bool() const {
254  return (iter_ < eh_.end()) && (iter_ >= eh_.begin());
255  }
256 
257  template <typename T>
258  void Looper<T>::realSize() const {
260  if (it < eh_.begin()) {
261  it = eh_.begin();
262  total_ = 0;
263  } else {
264  total_ = num_;
265  }
266  for (; it != eh_.end(); ++it) {
267  if ((*filter_)(*it))
268  ++total_;
269  }
270  }
271  } // namespace eventhypothesis
272 } // namespace pat
273 
274 #endif
const T * get(const reco::Candidate *ptr)
bool isTypeOk() const
test if the type is correct
const T * operator->() const
Accessor as if it was a const_iterator on a list of T.
bool typeOk(const reco::Candidate *ptr)
const CandRefType & ref() const
EDM Ref to pointed particle.
const char * ptr_
Definition: DataKey.cc:76
bool operator!=(const Looper< T2 > &other) const
Looper(const EventHypothesis &eh, const ParticleFilter &filter)
bool operator==(const Looper< T2 > &other) const
returns true if loopers point to the same record
assert(be >=bs)
size_t globalIndex()
Index of this item in the full EventHypothesis.
const reco::Candidate & cand() const
C++ reference to pointed particle.
const std::string & role() const
Role of pointed item.
size_t index() const
Index of this item among those in the loop.
const T & operator*() const
Accessor as if it was a const_iterator on a list of T.
void doPtr(const reco::Candidate *ptr)
EventHypothesis::const_iterator const_iterator
vector_type::const_iterator const_iterator
bool operator>=(const Looper< T2 > &other) const
Looper & skip(int delta)
skip (might be slow)
Looper< reco::Candidate > CandLooper
const ParticleFilterPtr filter_
long double T
const_iterator begin() const
bool operator>(const Looper< T2 > &other) const
size_t size() const
Number of particles in the loop.
std::shared_ptr< const ParticleFilter > ParticleFilterPtr