CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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 "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,//the type used here can not change when go from 32bit to 64bit or across platforms
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 //     pointers.reserve(this->size());
00213 //     for(typename CVal::const_iterator i=data_.begin(), e=data_.end(); i!=e; ++i)
00214 //       pointers.push_back(&(*i));
00215 //     // helpers is not yet filled in.
00216 //     //Exception::throwThis(errors::UnimplementedFeature, "AssociationVector<T>::fillView(...)");
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   // Free function template to support creation of Views.
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