test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AssociationVector.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_AssociationVector_h
2 #define DataFormats_Common_AssociationVector_h
3 /* class edm::AssociationVector<CKey, CVal>
4  *
5  * adds to a std::vector<CVal> a edm::RefProd<CKey>, in such a way
6  * that, assuming that the CVal and CKey collections have the same
7  * size and are properly ordered, the two collections can be
8  * in one-to-one correspondance
9  *
10  * \author Luca Lista, INFN
11  *
12  */
13 
24 
25 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
26 #include <atomic>
27 #include <type_traits>
28 #endif
29 #include <memory>
30 
31 namespace edm {
32  template<class T> class Ptr;
33 
34  namespace helper {
35 
37  template<typename T>
38  static T const& get(T const& t, ProductID) { return t; }
39  };
40 
41  template<typename T>
44  };
45 
46  template<typename REFPROD>
47  struct RefFromRefProdTrait { };
48 
49  template<typename C>
52  };
53 
54  template<typename T>
57  };
58  }
59 
60  template<typename KeyRefProd, typename CVal,
61  typename KeyRef = typename helper::RefFromRefProdTrait<KeyRefProd>::ref_type,
62  typename SizeType = unsigned int,//the type used here can not change when go from 32bit to 64bit or across platforms
63  typename KeyReferenceHelper = typename helper::AssociationKeyReferenceTrait<KeyRef>::type>
67 
68  public:
69  typedef KeyRefProd refprod_type;
70  typedef typename KeyRefProd::product_type CKey;
71  typedef SizeType size_type;
72  typedef typename KeyRef::value_type key_type;
73  typedef typename std::pair<KeyRef, typename CVal::value_type> value_type;
74  typedef std::vector<value_type> transient_vector_type;
75  typedef value_type const& const_reference;
77  AssociationVector(KeyRefProd const& ref, CKey const* = 0);
80 
81  size_type size() const;
82  bool empty() const;
84  typename CVal::const_reference operator[](KeyRef const& k) const;
85  typename CVal::reference operator[](KeyRef const& k);
86 
87  template< typename K>
88  typename CVal::const_reference operator[](edm::Ptr<K> const& k) const;
89  template< typename K>
90  typename CVal::const_reference operator[](edm::RefToBase<K> const& k) const;
91 
92  self& operator=(self const&);
93 
94  void clear();
95  void swap(self& other);
96  KeyRefProd const& keyProduct() const { return ref_; }
97  KeyRef key(size_type i) const { return KeyRef(ref_, i); }
98  typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
99  void setValue(size_type i, typename CVal::value_type const& val);
100  void fillView(ProductID const& id,
101  std::vector<void const*>& pointers,
102  FillViewHelperVector& helpers) const;
103 
104  typedef typename transient_vector_type::const_iterator const_iterator;
105 
106  const_iterator begin() const { return transientVector().begin(); }
107  const_iterator end() const { return transientVector().end(); }
108 
109  //Used by ROOT storage
111 
112  private:
114  CVal data_;
115  KeyRefProd ref_;
116 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
117  mutable std::atomic<transient_vector_type*> transientVector_;
118 #else
120 #endif
121 
122  transient_vector_type const& transientVector() const;
123  void fixup() const;
124  };
125 
126 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
127  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
130  fixup();
131  return *(transientVector_.load(std::memory_order_acquire)); }
132 #endif
133 
134  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
136  data_(), ref_(), transientVector_(nullptr) { }
137 
138  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
140  CKey const* coll) :
141  data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
142  transientVector_( new transient_vector_type(coll == 0 ? ref->size() : coll->size())) { }
143 
144 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
145  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
148  data_(o.data_), ref_(o.ref_), transientVector_() {
149  auto t = o.transientVector_.load(std::memory_order_acquire);
150  if(t) {
151  transientVector_.store( new transient_vector_type(*t), std::memory_order_release);
152  }
153  }
154 #endif
155 
156 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
157  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
159  delete transientVector_.load(std::memory_order_acquire);
160  }
161 #endif
162 
163  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
166  return transientVector()[ n ];
167  }
168 
169  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
170  inline typename CVal::const_reference
172  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
173  checkForWrongProduct(keyRef.id(), ref_.id());
174  return data_[ keyRef.key() ];
175  }
176 
177  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
178  template< typename K>
179  inline typename CVal::const_reference
181 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
182  static_assert(std::is_base_of<K,key_type>::value, "edm::Ptr's key type is not a base class of AssociationVector's item type");
183 #endif
184  checkForWrongProduct(k.id(), ref_.id());
185  return data_[ k.key() ];
186  }
187 
188  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
189  template< typename K>
190  typename CVal::const_reference
192 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
193  static_assert(std::is_base_of<K,key_type>::value,"edm::RefToBase's key type is not a base class of AssociationVector's item type");
194 #endif
195  checkForWrongProduct(k.id(), ref_.id());
196  return data_[ k.key() ];
197  }
198 
199 
200 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
201  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
202  inline typename CVal::reference
204  KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
205  auto t = transientVector_.exchange(nullptr,std::memory_order_acq_rel);
206  delete t;
207  checkForWrongProduct(keyRef.id(), ref_.id());
208  return data_[ keyRef.key() ];
209  }
210 #endif
211 
212 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
213  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
216  if(this == &o) {
217  return *this;
218  }
219  data_ = o.data_;
220  ref_ = o.ref_;
221  auto t =transientVector_.exchange(nullptr, std::memory_order_acq_rel);
222  delete t;
223  return *this;
224  }
225 
226  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
228  data_[ i ] = val;
229  KeyRef ref(ref_, i);
230  auto t = transientVector_.load(std::memory_order_acquire);
231  (*t)[ i ].first = ref;
232  (*t)[ i ].second = data_[ i ];
233  }
234 #endif
235 
236  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
239  return data_.size();
240  }
241 
242  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
244  return data_.empty();
245  }
246 
247 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
248  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
250  data_.clear();
251  auto t = transientVector_.load(std::memory_order_acquire);
252  if(t) t->clear();
253  ref_ = KeyRefProd();
254  }
255 
256  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
258  data_.swap(other.data_);
259  other.transientVector_.store(transientVector_.exchange(other.transientVector_.load(std::memory_order_acquire),std::memory_order_acq_rel),std::memory_order_release);
260  ref_.swap(other.ref_);
261  }
262 
263  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
265  if (nullptr == transientVector_.load(std::memory_order_acquire)) {
266  std::unique_ptr<transient_vector_type> newT {new transient_vector_type(size()) };
267  for(size_type i = 0; i != size(); ++i) {
268  (*newT)[ i ] = std::make_pair(KeyRef(ref_, i), data_[ i ]);
269  }
270  transient_vector_type* expected = nullptr;
271  if(transientVector_.compare_exchange_strong(expected, newT.get()) ) {
272  newT.release();
273  }
274  }
275  }
276 #endif
277 
278  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
280  std::vector<void const*>& pointers,
281  FillViewHelperVector& helpers) const
282  {
283  detail::reallyFillView(*this, id, pointers, helpers);
284 // pointers.reserve(this->size());
285 // for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
286 // pointers.push_back(&(*i));
287 // // helpers is not yet filled in.
288 // //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
289  }
290 
291  template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
294  a.swap(b);
295  }
296 
297  //----------------------------------------------------------------------
298  //
299  // Free function template to support creation of Views.
300 
301  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
302  inline
303  void
305  ProductID const& id,
306  std::vector<void const*>& pointers,
307  FillViewHelperVector& helpers) {
308  obj.fillView(id, pointers, helpers);
309  }
310 
311  template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
312  struct has_fillView<AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> > {
313  static bool const value = true;
314  };
315 
316 }
317 
318 #endif
void checkForWrongProduct(ProductID const &keyID, ProductID const &refID)
int i
Definition: DBlmapReader.cc:9
void fillView(ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers) const
transient_vector_type::const_iterator const_iterator
key_type key() const
Definition: Ptr.h:186
void reallyFillView(COLLECTION const &coll, ProductID const &id, std::vector< void const * > &ptrs, FillViewHelperVector &helpers)
Definition: FillView.h:28
Ref< typename RefProd< C >::product_type > ref_type
self & operator=(self const &)
const_iterator end() const
std::vector< value_type > transient_vector_type
#define nullptr
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
ProductID id() const
Definition: RefToBase.h:233
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
AssociationIdenticalKeyReference type
value_type const & const_reference
const_reference operator[](size_type n) const
size_t key() const
Definition: RefToBase.h:241
std::pair< KeyRef, typename CVal::value_type > value_type
BOOST_STATIC_ASSERT((boost::is_convertible< SizeType, typename CVal::size_type >::value))
void fillView(AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper > const &obj, ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers)
void swap(self &other)
#define private
Definition: FWEveView.cc:22
CVal::value_type const value(size_type i) const
KeyRefProd::product_type CKey
Container::transient_vector_type transient_vector_type
Container::value_type value_type
KeyRef key(size_type i) const
JetCorrectorParametersCollection coll
Definition: classes.h:10
double b
Definition: hdecay.h:120
KeyRef::value_type key_type
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:181
double a
Definition: hdecay.h:121
std::atomic< transient_vector_type * > transientVector_
KeyRefProd const & keyProduct() const
ProductIndex id() const
Definition: ProductID.h:38
transient_vector_type const & transientVector() const
long double T
void setValue(size_type i, typename CVal::value_type const &val)
const_iterator begin() const
std::vector< std::pair< edm::ProductID, unsigned long > > FillViewHelperVector
tuple size
Write out results.
T get(const Candidate &c)
Definition: component.h:55
static bool const value
Definition: traits.h:124
size_type size() const