CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/Common/interface/AssociationVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_AssociationVector_h
00002 #define DataFormats_Common_AssociationVector_h
00003 /* class edm::AssociationVector<CKey, CVal>
00004  *
00005  * adds to a std::vector<CVal> a edm::RefProd<CKey>, in such a way
00006  * that, assuming that the CVal and CKey collections have the same
00007  * size and are properly ordered, the two collections can be
00008  * in one-to-one correspondance
00009  *
00010  * \author Luca Lista, INFN
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,//the type used here can not change when go from 32bit to 64bit or across platforms
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     //Used by ROOT storage
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 //     pointers.reserve(this->size());
00217 //     for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
00218 //       pointers.push_back(&(*i));
00219 //     // helpers is not yet filled in.
00220 //     //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
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   // Free function template to support creation of Views.
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