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 
44 
45 namespace edm {
46  class Event;
47  template <class T>
48  class View;
49  template <class T>
50  class Handle;
51  template <class T>
52  class Association;
53  template <class T>
54  class RefToBase;
55  template <class T>
56  class Ptr;
57  template <class C, class T, class F>
58  class Ref;
59 } // namespace edm
60 
61 namespace edm {
62 
63  // Helper classes to convert one ref type to another.
64  // Now it's able to convert anything to itself, and RefToBase to anything else
65  // This won't be needed if we used Ptr
66  namespace helper {
67  template <typename RefFrom, typename RefTo>
68  struct RefConverter {
69  static RefTo convert(const RefFrom &ref) { return RefTo(ref); }
70  };
71  template <typename T>
72  struct RefConverter<RefToBase<T>, Ptr<T> > {
73  static Ptr<T> convert(const RefToBase<T> &ref) {
74  return Ptr<T>(ref.id(), ref.isAvailable() ? ref.get() : 0, ref.key());
75  }
76  };
77  template <typename T, typename C, typename V, typename F>
78  struct RefConverter<RefToBase<T>, Ref<C, V, F> > {
79  static Ref<C, V, F> convert(const RefToBase<T> &ref) { return ref.template castTo<Ref<C, V, F> >(); }
80  };
81  } // namespace helper
82 
84  // the implementation uses View, and works for RefType = Ref, RefToBase and Ptr
85  template <typename RefType, typename EventType>
87  public:
91 
92  RefType get(const ProductID &id, size_t idx) const {
93  typedef typename edm::RefToBase<element_type>
94  BaseRefType; // could also use Ptr, but then I can't do Ptr->RefToBase
95  if (id_ != id) {
96  id_ = id;
97  iEvent_.get(id_, view_);
98  }
99  BaseRefType ref = view_->refAt(idx);
101  return conv::convert(ref);
102  }
103 
104  private:
105  //This class is not intended to be used across threads
109  };
110 
111  // unfortunately it's not possible to define value_type of an Association<C> correctly
112  // so we need yet another template trick
113  namespace helper {
114  template <typename AC>
116  typedef typename AC::value_type type;
117  };
118 
119  template <typename C>
122  };
123  } // namespace helper
124 
125  template <typename KeyRefType, typename AssociativeCollection, typename ItemGetter>
127  public:
128  typedef KeyRefType key_type;
131  typedef typename std::pair<key_type, val_type> value_type;
132 
134 
136  AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter);
137 
141  // self_type & skipTo(const ProductID &id, size_t offs = 0) ; // to be implemented one day
142 
143  const value_type &operator*() const { return *(this->get()); }
144  const value_type *operator->() const { return (this->get()); }
145  const value_type *get() const {
146  chkPair();
147  return &pair_;
148  }
149 
150  const key_type &key() const {
151  chkPair();
152  return pair_.first;
153  }
154  const val_type &val() const { return map_.get(idx_); }
155  const ProductID &id() const { return ioi_->first; }
156 
157  operator bool() const { return idx_ < map_.size(); }
158  self_type end() const;
159 
160  bool operator==(const self_type &other) const { return other.idx_ == idx_; }
161  bool operator!=(const self_type &other) const { return other.idx_ != idx_; }
162  bool operator<(const self_type &other) const { return other.idx_ < idx_; }
163 
164  private:
165  typedef typename AssociativeCollection::id_offset_vector id_offset_vector;
166  typedef typename id_offset_vector::const_iterator id_offset_iterator;
167  const AssociativeCollection &map_;
169  size_t idx_;
170 
171  ItemGetter getter_;
172 
173  //This class is not intended to be used across threads
174  CMS_SA_ALLOW mutable bool pairOk_;
176 
177  void chkPair() const;
178  };
179 
180  template <typename KeyRefType, typename AC, typename IG>
182  : map_(map), ioi_(map_.ids().begin()), ioi2_(ioi_ + 1), idx_(0), getter_(getter), pairOk_(false) {}
183 
184  template <typename KeyRefType, typename AC, typename IG>
186  pairOk_ = false;
187  idx_++;
188  if (ioi2_ < map_.ids().end()) {
189  if (ioi2_->second == idx_) {
190  ++ioi_;
191  ++ioi2_;
192  }
193  }
194  return *this;
195  }
196 
197  template <typename KeyRefType, typename AC, typename IG>
199  pairOk_ = false;
200  idx_--;
201  if (ioi_->second < idx_) {
202  --ioi_;
203  --ioi2_;
204  }
205  return *this;
206  }
207 
208  template <typename KeyRefType, typename AC, typename IG>
210  pairOk_ = false;
211  ioi_++;
212  ioi2_++;
213  if (ioi_ == map_.ids().end()) {
214  idx_ = map_.size();
215  } else {
216  idx_ = ioi_->second;
217  }
218  }
219 
220  /*
221  template<typename KeyRefType, typename AC, typename IG>
222  AssociativeIterator<KeyRefType,AC,IG> & AssociativeIterator<KeyRefType,AC,IG>::skipTo(const ProductID &id, size_t offs) {
223  pairOk_ = false;
224  throw Exception(errors::UnimplementedFeature);
225  }
226  */
227 
228  template <typename KeyRefType, typename AC, typename IG>
230  self_type ret(map_, getter_);
231  ret.ioi_ = map_.ids().end();
232  ret.ioi2_ = ret.ioi_ + 1;
233  ret.idx_ = map_.size();
234  return ret;
235  }
236 
237  template <typename KeyRefType, typename AC, typename IG>
239  if (pairOk_)
240  return;
241  pair_.first = getter_.get(id(), idx_ - ioi_->second);
242  pair_.second = map_.get(idx_);
243  pairOk_ = true;
244  }
245 
246  template <typename KeyRefType, typename AC, typename EventType>
248  const AC &map, const EventType &event) {
250  return AssociativeIterator<KeyRefType, AC, Getter>(map, Getter{event});
251  }
252 } // namespace edm
253 
254 #endif
AssociativeIterator< KeyRefType, AC, edm::EventItemGetter< KeyRefType, EventType > > makeAssociativeIterator(const AC &map, const EventType &event)
const key_type & key() const
bool isAvailable() const
Definition: RefToBase.h:126
AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter)
Create the associative iterator, pointing at the beginning of the collection.
KeyRefType::value_type key_val_type
#define CMS_SA_ALLOW
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
const val_type & val() const
ret
prodAgent to be discontinued
const ProductID & id() const
reco::GenParticleCollection::const_iterator IG
static RefTo convert(const RefFrom &ref)
ProductID id() const
Definition: RefToBase.h:221
static Ref< C, V, F > convert(const RefToBase< T > &ref)
RefType::value_type element_type
const value_type & operator*() const
int iEvent
Definition: GenABIO.cc:224
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t V
const EventType & iEvent_
bool operator==(const self_type &other) const
bool operator!=(const self_type &other) const
W convert(V v)
Definition: ExtVec.h:66
size_t key() const
Definition: RefToBase.h:226
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
EPOS::IO_EPOS conv
HLT enums.
Handle< View< element_type > > view_
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
EventItemGetter(const EventType &iEvent)
long double T
value_type const * get() const
Definition: RefToBase.h:216
const value_type * operator->() const
Definition: event.py:1
bool operator<(const self_type &other) const