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