CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/Common/interface/VectorHolder.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_VectorHolder_h
00002 #define DataFormats_Common_VectorHolder_h
00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00004 #include "DataFormats/Common/interface/BaseVectorHolder.h"
00005 #include "DataFormats/Common/interface/Holder.h"
00006 #include <memory>
00007 #include "FWCore/Utilities/interface/GCC11Compatibility.h"
00008 
00009 namespace edm {
00010   namespace reftobase {
00011     
00012     class RefVectorHolderBase;
00013     
00014     template <class T, class REFV>
00015     class VectorHolder : public BaseVectorHolder<T> {
00016     public:
00017       typedef BaseVectorHolder<T>                base_type;
00018       typedef typename base_type::size_type      size_type;
00019       typedef typename base_type::element_type   element_type;
00020       typedef typename base_type::base_ref_type  base_ref_type;
00021       typedef typename base_type::const_iterator const_iterator;
00022       typedef REFV                               ref_vector_type;
00023       
00024       VectorHolder() : base_type() {}
00025       VectorHolder(VectorHolder const & rh) :  base_type(rh),  refVector_(rh.refVector_){}
00026 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00027       VectorHolder(VectorHolder && rh)  noexcept :  base_type(std::forward(rh)),  refVector_(std::move(rh.refVector_)){}
00028  #endif
00029 
00030       explicit VectorHolder(const ref_vector_type& iRefVector) : base_type(), refVector_(iRefVector) {}
00031       explicit VectorHolder(const ProductID& iId) : base_type(), refVector_(iId) {}
00032       virtual ~VectorHolder()  noexcept {}
00033       virtual base_type* clone() const { return new VectorHolder(*this); }
00034       virtual base_type* cloneEmpty() const { return new VectorHolder(refVector_.id()); }
00035       base_ref_type const at(size_type idx) const { return base_ref_type( refVector_.at( idx ) ); }
00036       bool empty() const { return refVector_.empty(); }
00037       size_type size() const { return refVector_.size(); }
00038       //size_type capacity() const { return refVector_.capacity(); }
00039       //void reserve(size_type n) { refVector_.reserve(n); }
00040       void clear() { refVector_.clear(); }
00041       ProductID id() const { return refVector_.id(); }
00042       EDProductGetter const* productGetter() const { return refVector_.productGetter(); }
00043       void swap(VectorHolder& other)  noexcept {
00044         this->BaseVectorHolder<T>::swap(other);
00045         refVector_.swap(other.refVector_);
00046       }
00047       VectorHolder& operator=(VectorHolder const& rhs) {
00048         VectorHolder temp(rhs);
00049         this->swap(temp);
00050         return *this;
00051       }
00052 #if defined(__GXX_EXPERIMENTAL_CXX0X__)
00053      VectorHolder& operator=(VectorHolder && rhs)  noexcept {
00054        base_type::operator=(std::forward(rhs));
00055        refVector_ = std::move(rhs.refVector_);
00056        return *this;
00057      }
00058 #endif
00059       
00060       const_iterator begin() const {
00061         return const_iterator( new const_iterator_imp_specific( refVector_.begin() ) );
00062       }
00063       const_iterator end() const {
00064         return const_iterator( new const_iterator_imp_specific( refVector_.end() ) );
00065       }
00066       virtual void push_back( const BaseHolder<T> * r ) {
00067         typedef Holder<T, typename REFV::value_type > holder_type;
00068         const holder_type * h = dynamic_cast<const holder_type *>( r );
00069         if( h == 0 )
00070           Exception::throwThis( errors::InvalidReference,
00071                                "In VectorHolder<T, REFV> trying to push_back wrong reference type");
00072         refVector_.push_back( h->getRef() );
00073       }
00074       virtual std::auto_ptr<RefVectorHolderBase> vectorHolder() const {
00075         return std::auto_ptr<RefVectorHolderBase>( new RefVectorHolder<REFV>( refVector_ ) );
00076       }
00077       virtual const void * product() const {
00078         return refVector_.product();
00079       }
00080       
00083       virtual bool isAvailable() const { return refVector_.isAvailable(); }
00084       
00085       //Used by ROOT storage
00086       CMS_CLASS_VERSION(10)
00087 
00088     private:
00089       typedef typename base_type::const_iterator_imp const_iterator_imp;
00090       
00091       ref_vector_type refVector_;
00092       
00093       // the following structure is public
00094       // to allow reflex dictionary to compile
00095     public:
00096       struct const_iterator_imp_specific : public const_iterator_imp {
00097         typedef ptrdiff_t difference_type;
00098         const_iterator_imp_specific() { }
00099         explicit const_iterator_imp_specific( const typename REFV::const_iterator & it ) : i ( it ) { }
00100         ~const_iterator_imp_specific() { }
00101         const_iterator_imp_specific * clone() const { return new const_iterator_imp_specific( i ); }
00102         void increase() { ++i; }
00103         void decrease() { --i; }
00104         void increase( difference_type d ) { i += d; }
00105         void decrease( difference_type d ) { i -= d; }
00106         bool equal_to( const const_iterator_imp * o ) const { return i == dc( o ); }
00107         bool less_than( const const_iterator_imp * o ) const { return i < dc( o ); }
00108         void assign( const const_iterator_imp * o ) { i = dc( o ); }
00109         base_ref_type deref() const { return base_ref_type( * i ); }
00110         difference_type difference( const const_iterator_imp * o ) const { return i - dc( o ); }
00111       private:
00112         const typename ref_vector_type::const_iterator & dc( const const_iterator_imp * o ) const {
00113           if ( o == 0 )
00114             Exception::throwThis( errors::InvalidReference,
00115                                  "In RefToBaseVector<T> trying to dereference a null pointer");
00116           const const_iterator_imp_specific * oo = dynamic_cast<const const_iterator_imp_specific *>( o );
00117           if ( oo == 0 )
00118             Exception::throwThis( errors::InvalidReference,
00119                                  "In RefToBaseVector<T> trying to cast iterator to wrong type ");
00120           return oo->i;
00121         }
00122         typename ref_vector_type::const_iterator i;
00123       };
00124     };
00125     
00126     // Free swap function
00127     template <typename T, typename REFV>
00128     inline
00129     void
00130     swap(VectorHolder<T, REFV>& lhs, VectorHolder<T, REFV>& rhs)  noexcept {
00131       lhs.swap(rhs);
00132     }
00133   }
00134 }
00135 
00136 #endif