CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/Common/interface/RefHolder_.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefHolder__h
00002 #define DataFormats_Common_RefHolder__h
00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00004 
00005 #include "DataFormats/Common/interface/RefHolderBase.h"
00006 #include "DataFormats/Provenance/interface/ProductID.h"
00007 #include "Reflex/Object.h"
00008 #include "Reflex/Type.h"
00009 #include "FWCore/Utilities/interface/UseReflex.h"
00010 #include <memory>
00011 
00012 namespace edm {
00013   namespace reftobase {
00014      //------------------------------------------------------------------
00015     // Class template RefHolder<REF>
00016     //------------------------------------------------------------------
00017 
00018 
00019     template <class REF>
00020     class RefHolder : public RefHolderBase {
00021     public:
00022       RefHolder();
00023       explicit RefHolder(REF const& ref);
00024       void swap(RefHolder& other);
00025       virtual ~RefHolder();
00026       virtual RefHolderBase* clone() const;
00027 
00028       virtual ProductID id() const;
00029       virtual size_t key() const;
00030       virtual bool isEqualTo(RefHolderBase const& rhs) const;
00031       virtual bool fillRefIfMyTypeMatches(RefHolderBase& fillme,
00032                                           std::string& msg) const;
00033       REF const& getRef() const;
00034       void setRef(REF const& r);
00035       virtual std::auto_ptr<RefVectorHolderBase> makeVectorHolder() const;
00036       virtual EDProductGetter const* productGetter() const;
00037       virtual bool hasProductCache() const;
00038       virtual void const * product() const;
00039 
00042       virtual bool isAvailable() const { return ref_.isAvailable(); }
00043 
00044       //Needed for ROOT storage
00045       CMS_CLASS_VERSION(10)
00046     private:
00047       virtual void const* pointerToType(Reflex::Type const& iToType) const;
00048       REF ref_;
00049     };
00050 
00051     //------------------------------------------------------------------
00052     // Implementation of RefHolder<REF>
00053     //------------------------------------------------------------------
00054 
00055     template <class REF>
00056     RefHolder<REF>::RefHolder() : 
00057       RefHolderBase(), ref_()
00058     { }
00059   
00060     template <class REF>
00061     RefHolder<REF>::RefHolder(REF const& ref) : 
00062       RefHolderBase(), ref_(ref) 
00063     { }
00064 
00065     template <class REF>
00066     RefHolder<REF>::~RefHolder() 
00067     { }
00068 
00069     template <class REF>
00070     RefHolderBase* 
00071     RefHolder<REF>::clone() const
00072     {
00073       return new RefHolder(ref_);
00074     }
00075 
00076     template <class REF>
00077     ProductID
00078     RefHolder<REF>::id() const 
00079     {
00080       return ref_.id();
00081     }
00082 
00083     template <class REF>
00084     bool
00085     RefHolder<REF>::isEqualTo(RefHolderBase const& rhs) const 
00086     { 
00087       RefHolder const* h(dynamic_cast<RefHolder const*>(&rhs));
00088       return h && (getRef() == h->getRef());
00089     }
00090 
00091     template <class REF>
00092     bool 
00093     RefHolder<REF>::fillRefIfMyTypeMatches(RefHolderBase& fillme,
00094                                            std::string& msg) const
00095     {
00096       RefHolder* h = dynamic_cast<RefHolder*>(&fillme);
00097       bool conversion_worked = (h != 0);
00098       if (conversion_worked)
00099         h->setRef(ref_);
00100       else
00101         msg = typeid(REF).name();
00102       return conversion_worked;
00103     }
00104 
00105     template <class REF>
00106     inline
00107     REF const&
00108     RefHolder<REF>::getRef() const
00109     {
00110       return ref_;
00111     }
00112 
00113     template<class REF>
00114     EDProductGetter const* RefHolder<REF>::productGetter() const {
00115       return ref_.productGetter();
00116     }
00117 
00118     template<class REF>
00119     bool RefHolder<REF>::hasProductCache() const {
00120       return ref_.hasProductCache();
00121     }
00122 
00123     template<class REF>
00124     void const * RefHolder<REF>::product() const {
00125       return ref_.product();
00126     }
00127 
00128     template <class REF>
00129     inline
00130     void
00131     RefHolder<REF>::swap(RefHolder& other)
00132     {
00133       std::swap(ref_, other.ref_);
00134     }
00135 
00136     template <class REF>
00137     inline
00138     void
00139     RefHolder<REF>::setRef(REF const& r)
00140     {
00141       ref_ = r;
00142     }
00143 
00144     template <class REF>
00145     void const* 
00146     RefHolder<REF>::pointerToType(Reflex::Type const& iToType) const 
00147     {
00148       typedef typename REF::value_type contained_type;
00149       static const Reflex::Type s_type(Reflex::Type::ByTypeInfo(typeid(contained_type)));
00150     
00151       // The const_cast below is needed because
00152       // Object's constructor requires a pointer to
00153       // non-const void, although the implementation does not, of
00154       // course, modify the object to which the pointer points.
00155       Reflex::Object obj(s_type, const_cast<void*>(static_cast<const void*>(ref_.get())));
00156       if ( s_type == iToType ) return obj.Address();
00157       Reflex::Object cast = obj.CastObject(iToType);
00158       return cast.Address(); // returns void*, after pointer adjustment
00159     }
00160   } // namespace reftobase
00161 }
00162 
00163 #endif