CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DataFormats/Common/interface/IndirectVectorHolder.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_IndirectVectorHolder_h
00002 #define DataFormats_Common_IndirectVectorHolder_h
00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00004 #include "DataFormats/Common/interface/BaseVectorHolder.h"
00005 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
00006 #include "DataFormats/Common/interface/IndirectHolder.h"
00007 #include <memory>
00008 
00009 namespace edm {
00010   namespace reftobase {
00011 
00012     template <typename T>
00013     class IndirectVectorHolder : public BaseVectorHolder<T> {
00014     public:
00015       typedef BaseVectorHolder<T>                base_type;
00016       typedef typename base_type::size_type      size_type;
00017       typedef typename base_type::element_type   element_type;
00018       typedef typename base_type::base_ref_type  base_ref_type;
00019       typedef typename base_type::const_iterator const_iterator;
00020 
00021       IndirectVectorHolder();
00022       IndirectVectorHolder( const IndirectVectorHolder & other);
00023       IndirectVectorHolder(boost::shared_ptr<RefVectorHolderBase> p);
00024       IndirectVectorHolder(RefVectorHolderBase * p);
00025       virtual ~IndirectVectorHolder();
00026       IndirectVectorHolder& operator= (IndirectVectorHolder const& rhs);
00027       void swap(IndirectVectorHolder& other);
00028       virtual BaseVectorHolder<T>* clone() const;
00029       virtual BaseVectorHolder<T>* cloneEmpty() const;
00030       virtual ProductID id() const;
00031       virtual EDProductGetter const* productGetter() const;
00032       virtual bool empty() const;
00033       virtual size_type size() const;
00034       virtual void clear();
00035       virtual base_ref_type const at(size_type idx) const;
00036       virtual std::auto_ptr<reftobase::RefVectorHolderBase> vectorHolder() const {
00037         return std::auto_ptr<reftobase::RefVectorHolderBase>( helper_->clone() );
00038       }
00039       virtual void push_back( const BaseHolder<T> * r ) {
00040         typedef IndirectHolder<T> holder_type;
00041         const holder_type * h = dynamic_cast<const holder_type *>( r );
00042         if( h == 0 )
00043           Exception::throwThis( errors::InvalidReference,
00044             "In IndirectHolder<T> trying to push_back wrong reference type");
00045         helper_->push_back( h->helper_ );
00046       }
00047       virtual const void * product() const {
00048         return helper_->product();
00049       }
00050 
00053       virtual bool isAvailable() const { return helper_->isAvailable(); }
00054 
00055       //Used by ROOT storage
00056       CMS_CLASS_VERSION(10)
00057 
00058     private:
00059       typedef typename base_type::const_iterator_imp const_iterator_imp;
00060       RefVectorHolderBase * helper_;
00061 
00062     public:
00063       struct const_iterator_imp_specific : public const_iterator_imp {
00064         typedef ptrdiff_t difference_type;
00065         const_iterator_imp_specific() { }
00066         explicit const_iterator_imp_specific( const typename RefVectorHolderBase::const_iterator & it ) : i ( it ) { }
00067         ~const_iterator_imp_specific() { }
00068         const_iterator_imp_specific * clone() const { return new const_iterator_imp_specific( i ); }
00069         void increase() { ++i; }
00070         void decrease() { --i; }
00071         void increase( difference_type d ) { i += d; }
00072         void decrease( difference_type d ) { i -= d; }
00073         bool equal_to( const const_iterator_imp * o ) const { return i == dc( o ); }
00074         bool less_than( const const_iterator_imp * o ) const { return i < dc( o ); }
00075         void assign( const const_iterator_imp * o ) { i = dc( o ); }
00076         base_ref_type deref() const {
00077           return base_ref_type( * i );
00078         }
00079         difference_type difference( const const_iterator_imp * o ) const { return i - dc( o ); }
00080       private:
00081         const typename RefVectorHolderBase::const_iterator & dc( const const_iterator_imp * o ) const {
00082           if ( o == 0 ) {
00083             Exception::throwThis( edm::errors::InvalidReference,
00084               "In IndirectVectorHolder trying to dereference a null pointer");
00085           }
00086           const const_iterator_imp_specific * oo = dynamic_cast<const const_iterator_imp_specific *>( o );
00087           if ( oo == 0 ) {
00088             Exception::throwThis( errors::InvalidReference,
00089               "In IndirectVectorHolder trying to cast iterator to wrong type ");
00090           }
00091           return oo->i;
00092         }
00093         typename RefVectorHolderBase::const_iterator i;
00094       };
00095 
00096       const_iterator begin() const {
00097         return const_iterator( new const_iterator_imp_specific( helper_->begin() ) );
00098       }
00099       const_iterator end() const {
00100         return const_iterator( new const_iterator_imp_specific( helper_->end() ) );
00101       }
00102     };
00103 
00104     template <typename T>
00105     IndirectVectorHolder<T>::IndirectVectorHolder() : BaseVectorHolder<T>(), helper_( 0 ) { }
00106 
00107     template <typename T>
00108     IndirectVectorHolder<T>::IndirectVectorHolder(boost::shared_ptr<RefVectorHolderBase> p) :
00109       BaseVectorHolder<T>(), helper_(p->clone()) { }
00110 
00111     template <typename T>
00112     IndirectVectorHolder<T>::IndirectVectorHolder(RefVectorHolderBase * p) :
00113       BaseVectorHolder<T>(), helper_(p) { }
00114 
00115     template <typename T>
00116     IndirectVectorHolder<T>::IndirectVectorHolder( const IndirectVectorHolder & other ) :
00117       BaseVectorHolder<T>(), helper_( other.helper_->clone() ) { }
00118 
00119     template <typename T>
00120     IndirectVectorHolder<T>::~IndirectVectorHolder() {
00121       delete helper_;
00122     }
00123 
00124     template <typename T>
00125     inline void IndirectVectorHolder<T>::swap(IndirectVectorHolder& other) {
00126       this->BaseVectorHolder<T>::swap(other);
00127       std::swap(helper_, other.helper_);
00128     }
00129 
00130     template <typename T>
00131     inline IndirectVectorHolder<T>&
00132     IndirectVectorHolder<T>::operator=(IndirectVectorHolder const& rhs) {
00133       IndirectVectorHolder temp(rhs);
00134       swap(temp);
00135       return *this;
00136     }
00137 
00138     template <typename T>
00139     BaseVectorHolder<T>*
00140     IndirectVectorHolder<T>::clone() const {
00141       return new IndirectVectorHolder<T>(*this);
00142     }
00143 
00144     template <typename T>
00145     BaseVectorHolder<T>*
00146     IndirectVectorHolder<T>::cloneEmpty() const {
00147       return new IndirectVectorHolder<T>( helper_->cloneEmpty() );
00148     }
00149 
00150     template <typename T>
00151     ProductID
00152     IndirectVectorHolder<T>::id() const {
00153       return helper_->id();
00154     }
00155 
00156     template <typename T>
00157     EDProductGetter const* IndirectVectorHolder<T>::productGetter() const {
00158       return helper_->productGetter();
00159     }
00160 
00161     template <typename T>
00162     bool IndirectVectorHolder<T>::empty() const {
00163       return helper_->empty();
00164     }
00165 
00166     template <typename T>
00167     typename IndirectVectorHolder<T>::size_type IndirectVectorHolder<T>::size() const {
00168       return helper_->size();
00169     }
00170 
00171     template <typename T>
00172     void IndirectVectorHolder<T>::clear() {
00173       return helper_->clear();
00174     }
00175 
00176     template <typename T>
00177     typename IndirectVectorHolder<T>::base_ref_type const IndirectVectorHolder<T>::at(size_type idx) const {
00178       return helper_ ? helper_->template getRef<T>( idx ) : typename IndirectVectorHolder<T>::base_ref_type();
00179     }
00180 
00181     // Free swap function
00182     template <typename T>
00183     inline
00184     void swap(IndirectVectorHolder<T>& lhs, IndirectVectorHolder<T>& rhs) {
00185       lhs.swap(rhs);
00186     }
00187   }
00188 }
00189 
00190 #endif
00191 
00192