CMS 3D CMS Logo

AssociativeIterator.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_AssociativeIterator_h
2 #define DataFormats_Common_AssociativeIterator_h
3 
43 
44 namespace edm {
45  class Event;
46  template <class T>
47  class View;
48  template <class T>
49  class Handle;
50  template <class T>
51  class Association;
52  template <class T>
53  class RefToBase;
54  template <class T>
55  class Ptr;
56  template <class C, class T, class F>
57  class Ref;
58 } // namespace edm
59 
60 namespace edm {
61 
62  // Helper classes to convert one ref type to another.
63  // Now it's able to convert anything to itself, and RefToBase to anything else
64  // This won't be needed if we used Ptr
65  namespace helper {
66  template <typename RefFrom, typename RefTo>
67  struct RefConverter {
68  static RefTo convert(const RefFrom &ref) { return RefTo(ref); }
69  };
70  template <typename T>
71  struct RefConverter<RefToBase<T>, Ptr<T> > {
72  static Ptr<T> convert(const RefToBase<T> &ref) {
73  return Ptr<T>(ref.id(), ref.isAvailable() ? ref.get() : 0, ref.key());
74  }
75  };
76  template <typename T, typename C, typename V, typename F>
77  struct RefConverter<RefToBase<T>, Ref<C, V, F> > {
78  static Ref<C, V, F> convert(const RefToBase<T> &ref) { return ref.template castTo<Ref<C, V, F> >(); }
79  };
80  } // namespace helper
81 
83  // the implementation uses View, and works for RefType = Ref, RefToBase and Ptr
84  template <typename RefType, typename EventType>
86  public:
88  EventItemGetter(const EventType &iEvent) : iEvent_(iEvent) {}
90 
91  RefType get(const ProductID &id, size_t idx) const {
92  typedef typename edm::RefToBase<element_type>
93  BaseRefType; // could also use Ptr, but then I can't do Ptr->RefToBase
94  if (id_ != id) {
95  id_ = id;
96  iEvent_.get(id_, view_);
97  }
98  BaseRefType ref = view_->refAt(idx);
100  return conv::convert(ref);
101  }
102 
103  private:
105  mutable ProductID id_;
107  };
108 
109  // unfortunately it's not possible to define value_type of an Association<C> correctly
110  // so we need yet another template trick
111  namespace helper {
112  template <typename AC>
114  typedef typename AC::value_type type;
115  };
116 
117  template <typename C>
120  };
121  } // namespace helper
122 
123  template <typename KeyRefType, typename AssociativeCollection, typename ItemGetter>
125  public:
126  typedef KeyRefType key_type;
129  typedef typename std::pair<key_type, val_type> value_type;
130 
132 
134  AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter);
135 
136  self_type &operator++();
137  self_type &operator--();
138  self_type &nextProductID();
139  // self_type & skipTo(const ProductID &id, size_t offs = 0) ; // to be implemented one day
140 
141  const value_type &operator*() const { return *(this->get()); }
142  const value_type *operator->() const { return (this->get()); }
143  const value_type *get() const {
144  chkPair();
145  return &pair_;
146  }
147 
148  const key_type &key() const {
149  chkPair();
150  return pair_.first;
151  }
152  const val_type &val() const { return map_.get(idx_); }
153  const ProductID &id() const { return ioi_->first; }
154 
155  operator bool() const { return idx_ < map_.size(); }
156  self_type end() const;
157 
158  bool operator==(const self_type &other) const { return other.idx_ == idx_; }
159  bool operator!=(const self_type &other) const { return other.idx_ != idx_; }
160  bool operator<(const self_type &other) const { return other.idx_ < idx_; }
161 
162  private:
163  typedef typename AssociativeCollection::id_offset_vector id_offset_vector;
164  typedef typename id_offset_vector::const_iterator id_offset_iterator;
165  const AssociativeCollection &map_;
166  id_offset_iterator ioi_, ioi2_;
167  size_t idx_;
168 
169  ItemGetter getter_;
170 
171  mutable bool pairOk_;
172  mutable value_type pair_;
173 
174  void chkPair() const;
175  };
176 
177  template <typename KeyRefType, typename AC, typename IG>
179  : map_(map), ioi_(map_.ids().begin()), ioi2_(ioi_ + 1), idx_(0), getter_(getter), pairOk_(false) {}
180 
181  template <typename KeyRefType, typename AC, typename IG>
183  pairOk_ = false;
184  idx_++;
185  if (ioi2_ < map_.ids().end()) {
186  if (ioi2_->second == idx_) {
187  ++ioi_;
188  ++ioi2_;
189  }
190  }
191  return *this;
192  }
193 
194  template <typename KeyRefType, typename AC, typename IG>
196  pairOk_ = false;
197  idx_--;
198  if (ioi_->second < idx_) {
199  --ioi_;
200  --ioi2_;
201  }
202  return *this;
203  }
204 
205  template <typename KeyRefType, typename AC, typename IG>
207  pairOk_ = false;
208  ioi_++;
209  ioi2_++;
210  if (ioi_ == map_.ids().end()) {
211  idx_ = map_.size();
212  } else {
213  idx_ = ioi_->second;
214  }
215  }
216 
217  /*
218  template<typename KeyRefType, typename AC, typename IG>
219  AssociativeIterator<KeyRefType,AC,IG> & AssociativeIterator<KeyRefType,AC,IG>::skipTo(const ProductID &id, size_t offs) {
220  pairOk_ = false;
221  throw Exception(errors::UnimplementedFeature);
222  }
223  */
224 
225  template <typename KeyRefType, typename AC, typename IG>
228  ret.ioi_ = map_.ids().end();
229  ret.ioi2_ = ret.ioi_ + 1;
230  ret.idx_ = map_.size();
231  return ret;
232  }
233 
234  template <typename KeyRefType, typename AC, typename IG>
236  if (pairOk_)
237  return;
238  pair_.first = getter_.get(id(), idx_ - ioi_->second);
239  pair_.second = map_.get(idx_);
240  pairOk_ = true;
241  }
242 
243  template <typename KeyRefType, typename AC, typename EventType>
245  const AC &map, const EventType &event) {
247  return AssociativeIterator<KeyRefType, AC, Getter>(map, Getter{event});
248  }
249 } // namespace edm
250 
251 #endif
AssociativeIterator< KeyRefType, AC, edm::EventItemGetter< KeyRefType, EventType > > makeAssociativeIterator(const AC &map, const EventType &event)
value_type const * get() const
Definition: RefToBase.h:209
AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter)
Create the associative iterator, pointing at the beginning of the collection.
KeyRefType::value_type key_val_type
Definition: helper.py:1
Helper class that fetches some type of Ref given ProductID and index, using the edm::Event.
AssociativeCollection::id_offset_vector id_offset_vector
AssociativeIterator< KeyRefType, AssociativeCollection, ItemGetter > self_type
static HepMC::IO_HEPEVT conv
bool isAvailable() const
Definition: RefToBase.h:119
ret
prodAgent to be discontinued
const val_type & val() const
reco::GenParticleCollection::const_iterator IG
static RefTo convert(const RefFrom &ref)
ProductID id() const
Definition: RefToBase.h:214
static Ref< C, V, F > convert(const RefToBase< T > &ref)
RefType::value_type element_type
int iEvent
Definition: GenABIO.cc:224
const EventType & iEvent_
size_t key() const
Definition: RefToBase.h:219
const value_type & operator*() const
#define end
Definition: vmac.h:39
def convert(infile, ofile)
bool operator<(const self_type &other) const
const value_type * operator->() const
id_offset_vector::const_iterator id_offset_iterator
std::pair< key_type, val_type > value_type
static Ptr< T > convert(const RefToBase< T > &ref)
const AssociativeCollection & map_
helper::AssociativeCollectionValueType< AssociativeCollection >::type val_type
bool operator!=(const self_type &other) const
#define begin
Definition: vmac.h:32
HLT enums.
Handle< View< element_type > > view_
bool operator==(const self_type &other) const
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
EventItemGetter(const EventType &iEvent)
long double T
const ProductID & id() const
Definition: event.py:1
const key_type & key() const