CMS 3D CMS Logo

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