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> class View;
47  template <class T> class Handle;
48  template <class T> class Association;
49  template <class T> class RefToBase;
50  template <class T> class Ptr;
51  template <class C, class T, class F> class Ref;
52 }
53 
54 namespace edm {
55 
56  // Helper classes to convert one ref type to another.
57  // Now it's able to convert anything to itself, and RefToBase to anything else
58  // This won't be needed if we used Ptr
59  namespace helper {
60  template<typename RefFrom, typename RefTo>
61  struct RefConverter {
62  static RefTo convert(const RefFrom &ref) { return RefTo(ref); }
63  };
64  template<typename T>
65  struct RefConverter<RefToBase<T>, Ptr<T> > {
66  static Ptr<T> convert(const RefToBase<T> &ref) { return Ptr<T>(ref.id(), ref.isAvailable() ? ref.get() : 0, ref.key()); }
67  };
68  template<typename T, typename C, typename V, typename F>
69  struct RefConverter<RefToBase<T>, Ref<C,V,F> > {
70  static Ref<C,V,F> convert(const RefToBase<T> &ref) { return ref.template castTo<Ref<C,V,F> >(); }
71  };
72  }
73 
75  // the implementation uses View, and works for RefType = Ref, RefToBase and Ptr
76  template<typename RefType, typename EventType>
78  public:
80  EventItemGetter(const EventType &iEvent) : iEvent_(iEvent) { }
82 
83  RefType get(const ProductID &id, size_t idx) const {
84  typedef typename edm::RefToBase<element_type> BaseRefType; // could also use Ptr, but then I can't do Ptr->RefToBase
85  if (id_ != id) {
86  id_ = id;
87  iEvent_.get(id_, view_);
88  }
89  BaseRefType ref = view_->refAt(idx);
91  return conv::convert(ref);
92  }
93  private:
95  mutable ProductID id_;
97  };
98 
99  // unfortunately it's not possible to define value_type of an Association<C> correctly
100  // so we need yet another template trick
101  namespace helper {
102  template<typename AC>
104  typedef typename AC::value_type type;
105  };
106 
107  template<typename C>
110  };
111  }
112 
113 template<typename KeyRefType, typename AssociativeCollection, typename ItemGetter >
115  public:
116  typedef KeyRefType key_type;
119  typedef typename std::pair<key_type, val_type> value_type;
120 
122 
124  AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter) ;
125 
126  self_type & operator++() ;
127  self_type & operator--() ;
128  self_type & nextProductID() ;
129  // self_type & skipTo(const ProductID &id, size_t offs = 0) ; // to be implemented one day
130 
131  const value_type & operator*() const { return *(this->get()); }
132  const value_type * operator->() const { return (this->get()); }
133  const value_type * get() const { chkPair(); return & pair_; }
134 
135  const key_type & key() const { chkPair(); return pair_.first; }
136  const val_type & val() const { return map_.get(idx_); }
137  const ProductID & id() const { return ioi_->first; }
138 
139  operator bool() const { return idx_ < map_.size(); }
140  self_type end() const ;
141 
142  bool operator==(const self_type &other) const { return other.idx_ == idx_; }
143  bool operator!=(const self_type &other) const { return other.idx_ != idx_; }
144  bool operator<( const self_type &other) const { return other.idx_ < idx_; }
145 
146  private:
147  typedef typename AssociativeCollection::id_offset_vector id_offset_vector;
148  typedef typename id_offset_vector::const_iterator id_offset_iterator;
149  const AssociativeCollection & map_;
150  id_offset_iterator ioi_, ioi2_;
151  size_t idx_;
152 
153  ItemGetter getter_;
154 
155  mutable bool pairOk_;
156  mutable value_type pair_;
157 
158  void chkPair() const ;
159 
160  };
161 
162  template<typename KeyRefType, typename AC, typename IG>
164  map_(map), ioi_(map_.ids().begin()), ioi2_(ioi_+1), idx_(0),
165  getter_(getter),
166  pairOk_(false)
167  {
168  }
169 
170  template<typename KeyRefType, typename AC, typename IG>
172  pairOk_ = false;
173  idx_++;
174  if (ioi2_ < map_.ids().end()) {
175  if (ioi2_->second == idx_) {
176  ++ioi_; ++ioi2_;
177  }
178  }
179  return *this;
180  }
181 
182  template<typename KeyRefType, typename AC, typename IG>
184  pairOk_ = false;
185  idx_--;
186  if (ioi_->second < idx_) {
187  --ioi_; --ioi2_;
188  }
189  return *this;
190 
191  }
192 
193  template<typename KeyRefType, typename AC, typename IG>
195  pairOk_ = false;
196  ioi_++; ioi2_++;
197  if (ioi_ == map_.ids().end()) {
198  idx_ = map_.size();
199  } else {
200  idx_ = ioi_->second;
201  }
202  }
203 
204  /*
205  template<typename KeyRefType, typename AC, typename IG>
206  AssociativeIterator<KeyRefType,AC,IG> & AssociativeIterator<KeyRefType,AC,IG>::skipTo(const ProductID &id, size_t offs) {
207  pairOk_ = false;
208  throw Exception(errors::UnimplementedFeature);
209  }
210  */
211 
212  template<typename KeyRefType, typename AC, typename IG>
214  self_type ret(map_, getter_);
215  ret.ioi_ = map_.ids().end();
216  ret.ioi2_ = ret.ioi_ + 1;
217  ret.idx_ = map_.size();
218  return ret;
219  }
220 
221  template<typename KeyRefType, typename AC, typename IG>
223  if (pairOk_) return;
224  pair_.first = getter_.get(id(), idx_ - ioi_->second);
225  pair_.second = map_.get(idx_);
226  pairOk_ = true;
227  }
228 
229  template<typename KeyRefType, typename AC, typename EventType>
233  return AssociativeIterator<KeyRefType, AC, Getter >(map, Getter{event});
234  }
235 }
236 
237 #endif
238 
value_type const * get() const
Definition: RefToBase.h:234
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
static HepMC::IO_HEPEVT conv
bool isAvailable() const
Definition: RefToBase.h:114
const val_type & val() const
AssociativeIterator< KeyRefType, AssociativeCollection, ItemGetter > self_type
reco::GenParticleCollection::const_iterator IG
static RefTo convert(const RefFrom &ref)
ProductID id() const
Definition: RefToBase.h:242
RefType::value_type element_type
int iEvent
Definition: GenABIO.cc:224
const EventType & iEvent_
size_t key() const
Definition: RefToBase.h:250
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.
AssociativeIterator< KeyRefType, AC, edm::EventItemGetter< KeyRefType, EventType > > makeAssociativeIterator(const AC &map, const EventType &event)
Handle< View< element_type > > view_
bool operator==(const self_type &other) const
static Ref< C, V, F > convert(const RefToBase< T > &ref)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
EventItemGetter(const EventType &iEvent)
long double T
const ProductID & id() const
Definition: event.py:1
const key_type & key() const