CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  struct Event;
47  template <class T> struct View;
48  template <class T> struct Handle;
49  template <class T> struct Association;
50  template <class T> struct RefToBase;
51  template <class T> struct Ptr;
52  template <class C, class T, class F> struct Ref;
53 }
54 
55 namespace edm {
56 
57  // Helper classes to convert one ref type to another.
58  // Now it's able to convert anything to itself, and RefToBase to anything else
59  // This won't be needed if we used Ptr
60  namespace helper {
61  template<typename RefFrom, typename RefTo>
62  struct RefConverter {
63  static RefTo convert(const RefFrom &ref) { return RefTo(ref); }
64  };
65  template<typename T>
66  struct RefConverter<RefToBase<T>, Ptr<T> > {
67  static Ptr<T> convert(const RefToBase<T> &ref) { return Ptr<T>(ref.id(), ref.isAvailable() ? ref.get() : 0, ref.key()); }
68  };
69  template<typename T, typename C, typename V, typename F>
70  struct RefConverter<RefToBase<T>, Ref<C,V,F> > {
71  static Ref<C,V,F> convert(const RefToBase<T> &ref) { return ref.template castTo<Ref<C,V,F> >(); }
72  };
73  }
74 
76  // the implementation uses View, and works for RefType = Ref, RefToBase and Ptr
77  template<typename RefType>
79  public:
83 
84  RefType get(const ProductID &id, size_t idx) const {
85  typedef typename edm::RefToBase<element_type> BaseRefType; // could also use Ptr, but then I can't do Ptr->RefToBase
86  if (id_ != id) {
87  id_ = id;
88  iEvent_.get(id_, view_);
89  }
90  BaseRefType ref = view_->refAt(idx);
92  return conv::convert(ref);
93  }
94  private:
96  mutable ProductID id_;
98  };
99 
100  // unfortunately it's not possible to define value_type of an Association<C> correctly
101  // so we need yet another template trick
102  namespace helper {
103  template<typename AC>
105  typedef typename AC::value_type type;
106  };
107 
108  template<typename C>
111  };
112  }
113 
114 template<typename KeyRefType, typename AssociativeCollection,
115  typename ItemGetter = EdmEventItemGetter<KeyRefType> >
117  public:
118  typedef KeyRefType key_type;
121  typedef typename std::pair<key_type, val_type> value_type;
122 
124 
126  AssociativeIterator(const AssociativeCollection &map, const ItemGetter &getter) ;
127 
128  self_type & operator++() ;
129  self_type & operator--() ;
131  // self_type & skipTo(const ProductID &id, size_t offs = 0) ; // to be implemented one day
132 
133  const value_type & operator*() const { return *(this->get()); }
134  const value_type * operator->() const { return (this->get()); }
135  const value_type * get() const { chkPair(); return & pair_; }
136 
137  const key_type & key() const { chkPair(); return pair_.first; }
138  const val_type & val() const { return map_.get(idx_); }
139  const ProductID & id() const { return ioi_->first; }
140 
141  operator bool() const { return idx_ < map_.size(); }
142  self_type end() const ;
143 
144  bool operator==(const self_type &other) const { return other.idx_ == idx_; }
145  bool operator!=(const self_type &other) const { return other.idx_ != idx_; }
146  bool operator<( const self_type &other) const { return other.idx_ < idx_; }
147 
148  private:
149  typedef typename AssociativeCollection::id_offset_vector id_offset_vector;
150  typedef typename id_offset_vector::const_iterator id_offset_iterator;
151  const AssociativeCollection & map_;
153  size_t idx_;
154 
155  ItemGetter getter_;
156 
157  mutable bool pairOk_;
158  mutable value_type pair_;
159 
160  void chkPair() const ;
161 
162  };
163 
164  template<typename KeyRefType, typename AC, typename IG>
166  map_(map), ioi_(map_.ids().begin()), ioi2_(ioi_+1), idx_(0),
167  getter_(getter),
168  pairOk_(false)
169  {
170  }
171 
172  template<typename KeyRefType, typename AC, typename IG>
174  pairOk_ = false;
175  idx_++;
176  if (ioi2_ < map_.ids().end()) {
177  if (ioi2_->second == idx_) {
178  ++ioi_; ++ioi2_;
179  }
180  }
181  return *this;
182  }
183 
184  template<typename KeyRefType, typename AC, typename IG>
186  pairOk_ = false;
187  idx_--;
188  if (ioi_->second < idx_) {
189  --ioi_; --ioi2_;
190  }
191  return *this;
192 
193  }
194 
195  template<typename KeyRefType, typename AC, typename IG>
197  pairOk_ = false;
198  ioi_++; ioi2_++;
199  if (ioi_ == map_.ids().end()) {
200  idx_ = map_.size();
201  } else {
202  idx_ = ioi_->second;
203  }
204  }
205 
206  /*
207  template<typename KeyRefType, typename AC, typename IG>
208  AssociativeIterator<KeyRefType,AC,IG> & AssociativeIterator<KeyRefType,AC,IG>::skipTo(const ProductID &id, size_t offs) {
209  pairOk_ = false;
210  throw Exception(errors::UnimplementedFeature);
211  }
212  */
213 
214  template<typename KeyRefType, typename AC, typename IG>
216  self_type ret(map_, getter_);
217  ret.ioi_ = map_.ids().end();
218  ret.ioi2_ = ret.ioi_ + 1;
219  ret.idx_ = map_.size();
220  return ret;
221  }
222 
223  template<typename KeyRefType, typename AC, typename IG>
225  if (pairOk_) return;
226  pair_.first = getter_.get(id(), idx_ - ioi_->second);
227  pair_.second = map_.get(idx_);
228  pairOk_ = true;
229  }
230 
231 }
232 
233 #endif
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
AssociativeCollection::id_offset_vector id_offset_vector
static HepMC::IO_HEPEVT conv
const val_type & val() const
Handle< View< element_type > > view_
AssociativeIterator< KeyRefType, AssociativeCollection, ItemGetter > self_type
reco::GenParticleCollection::const_iterator IG
ProductID id() const
Definition: RefToBase.h:220
const edm::Event & iEvent_
static RefTo convert(const RefFrom &ref)
void convert(uint32 i, char_uint32 v)
Definition: MsgTools.h:46
bool isAvailable() const
Definition: RefToBase.h:112
int iEvent
Definition: GenABIO.cc:243
EdmEventItemGetter(const edm::Event &iEvent)
const value_type & operator*() const
Helper class that fetches some type of Ref given ProductID and index, using the edm::Event.
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:267
bool operator<(const self_type &other) const
Container::value_type value_type
size_t key() const
Definition: RefToBase.h:228
RefType::value_type element_type
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:31
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
long double T
const ProductID & id() const
value_type const * get() const
Definition: RefToBase.h:212
const key_type & key() const