![]() |
![]() |
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