00001 #ifndef DataFormats_Common_AssociationVector_h
00002 #define DataFormats_Common_AssociationVector_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "FWCore/Utilities/interface/EDMException.h"
00015
00016 #include "DataFormats/Common/interface/traits.h"
00017 #include "DataFormats/Common/interface/EDProduct.h"
00018 #include "DataFormats/Common/interface/RefProd.h"
00019 #include "DataFormats/Common/interface/RefToBaseProd.h"
00020 #include "DataFormats/Common/interface/Ref.h"
00021 #include "DataFormats/Common/interface/RefToBase.h"
00022 #include "DataFormats/Common/interface/FillView.h"
00023 #include "DataFormats/Common/interface/CommonExceptions.h"
00024
00025 #include "DataFormats/Provenance/interface/ProductID.h"
00026
00027 #include "boost/static_assert.hpp"
00028
00029 namespace edm {
00030 namespace helper {
00031
00032 struct AssociationIdenticalKeyReference {
00033 template<typename T>
00034 static T const& get(T const& t, ProductID) { return t; }
00035 };
00036
00037 template<typename T>
00038 struct AssociationKeyReferenceTrait {
00039 typedef AssociationIdenticalKeyReference type;
00040 };
00041
00042 template<typename REFPROD>
00043 struct RefFromRefProdTrait { };
00044
00045 template<typename C>
00046 struct RefFromRefProdTrait<RefProd<C> > {
00047 typedef Ref<typename RefProd<C>::product_type> ref_type;
00048 };
00049
00050 template<typename T>
00051 struct RefFromRefProdTrait<RefToBaseProd<T> > {
00052 typedef RefToBase<T> ref_type;
00053 };
00054 }
00055
00056 template<typename KeyRefProd, typename CVal,
00057 typename KeyRef = typename helper::RefFromRefProdTrait<KeyRefProd>::ref_type,
00058 typename SizeType = unsigned int,
00059 typename KeyReferenceHelper = typename helper::AssociationKeyReferenceTrait<KeyRef>::type>
00060 class AssociationVector {
00061 BOOST_STATIC_ASSERT((boost::is_convertible<SizeType, typename CVal::size_type>::value));
00062 typedef AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> self;
00063
00064 public:
00065 typedef KeyRefProd refprod_type;
00066 typedef typename KeyRefProd::product_type CKey;
00067 typedef SizeType size_type;
00068 typedef typename KeyRef::value_type key_type;
00069 typedef typename std::pair<KeyRef, typename CVal::value_type> value_type;
00070 typedef std::vector<value_type> transient_vector_type;
00071 typedef value_type const& const_reference;
00072 AssociationVector();
00073 AssociationVector(KeyRefProd const& ref, CKey const* = 0);
00074 AssociationVector(AssociationVector const&);
00075 ~AssociationVector();
00076
00077 size_type size() const;
00078 bool empty() const;
00079 const_reference operator[](size_type n) const;
00080 typename CVal::const_reference operator[](KeyRef const& k) const;
00081 typename CVal::reference operator[](KeyRef const& k);
00082
00083 self& operator=(self const&);
00084
00085 void clear();
00086 void swap(self& other);
00087 KeyRefProd const& keyProduct() const { return ref_; }
00088 KeyRef key(size_type i) const { return KeyRef(ref_, i); }
00089 typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
00090 void setValue(size_type i, typename CVal::value_type const& val);
00091 void fillView(ProductID const& id,
00092 std::vector<void const*>& pointers,
00093 helper_vector& helpers) const;
00094
00095 typedef typename transient_vector_type::const_iterator const_iterator;
00096
00097 const_iterator begin() const { return transientVector().begin(); }
00098 const_iterator end() const { return transientVector().end(); }
00099
00100 private:
00101 CVal data_;
00102 KeyRefProd ref_;
00103 mutable transient_vector_type transientVector_;
00104 mutable bool fixed_;
00105 transient_vector_type const& transientVector() const { fixup(); return transientVector_; }
00106 void fixup() const;
00107 };
00108
00109 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00110 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::AssociationVector() :
00111 data_(), ref_(), transientVector_(), fixed_(false) { }
00112
00113 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00114 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::AssociationVector(KeyRefProd const& ref,
00115 CKey const* coll) :
00116 data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
00117 transientVector_(coll == 0 ? ref->size() : coll->size()), fixed_(true) { }
00118
00119 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00120 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::
00121 AssociationVector(AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> const& o) :
00122 data_(o.data_), ref_(o.ref_), transientVector_(o.transientVector_), fixed_(o.fixed_) { }
00123
00124 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00125 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::~AssociationVector() { }
00126
00127 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00128 inline typename AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::const_reference
00129 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](size_type n) const {
00130 return transientVector()[ n ];
00131 }
00132
00133 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00134 inline typename CVal::const_reference
00135 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](KeyRef const& k) const {
00136 KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
00137 checkForWrongProduct(keyRef.id(), ref_.id());
00138 return data_[ keyRef.key() ];
00139 }
00140
00141
00142 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00143 inline typename CVal::reference
00144 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](KeyRef const& k) {
00145 KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
00146 fixed_ = false;
00147 checkForWrongProduct(keyRef.id(), ref_.id());
00148 return data_[ keyRef.key() ];
00149 }
00150
00151 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00152 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>&
00153 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator=(self const& o) {
00154 data_ = o.data_;
00155 ref_ = o.ref_;
00156 fixed_ = false;
00157 return * this;
00158 }
00159
00160 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00161 inline void AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::setValue(size_type i, typename CVal::value_type const& val) {
00162 data_[ i ] = val;
00163 KeyRef ref(ref_, i);
00164 transientVector_[ i ].first = ref;
00165 transientVector_[ i ].second = data_[ i ];
00166 }
00167
00168 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00169 inline typename AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::size_type
00170 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::size() const {
00171 return data_.size();
00172 }
00173
00174 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00175 inline bool AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::empty() const {
00176 return data_.empty();
00177 }
00178
00179 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00180 inline void AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::clear() {
00181 data_.clear();
00182 transientVector_.clear();
00183 ref_ = KeyRefProd();
00184 fixed_ = true;
00185 }
00186
00187 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00188 inline void AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::swap(self& other) {
00189 data_.swap(other.data_);
00190 transientVector_.swap(other.transientVector_);
00191 ref_.swap(other.ref_);
00192 std::swap(fixed_, other.fixed_);
00193 }
00194
00195 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00196 inline void AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::fixup() const {
00197 if (!fixed_) {
00198 fixed_ = true;
00199 transientVector_.resize(size());
00200 for(size_type i = 0; i != size(); ++i) {
00201 transientVector_[ i ] = std::make_pair(KeyRef(ref_, i), data_[ i ]);
00202 }
00203 }
00204 }
00205
00206 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00207 void AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::fillView(ProductID const& id,
00208 std::vector<void const*>& pointers,
00209 helper_vector& helpers) const
00210 {
00211 detail::reallyFillView(*this, id, pointers, helpers);
00212
00213
00214
00215
00216
00217 }
00218
00219 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00220 inline void swap(AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>& a,
00221 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>& b) {
00222 a.swap(b);
00223 }
00224
00225
00226
00227
00228
00229 template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00230 inline
00231 void
00232 fillView(AssociationVector<KeyRefProd,CVal, KeyRef, SizeType, KeyReferenceHelper> const& obj,
00233 ProductID const& id,
00234 std::vector<void const*>& pointers,
00235 helper_vector& helpers) {
00236 obj.fillView(id, pointers, helpers);
00237 }
00238
00239 template <typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00240 struct has_fillView<AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> > {
00241 static bool const value = true;
00242 };
00243
00244 }
00245
00246 #endif