CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:30:39 2009 for CMSSW by  doxygen 1.5.4