CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch2/src/DataFormats/Common/interface/RefVector.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefVector_h
00002 #define DataFormats_Common_RefVector_h
00003 
00004 /*----------------------------------------------------------------------
00005 
00006 RefVector: A template for a vector of interproduct references.
00007         Each vector element is a reference to a member of the same product.
00008 
00009 ----------------------------------------------------------------------*/
00010 
00011 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00012 #include "DataFormats/Common/interface/EDProductfwd.h"
00013 #include "DataFormats/Common/interface/FillView.h"
00014 #include "DataFormats/Common/interface/Ref.h"
00015 #include "DataFormats/Common/interface/RefHolderBase.h"
00016 #include "DataFormats/Common/interface/RefTraits.h"
00017 #include "DataFormats/Common/interface/RefVectorBase.h"
00018 #include "DataFormats/Common/interface/RefVectorIterator.h"
00019 #include "DataFormats/Common/interface/RefVectorTraits.h"
00020 #include "DataFormats/Common/interface/traits.h"
00021 #include "DataFormats/Provenance/interface/ProductID.h"
00022 
00023 #include <stdexcept>
00024 #include <vector>
00025 
00026 namespace edm {
00027 
00028   template<typename T>
00029   T const* getProduct(RefCore const& ref);
00030 
00031   template<typename C,
00032             typename T = typename refhelper::ValueTrait<C>::value,
00033             typename F = typename refhelper::FindTrait<C, T>::value>
00034   class RefVector {
00035   public:
00036     typedef C                               collection_type;
00037     typedef T                               member_type;
00038     typedef F                               finder_type;
00039     typedef typename refhelper::RefVectorTrait<C, T, F>::iterator_type iterator;
00040     typedef iterator                        const_iterator;
00041     typedef typename refhelper::RefVectorTrait<C, T, F>::ref_type value_type;
00042     typedef value_type const                const_reference; // better this than the default 'const value_type &'
00043     typedef const_reference                 reference;       // as operator[] returns 'const R' and not 'R &'
00044 
00045     // key_type is the type of the key into the collection
00046     typedef typename value_type::key_type   key_type;
00047     typedef std::vector<key_type>           KeyVec;
00048 
00049     // size_type is the type of the index into the RefVector
00050     typedef typename KeyVec::size_type      size_type;
00051     typedef RefVectorBase<key_type>         contents_type;
00052 
00055     RefVector() : refVector_() {}
00056     RefVector(RefVector const& rh) : refVector_(rh.refVector_){}
00057 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00058     RefVector(RefVector && rh) : refVector_(std::move(rh.refVector_)){}
00059 #endif
00060 
00061     RefVector(ProductID const& iId) : refVector_(iId) {}
00063     void push_back(value_type const& ref) {
00064       refVector_.pushBack(ref.refCore(), ref.key());
00065     }
00066 
00068     value_type const operator[](size_type idx) const {
00069       key_type const& key = refVector_.keys()[idx];
00070       RefCore const& prod = refVector_.refCore();
00071       return value_type(prod, key);
00072     }
00073 
00075     value_type const at(size_type idx) const {
00076       key_type const& key = refVector_.keys().at(idx);
00077       RefCore const& prod = refVector_.refCore();
00078       return value_type(prod, key);
00079     }
00080 
00082     contents_type const& refVector() const {return refVector_;}
00083 
00085     bool empty() const {return refVector_.empty();}
00086 
00088     size_type size() const {return refVector_.size();}
00089 
00091     size_type capacity() const {return refVector_.capacity();}
00092 
00094     void reserve(size_type n) {refVector_.reserve(n);}
00095 
00097     const_iterator begin() const;
00098 
00100     const_iterator end() const;
00101 
00103     ProductID id() const {return refVector_.refCore().id();}
00104 
00106     EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00107 
00109     bool isNull() const {return !id().isValid();}
00110 
00112     bool isNonnull() const {return !isNull();}
00113 
00115     bool operator!() const {return isNull();}
00116 
00118     // Accessor must get the product if necessary
00119     C const* product() const;
00120 
00123     bool isAvailable() const {return refVector_.refCore().isAvailable();}
00124 
00126     bool isTransient() const {return refVector_.refCore().isTransient();}
00127 
00129     iterator erase(iterator const& pos);
00130 
00132     void clear() {refVector_.clear();}
00133 
00135     void swap(RefVector<C, T, F> & other);
00136 
00138     RefVector& operator=(RefVector const& rhs);
00139 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00140     RefVector& operator=(RefVector  && rhs) { 
00141       refVector_ = std::move(rhs.refVector_);
00142       return *this;
00143     }
00144 #endif
00145 
00146     bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00147 
00148     void fillView(ProductID const& id,
00149                   std::vector<void const*>& pointers,
00150                   helper_vector& helpers) const;
00151 
00152     //Needed for ROOT storage
00153     CMS_CLASS_VERSION(10)
00154   private:
00155     contents_type refVector_;
00156   };
00157 
00158   template<typename C, typename T, typename F>
00159   inline
00160   void
00161   RefVector<C, T, F>::swap(RefVector<C, T, F> & other) {
00162     refVector_.swap(other.refVector_);
00163   }
00164 
00165   template<typename C, typename T, typename F>
00166   inline
00167   RefVector<C, T, F>&
00168   RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00169     RefVector<C, T, F> temp(rhs);
00170     this->swap(temp);
00171     return *this;
00172   }
00173 
00174   template<typename C, typename T, typename F>
00175   inline
00176   void
00177   swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b) {
00178     a.swap(b);
00179   }
00180 
00181   template<typename C, typename T, typename F>
00182   void
00183   RefVector<C,T,F>::fillView(ProductID const&,
00184                              std::vector<void const*>& pointers,
00185                              helper_vector& helpers) const {
00186     typedef Ref<C,T,F>                     ref_type;
00187     typedef reftobase::RefHolder<ref_type> holder_type;
00188 
00189     pointers.reserve(this->size());
00190     helpers.reserve(this->size());
00191 
00192     size_type key = 0;
00193     for(const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00194       member_type const* address = i->isNull() ? 0 : &**i;
00195       pointers.push_back(address);
00196       holder_type h(ref_type(i->id(), address, i->key(), product()));
00197       helpers.push_back(&h);
00198     }
00199   }
00200 
00201   template<typename C, typename T, typename F>
00202   inline
00203   void
00204   fillView(RefVector<C,T,F> const& obj,
00205            ProductID const& id,
00206            std::vector<void const*>& pointers,
00207            helper_vector& helpers) {
00208     obj.fillView(id, pointers, helpers);
00209   }
00210 
00211   template<typename C, typename T, typename F>
00212   struct has_fillView<RefVector<C,T,F> > {
00213     static bool const value = true;
00214   };
00215 
00216   template<typename C, typename T, typename F>
00217   inline
00218   bool
00219   operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00220     return lhs.refVector() == rhs.refVector();
00221   }
00222 
00223   template<typename C, typename T, typename F>
00224   inline
00225   bool
00226   operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00227     return !(lhs == rhs);
00228   }
00229 
00230   template<typename C, typename T, typename F>
00231   inline
00232   typename RefVector<C, T, F>::iterator
00233   RefVector<C, T, F>::erase(iterator const& pos) {
00234     typename contents_type::keys_type::size_type index = pos - begin();
00235     typename contents_type::keys_type::iterator newPos =
00236       refVector_.eraseAtIndex(index);
00237     RefCore const& prod = refVector_.refCore();
00238     //return typename RefVector<C, T, F>::iterator(prod, newPos);
00239     return iterator(prod, newPos);
00240   }
00241 
00242   template<typename C, typename T, typename F>
00243   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00244     return iterator(refVector_.refCore(), refVector_.keys().begin());
00245   }
00246 
00247   template<typename C, typename T, typename F>
00248   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00249     return iterator(refVector_.refCore(), refVector_.keys().end());
00250   }
00251 
00252   template<typename C, typename T, typename F>
00253   std::ostream&
00254   operator<<(std::ostream& os, RefVector<C,T,F> const& r) {
00255     for(typename RefVector<C,T,F>::const_iterator
00256            i = r.begin(),
00257            e = r.end();
00258            i != e;
00259            ++i) {
00260         os << *i << '\n';
00261       }
00262     return os;
00263   }
00264 }
00265 
00266 #include "DataFormats/Common/interface/RefCoreGet.h"
00267 
00268 namespace edm {
00269 
00270   template<typename C, typename T, typename F>
00271   C const* RefVector<C,T,F>::product() const {
00272     return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00273   }
00274 }
00275 
00276 #include "DataFormats/Common/interface/GetProduct.h"
00277 namespace edm {
00278   namespace detail {
00279 
00280     template<typename C, typename T, typename F>
00281     struct GetProduct<RefVector<C, T, F> > {
00282       typedef T element_type;
00283       typedef typename RefVector<C, T, F>::const_iterator iter;
00284       static element_type const* address(iter const& i) {
00285         return &**i;
00286       }
00287       static C const* product(RefVector<C, T, F> const& coll) {
00288         return coll.product();
00289       }
00290     };
00291   }
00292 }
00293 #endif