CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch1/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 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00023 
00024 #include <stdexcept>
00025 #include <vector>
00026 
00027 namespace edm {
00028 
00029   template<typename T>
00030   T const* getProduct(RefCore const& ref);
00031 
00032   template<typename C,
00033             typename T = typename refhelper::ValueTrait<C>::value,
00034             typename F = typename refhelper::FindTrait<C, T>::value>
00035   class RefVector {
00036   public:
00037     typedef C                               collection_type;
00038     typedef T                               member_type;
00039     typedef F                               finder_type;
00040     typedef typename refhelper::RefVectorTrait<C, T, F>::iterator_type iterator;
00041     typedef iterator                        const_iterator;
00042     typedef typename refhelper::RefVectorTrait<C, T, F>::ref_type value_type;
00043     typedef value_type const                const_reference; // better this than the default 'const value_type &'
00044     typedef const_reference                 reference;       // as operator[] returns 'const R' and not 'R &'
00045 
00046     // key_type is the type of the key into the collection
00047     typedef typename value_type::key_type   key_type;
00048     typedef std::vector<key_type>           KeyVec;
00049 
00050     // size_type is the type of the index into the RefVector
00051     typedef typename KeyVec::size_type      size_type;
00052     typedef RefVectorBase<key_type>         contents_type;
00053 
00056     RefVector() : refVector_() {}
00057     RefVector(RefVector const& rh) : refVector_(rh.refVector_){}
00058 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00059     RefVector(RefVector && rh)  noexcept : refVector_(std::move(rh.refVector_)){}
00060 #endif
00061 
00062     RefVector(ProductID const& iId) : refVector_(iId) {}
00064     void push_back(value_type const& ref) {
00065       refVector_.pushBack(ref.refCore(), ref.key());
00066     }
00067 
00069     value_type const operator[](size_type idx) const {
00070       key_type const& key = refVector_.keys()[idx];
00071       RefCore const& prod = refVector_.refCore();
00072       return value_type(prod, key);
00073     }
00074 
00076     value_type const at(size_type idx) const {
00077       key_type const& key = refVector_.keys().at(idx);
00078       RefCore const& prod = refVector_.refCore();
00079       return value_type(prod, key);
00080     }
00081 
00083     contents_type const& refVector() const {return refVector_;}
00084 
00086     bool empty() const {return refVector_.empty();}
00087 
00089     size_type size() const {return refVector_.size();}
00090 
00092     size_type capacity() const {return refVector_.capacity();}
00093 
00095     void reserve(size_type n) {refVector_.reserve(n);}
00096 
00098     const_iterator begin() const;
00099 
00101     const_iterator end() const;
00102 
00104     ProductID id() const {return refVector_.refCore().id();}
00105 
00107     EDProductGetter const* productGetter() const {return refVector_.refCore().productGetter();}
00108 
00110     bool isNull() const {return !id().isValid();}
00111 
00113     bool isNonnull() const {return !isNull();}
00114 
00116     bool operator!() const {return isNull();}
00117 
00119     // Accessor must get the product if necessary
00120     C const* product() const;
00121 
00124     bool isAvailable() const {return refVector_.refCore().isAvailable();}
00125 
00127     bool isTransient() const {return refVector_.refCore().isTransient();}
00128 
00130     iterator erase(iterator const& pos);
00131 
00133     void clear() {refVector_.clear();}
00134 
00136     void swap(RefVector<C, T, F> & other)  noexcept;
00137 
00139     RefVector& operator=(RefVector const& rhs);
00140 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00141     RefVector& operator=(RefVector  && rhs)  noexcept { 
00142       refVector_ = std::move(rhs.refVector_);
00143       return *this;
00144     }
00145 #endif
00146 
00147     bool hasProductCache() const {return refVector_.refCore().productPtr() != 0;}
00148 
00149     void fillView(ProductID const& id,
00150                   std::vector<void const*>& pointers,
00151                   helper_vector& helpers) const;
00152 
00153     //Needed for ROOT storage
00154     CMS_CLASS_VERSION(10)
00155   private:
00156     contents_type refVector_;
00157   };
00158 
00159   template<typename C, typename T, typename F>
00160   inline
00161   void
00162   RefVector<C, T, F>::swap(RefVector<C, T, F> & other) noexcept {
00163     refVector_.swap(other.refVector_);
00164   }
00165 
00166   template<typename C, typename T, typename F>
00167   inline
00168   RefVector<C, T, F>&
00169   RefVector<C, T, F>::operator=(RefVector<C, T, F> const& rhs) {
00170     RefVector<C, T, F> temp(rhs);
00171     this->swap(temp);
00172     return *this;
00173   }
00174 
00175   template<typename C, typename T, typename F>
00176   inline
00177   void
00178   swap(RefVector<C, T, F> & a, RefVector<C, T, F> & b)  noexcept {
00179     a.swap(b);
00180   }
00181 
00182   template<typename C, typename T, typename F>
00183   void
00184   RefVector<C,T,F>::fillView(ProductID const&,
00185                              std::vector<void const*>& pointers,
00186                              helper_vector& helpers) const {
00187     typedef Ref<C,T,F>                     ref_type;
00188     typedef reftobase::RefHolder<ref_type> holder_type;
00189 
00190     pointers.reserve(this->size());
00191     helpers.reserve(this->size());
00192 
00193     size_type key = 0;
00194     for(const_iterator i=begin(), e=end(); i!=e; ++i, ++key) {
00195       member_type const* address = i->isNull() ? 0 : &**i;
00196       pointers.push_back(address);
00197       holder_type h(ref_type(i->id(), address, i->key(), product()));
00198       helpers.push_back(&h);
00199     }
00200   }
00201 
00202   template<typename C, typename T, typename F>
00203   inline
00204   void
00205   fillView(RefVector<C,T,F> const& obj,
00206            ProductID const& id,
00207            std::vector<void const*>& pointers,
00208            helper_vector& helpers) {
00209     obj.fillView(id, pointers, helpers);
00210   }
00211 
00212   template<typename C, typename T, typename F>
00213   struct has_fillView<RefVector<C,T,F> > {
00214     static bool const value = true;
00215   };
00216 
00217   template<typename C, typename T, typename F>
00218   inline
00219   bool
00220   operator==(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00221     return lhs.refVector() == rhs.refVector();
00222   }
00223 
00224   template<typename C, typename T, typename F>
00225   inline
00226   bool
00227   operator!=(RefVector<C, T, F> const& lhs, RefVector<C, T, F> const& rhs) {
00228     return !(lhs == rhs);
00229   }
00230 
00231   template<typename C, typename T, typename F>
00232   inline
00233   typename RefVector<C, T, F>::iterator
00234   RefVector<C, T, F>::erase(iterator const& pos) {
00235     typename contents_type::keys_type::size_type index = pos - begin();
00236     typename contents_type::keys_type::iterator newPos =
00237       refVector_.eraseAtIndex(index);
00238     RefCore const& prod = refVector_.refCore();
00239     //return typename RefVector<C, T, F>::iterator(prod, newPos);
00240     return iterator(prod, newPos);
00241   }
00242 
00243   template<typename C, typename T, typename F>
00244   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::begin() const {
00245     return iterator(refVector_.refCore(), refVector_.keys().begin());
00246   }
00247 
00248   template<typename C, typename T, typename F>
00249   typename RefVector<C, T, F>::const_iterator RefVector<C, T, F>::end() const {
00250     return iterator(refVector_.refCore(), refVector_.keys().end());
00251   }
00252 
00253   template<typename C, typename T, typename F>
00254   std::ostream&
00255   operator<<(std::ostream& os, RefVector<C,T,F> const& r) {
00256     for(typename RefVector<C,T,F>::const_iterator
00257            i = r.begin(),
00258            e = r.end();
00259            i != e;
00260            ++i) {
00261         os << *i << '\n';
00262       }
00263     return os;
00264   }
00265 }
00266 
00267 #include "DataFormats/Common/interface/RefCoreGet.h"
00268 
00269 namespace edm {
00270 
00271   template<typename C, typename T, typename F>
00272   C const* RefVector<C,T,F>::product() const {
00273     return isNull() ? 0 : edm::template getProduct<C>(refVector_.refCore());
00274   }
00275 }
00276 
00277 #include "DataFormats/Common/interface/GetProduct.h"
00278 namespace edm {
00279   namespace detail {
00280 
00281     template<typename C, typename T, typename F>
00282     struct GetProduct<RefVector<C, T, F> > {
00283       typedef T element_type;
00284       typedef typename RefVector<C, T, F>::const_iterator iter;
00285       static element_type const* address(iter const& i) {
00286         return &**i;
00287       }
00288       static C const* product(RefVector<C, T, F> const& coll) {
00289         return coll.product();
00290       }
00291     };
00292   }
00293 }
00294 #endif