CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:29:56 2009 for CMSSW by  doxygen 1.5.4