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 "FWCore/Utilities/interface/EDMException.h"
00016
00017 #include "DataFormats/Common/interface/traits.h"
00018 #include "DataFormats/Common/interface/EDProduct.h"
00019 #include "DataFormats/Common/interface/RefProd.h"
00020 #include "DataFormats/Common/interface/RefToBaseProd.h"
00021 #include "DataFormats/Common/interface/Ref.h"
00022 #include "DataFormats/Common/interface/RefToBase.h"
00023 #include "DataFormats/Common/interface/FillView.h"
00024 #include "DataFormats/Common/interface/CommonExceptions.h"
00025
00026 #include "DataFormats/Provenance/interface/ProductID.h"
00027
00028 #include "boost/static_assert.hpp"
00029
00030 namespace edm {
00031 namespace helper {
00032
00033 struct AssociationIdenticalKeyReference {
00034 template<typename T>
00035 static T const& get(T const& t, ProductID) { return t; }
00036 };
00037
00038 template<typename T>
00039 struct AssociationKeyReferenceTrait {
00040 typedef AssociationIdenticalKeyReference type;
00041 };
00042
00043 template<typename REFPROD>
00044 struct RefFromRefProdTrait { };
00045
00046 template<typename C>
00047 struct RefFromRefProdTrait<RefProd<C> > {
00048 typedef Ref<typename RefProd<C>::product_type> ref_type;
00049 };
00050
00051 template<typename T>
00052 struct RefFromRefProdTrait<RefToBaseProd<T> > {
00053 typedef RefToBase<T> ref_type;
00054 };
00055 }
00056
00057 template<typename KeyRefProd, typename CVal,
00058 typename KeyRef = typename helper::RefFromRefProdTrait<KeyRefProd>::ref_type,
00059 typename SizeType = unsigned int,
00060 typename KeyReferenceHelper = typename helper::AssociationKeyReferenceTrait<KeyRef>::type>
00061 class AssociationVector {
00062 BOOST_STATIC_ASSERT((boost::is_convertible<SizeType, typename CVal::size_type>::value));
00063 typedef AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> self;
00064
00065 public:
00066 typedef KeyRefProd refprod_type;
00067 typedef typename KeyRefProd::product_type CKey;
00068 typedef SizeType size_type;
00069 typedef typename KeyRef::value_type key_type;
00070 typedef typename std::pair<KeyRef, typename CVal::value_type> value_type;
00071 typedef std::vector<value_type> transient_vector_type;
00072 typedef value_type const& const_reference;
00073 AssociationVector();
00074 AssociationVector(KeyRefProd const& ref, CKey const* = 0);
00075 AssociationVector(AssociationVector const&);
00076 ~AssociationVector();
00077
00078 size_type size() const;
00079 bool empty() const;
00080 const_reference operator[](size_type n) const;
00081 typename CVal::const_reference operator[](KeyRef const& k) const;
00082 typename CVal::reference operator[](KeyRef const& k);
00083
00084 self& operator=(self const&);
00085
00086 void clear();
00087 void swap(self& other);
00088 KeyRefProd const& keyProduct() const { return ref_; }
00089 KeyRef key(size_type i) const { return KeyRef(ref_, i); }
00090 typename CVal::value_type const value(size_type i) const { return data_[ i ]; }
00091 void setValue(size_type i, typename CVal::value_type const& val);
00092 void fillView(ProductID const& id,
00093 std::vector<void const*>& pointers,
00094 helper_vector& helpers) const;
00095
00096 typedef typename transient_vector_type::const_iterator const_iterator;
00097
00098 const_iterator begin() const { return transientVector().begin(); }
00099 const_iterator end() const { return transientVector().end(); }
00100
00101
00102 CMS_CLASS_VERSION(10)
00103
00104 private:
00105 CVal data_;
00106 KeyRefProd ref_;
00107 mutable transient_vector_type transientVector_;
00108 mutable bool fixed_;
00109 transient_vector_type const& transientVector() const { fixup(); return transientVector_; }
00110 void fixup() const;
00111 };
00112
00113 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00114 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::AssociationVector() :
00115 data_(), ref_(), transientVector_(), fixed_(false) { }
00116
00117 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00118 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::AssociationVector(KeyRefProd const& ref,
00119 CKey const* coll) :
00120 data_(coll == 0 ? ref->size() : coll->size()), ref_(ref),
00121 transientVector_(coll == 0 ? ref->size() : coll->size()), fixed_(true) { }
00122
00123 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00124 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::
00125 AssociationVector(AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper> const& o) :
00126 data_(o.data_), ref_(o.ref_), transientVector_(o.transientVector_), fixed_(o.fixed_) { }
00127
00128 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00129 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::~AssociationVector() { }
00130
00131 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00132 inline typename AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::const_reference
00133 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](size_type n) const {
00134 return transientVector()[ n ];
00135 }
00136
00137 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00138 inline typename CVal::const_reference
00139 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](KeyRef const& k) const {
00140 KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
00141 checkForWrongProduct(keyRef.id(), ref_.id());
00142 return data_[ keyRef.key() ];
00143 }
00144
00145
00146 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00147 inline typename CVal::reference
00148 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator[](KeyRef const& k) {
00149 KeyRef keyRef = KeyReferenceHelper::get(k, ref_.id());
00150 fixed_ = false;
00151 checkForWrongProduct(keyRef.id(), ref_.id());
00152 return data_[ keyRef.key() ];
00153 }
00154
00155 template<typename KeyRefProd, typename CVal, typename KeyRef, typename SizeType, typename KeyReferenceHelper>
00156 inline AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>&
00157 AssociationVector<KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper>::operator=(self const& o) {
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