CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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 
00062 
00063     RefVector(ProductID const& iId) : refVector_(iId) {}
00065     void push_back(value_type const& ref) {
00066       refVector_.pushBack(ref.refCore(), ref.key());
00067     }
00068 
00070     value_type const operator[](size_type idx) const {
00071       key_type const& key = refVector_.keys()[idx];
00072       RefCore const& prod = refVector_.refCore();
00073       return value_type(prod, key);
00074     }
00075 
00077     value_type const at(size_type idx) const {
00078       key_type const& key = refVector_.keys().at(idx);
00079       RefCore const& prod = refVector_.refCore();
00080       return value_type(prod, key);
00081     }
00082 
00084     contents_type const& refVector() const {return refVector_;}
00085 
00087     bool empty() const {return refVector_.empty();}
00088 
00090     size_type size() const {return refVector_.size();}
00091 
00093     size_type capacity() const {return refVector_.capacity();}
00094 
00096     void reserve(size_type n) {refVector_.reserve(n);}
00097 
00099     const_iterator begin() const;
00100 
00102     const_iterator end() const;
00103 
00105     ProductID id() const {return refVector_.refCore().id();}
00106 
00108     EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00109 
00111     bool isNull() const {return !id().isValid();}
00112 
00114     bool isNonnull() const {return !isNull();}
00115 
00117     bool operator!() const {return isNull();}
00118 
00120     // Accessor must get the product if necessary
00121     C const* product() const;
00122 
00125     bool isAvailable() const {return refVector_.refCore().isAvailable();}
00126 
00128     bool isTransient() const {return refVector_.refCore().isTransient();}
00129 
00131     iterator erase(iterator const& pos);
00132 
00134     void clear() {refVector_.clear();}
00135 
00137     void swap(RefVector<C, T, F> & other);
00138 
00140     RefVector& operator=(RefVector const& rhs);
00141 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00142     RefVector& operator=(RefVector  && rhs) { 
00143       refVector_ = std::move(rhs.refVector_);
00144       return *this;
00145     }
00146 #endif
00147 
00148     bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00149 
00150     void fillView(ProductID const& id,
00151                   std::vector<void const*>& pointers,
00152                   helper_vector& helpers) const;
00153 
00154     //Needed for ROOT storage
00155     CMS_CLASS_VERSION(10)
00156   private:
00157     contents_type refVector_;
00158   };
00159 
00160   template<typename C, typename T, typename F>
00161   inline
00162   void
00163   RefVector<C, T, F>::swap(RefVector<C, T, F> & other) {
00164     refVector_.swap(other.refVector_);
00165   }
00166 
00167   template<typename C, typename T, typename F>
00168   inline
00169   RefVector<C, T, F>&
00170   RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00171     RefVector<C, T, F> temp(rhs);
00172     this->swap(temp);
00173     return *this;
00174   }
00175 
00176   template<typename C, typename T, typename F>
00177   inline
00178   void
00179   swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b) {
00180     a.swap(b);
00181   }
00182 
00183   template<typename C, typename T, typename F>
00184   void
00185   RefVector<C,T,F>::fillView(ProductID const&,
00186                              std::vector<void const*>& pointers,
00187                              helper_vector& helpers) const {
00188     typedef Ref<C,T,F>                     ref_type;
00189     typedef reftobase::RefHolder<ref_type> holder_type;
00190 
00191     pointers.reserve(this->size());
00192     helpers.reserve(this->size());
00193 
00194     size_type key = 0;
00195     for(const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00196       member_type const* address = i->isNull() ? 0 : &**i;
00197       pointers.push_back(address);
00198       holder_type h(ref_type(i->id(), address, i->key(), product()));
00199       helpers.push_back(&h);
00200     }
00201   }
00202 
00203   template<typename C, typename T, typename F>
00204   inline
00205   void
00206   fillView(RefVector<C,T,F> const& obj,
00207            ProductID const& id,
00208            std::vector<void const*>& pointers,
00209            helper_vector& helpers) {
00210     obj.fillView(id, pointers, helpers);
00211   }
00212 
00213   template<typename C, typename T, typename F>
00214   struct has_fillView<RefVector<C,T,F> > {
00215     static bool const value = true;
00216   };
00217 
00218   template<typename C, typename T, typename F>
00219   inline
00220   bool
00221   operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00222     return lhs.refVector() == rhs.refVector();
00223   }
00224 
00225   template<typename C, typename T, typename F>
00226   inline
00227   bool
00228   operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00229     return !(lhs == rhs);
00230   }
00231 
00232   template<typename C, typename T, typename F>
00233   inline
00234   typename RefVector<C, T, F>::iterator
00235   RefVector<C, T, F>::erase(iterator const& pos) {
00236     typename contents_type::keys_type::size_type index = pos - begin();
00237     typename contents_type::keys_type::iterator newPos =
00238       refVector_.eraseAtIndex(index);
00239     RefCore const& prod = refVector_.refCore();
00240     //return typename RefVector<C, T, F>::iterator(prod, newPos);
00241     return iterator(prod, newPos);
00242   }
00243 
00244   template<typename C, typename T, typename F>
00245   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00246     return iterator(refVector_.refCore(), refVector_.keys().begin());
00247   }
00248 
00249   template<typename C, typename T, typename F>
00250   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00251     return iterator(refVector_.refCore(), refVector_.keys().end());
00252   }
00253 
00254   template<typename C, typename T, typename F>
00255   std::ostream&
00256   operator<<(std::ostream& os, RefVector<C,T,F> const& r) {
00257     for(typename RefVector<C,T,F>::const_iterator
00258            i = r.begin(),
00259            e = r.end();
00260            i != e;
00261            ++i) {
00262         os << *i << '\n';
00263       }
00264     return os;
00265   }
00266 }
00267 
00268 #include "DataFormats/Common/interface/RefCoreGet.h"
00269 
00270 namespace edm {
00271 
00272   template<typename C, typename T, typename F>
00273   C const* RefVector<C,T,F>::product() const {
00274     return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00275   }
00276 }
00277 
00278 #include "DataFormats/Common/interface/GetProduct.h"
00279 namespace edm {
00280   namespace detail {
00281 
00282     template<typename C, typename T, typename F>
00283     struct GetProduct<RefVector<C, T, F> > {
00284       typedef T element_type;
00285       typedef typename RefVector<C, T, F>::const_iterator iter;
00286       static element_type const* address(iter const& i) {
00287         return &**i;
00288       }
00289       static C const* product(RefVector<C, T, F> const& coll) {
00290         return coll.product();
00291       }
00292     };
00293   }
00294 }
00295 #endif