CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_IndirectHolder_h
00002 #define DataFormats_Common_IndirectHolder_h
00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00004 #include "DataFormats/Common/interface/BaseHolder.h"
00005 #include "DataFormats/Common/interface/RefHolderBase.h"
00006 #include "DataFormats/Provenance/interface/ProductID.h"
00007 
00008 #include "boost/shared_ptr.hpp"
00009 #include <memory>
00010 
00011 namespace edm {
00012   template<typename T> class RefToBase;
00013 
00014   namespace reftobase {
00015 
00016     template<typename T> class IndirectVectorHolder;
00017     class RefVectorHolderBase;
00018     class RefHolderBase;
00019 
00020     //------------------------------------------------------------------
00021     // Class template IndirectHolder<T>
00022     //------------------------------------------------------------------
00023 
00024     template <typename T>
00025     class IndirectHolder : public BaseHolder<T> {
00026     public:
00027       // It may be better to use auto_ptr<RefHolderBase> in
00028       // this constructor, so that the cloning can be avoided. I'm not
00029       // sure if use of auto_ptr here causes any troubles elsewhere.
00030       IndirectHolder() : BaseHolder<T>(), helper_( 0 ) { }
00031       IndirectHolder(boost::shared_ptr<RefHolderBase> p);
00032       IndirectHolder(IndirectHolder const& other);
00033       IndirectHolder& operator= (IndirectHolder const& rhs);
00034       void swap(IndirectHolder& other);
00035       virtual ~IndirectHolder();
00036       
00037       virtual BaseHolder<T>* clone() const;
00038       virtual T const* getPtr() const;
00039       virtual ProductID id() const;
00040       virtual size_t key() const;
00041       virtual bool isEqualTo(BaseHolder<T> const& rhs) const;
00042 
00043       virtual bool fillRefIfMyTypeMatches(RefHolderBase& fillme,
00044                                           std::string& msg) const;
00045       virtual std::auto_ptr<RefHolderBase> holder() const;
00046       virtual std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() const;
00047       virtual std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() const;
00048       virtual EDProductGetter const* productGetter() const;
00049       virtual bool hasProductCache() const;
00050       virtual void const * product() const;
00051 
00054       virtual bool isAvailable() const { return helper_->isAvailable(); }
00055 
00056       //Used by ROOT storage
00057       CMS_CLASS_VERSION(10)
00058 
00059     private:
00060       friend class RefToBase<T>;
00061       friend class IndirectVectorHolder<T>;
00062       RefHolderBase* helper_;
00063     };
00064     //------------------------------------------------------------------
00065     // Implementation of IndirectHolder<T>
00066     //------------------------------------------------------------------
00067 
00068     template <typename T>
00069     inline
00070     IndirectHolder<T>::IndirectHolder(boost::shared_ptr<RefHolderBase> p) :
00071       BaseHolder<T>(), helper_(p->clone()) 
00072     { }
00073 
00074     template <typename T>
00075     inline
00076     IndirectHolder<T>::IndirectHolder(IndirectHolder const& other) : 
00077       BaseHolder<T>(other), helper_(other.helper_->clone()) 
00078     { }
00079 
00080     template <typename T>
00081     inline
00082     void
00083     IndirectHolder<T>::swap(IndirectHolder& other) 
00084     {
00085       this->BaseHolder<T>::swap(other);
00086       std::swap(helper_, other.helper_);
00087     }
00088 
00089     template <typename T>
00090     inline
00091     IndirectHolder<T>& 
00092     IndirectHolder<T>::operator= (IndirectHolder const& rhs) 
00093     {
00094       IndirectHolder temp(rhs);
00095       swap(temp);
00096       return *this;
00097     }
00098 
00099     template <typename T>
00100     IndirectHolder<T>::~IndirectHolder()
00101     {
00102       delete helper_;
00103     }
00104 
00105     template <typename T>
00106     BaseHolder<T>* 
00107     IndirectHolder<T>::clone() const
00108     {
00109       return new IndirectHolder<T>(*this);
00110     }
00111 
00112     template <typename T>
00113     T const* 
00114     IndirectHolder<T>::getPtr() const 
00115     {
00116      return helper_-> template getPtr<T>();
00117     }
00118 
00119     template <typename T>
00120     ProductID
00121     IndirectHolder<T>::id() const
00122     {
00123       return helper_->id();
00124     }
00125 
00126     template <typename T>
00127     size_t
00128     IndirectHolder<T>::key() const
00129     {
00130       return helper_->key();
00131     }
00132 
00133     template <typename T>
00134     inline
00135     EDProductGetter const* IndirectHolder<T>::productGetter() const {
00136       return helper_->productGetter();
00137     }
00138 
00139     template <typename T>
00140     inline
00141     bool IndirectHolder<T>::hasProductCache() const {
00142       return helper_->hasProductCache();
00143     }
00144 
00145     template <typename T>
00146     inline
00147     void const * IndirectHolder<T>::product() const {
00148       return helper_->product();
00149     }
00150 
00151     template <typename T>
00152     bool
00153     IndirectHolder<T>::isEqualTo(BaseHolder<T> const& rhs) const 
00154     {
00155       IndirectHolder const* h = dynamic_cast<IndirectHolder const*>(&rhs);
00156       return h && helper_->isEqualTo(*h->helper_);
00157     }
00158 
00159     template <typename T>
00160     bool
00161     IndirectHolder<T>::fillRefIfMyTypeMatches(RefHolderBase& fillme,
00162                                               std::string& msg) const
00163     {
00164       return helper_->fillRefIfMyTypeMatches(fillme, msg);
00165     }
00166 
00167     template <typename T>
00168     std::auto_ptr<RefHolderBase> IndirectHolder<T>::holder() const { 
00169       return std::auto_ptr<RefHolderBase>( helper_->clone() ); 
00170     }
00171 
00172     // Free swap function
00173     template <typename T>
00174     inline
00175     void
00176     swap(IndirectHolder<T>& lhs, IndirectHolder<T>& rhs) {
00177       lhs.swap(rhs);
00178     }
00179   }
00180 
00181 }
00182 
00183 #include "DataFormats/Common/interface/IndirectVectorHolder.h"
00184 #include "DataFormats/Common/interface/RefVectorHolderBase.h"
00185 
00186 namespace edm {
00187   namespace reftobase {
00188     template <typename T>
00189     std::auto_ptr<BaseVectorHolder<T> > IndirectHolder<T>::makeVectorHolder() const {
00190       std::auto_ptr<RefVectorHolderBase> p = helper_->makeVectorHolder();
00191       boost::shared_ptr<RefVectorHolderBase> sp( p );
00192       return std::auto_ptr<BaseVectorHolder<T> >( new IndirectVectorHolder<T>( sp ) );
00193     }
00194 
00195     template <typename T>
00196     std::auto_ptr<RefVectorHolderBase> IndirectHolder<T>::makeVectorBaseHolder() const {
00197       return helper_->makeVectorHolder();
00198     }
00199   }
00200 }
00201 
00202 #endif