CMS 3D CMS Logo

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