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 "FWCore/Utilities/interface/TypeWithDict.h" 00008 #include "FWCore/Utilities/interface/DictionaryTools.h" 00009 #include <memory> 00010 00011 namespace edm { 00012 namespace reftobase { 00013 //------------------------------------------------------------------ 00014 // Class template RefHolder<REF> 00015 //------------------------------------------------------------------ 00016 00017 00018 template <class REF> 00019 class RefHolder : public RefHolderBase { 00020 public: 00021 RefHolder(); 00022 explicit RefHolder(REF const& ref); 00023 void swap(RefHolder& other); 00024 virtual ~RefHolder(); 00025 virtual RefHolderBase* clone() const; 00026 00027 virtual ProductID id() const; 00028 virtual size_t key() const; 00029 virtual bool isEqualTo(RefHolderBase const& rhs) const; 00030 virtual bool fillRefIfMyTypeMatches(RefHolderBase& fillme, 00031 std::string& msg) const; 00032 REF const& getRef() const; 00033 void setRef(REF const& r); 00034 virtual std::auto_ptr<RefVectorHolderBase> makeVectorHolder() const; 00035 virtual EDProductGetter const* productGetter() const; 00036 virtual bool hasProductCache() const; 00037 virtual void const * product() const; 00038 00041 virtual bool isAvailable() const { return ref_.isAvailable(); } 00042 00043 //Needed for ROOT storage 00044 CMS_CLASS_VERSION(10) 00045 private: 00046 virtual void const* pointerToType(TypeWithDict const& iToType) const; 00047 REF ref_; 00048 }; 00049 00050 //------------------------------------------------------------------ 00051 // Implementation of RefHolder<REF> 00052 //------------------------------------------------------------------ 00053 00054 template <class REF> 00055 RefHolder<REF>::RefHolder() : 00056 RefHolderBase(), ref_() 00057 { } 00058 00059 template <class REF> 00060 RefHolder<REF>::RefHolder(REF const& ref) : 00061 RefHolderBase(), ref_(ref) 00062 { } 00063 00064 template <class REF> 00065 RefHolder<REF>::~RefHolder() 00066 { } 00067 00068 template <class REF> 00069 RefHolderBase* 00070 RefHolder<REF>::clone() const 00071 { 00072 return new RefHolder(ref_); 00073 } 00074 00075 template <class REF> 00076 ProductID 00077 RefHolder<REF>::id() const 00078 { 00079 return ref_.id(); 00080 } 00081 00082 template <class REF> 00083 bool 00084 RefHolder<REF>::isEqualTo(RefHolderBase const& rhs) const 00085 { 00086 RefHolder const* h(dynamic_cast<RefHolder const*>(&rhs)); 00087 return h && (getRef() == h->getRef()); 00088 } 00089 00090 template <class REF> 00091 bool 00092 RefHolder<REF>::fillRefIfMyTypeMatches(RefHolderBase& fillme, 00093 std::string& msg) const 00094 { 00095 RefHolder* h = dynamic_cast<RefHolder*>(&fillme); 00096 bool conversion_worked = (h != 0); 00097 if (conversion_worked) 00098 h->setRef(ref_); 00099 else 00100 msg = typeid(REF).name(); 00101 return conversion_worked; 00102 } 00103 00104 template <class REF> 00105 inline 00106 REF const& 00107 RefHolder<REF>::getRef() const 00108 { 00109 return ref_; 00110 } 00111 00112 template<class REF> 00113 EDProductGetter const* RefHolder<REF>::productGetter() const { 00114 return ref_.productGetter(); 00115 } 00116 00117 template<class REF> 00118 bool RefHolder<REF>::hasProductCache() const { 00119 return ref_.hasProductCache(); 00120 } 00121 00122 template<class REF> 00123 void const * RefHolder<REF>::product() const { 00124 return ref_.product(); 00125 } 00126 00127 template <class REF> 00128 inline 00129 void 00130 RefHolder<REF>::swap(RefHolder& other) 00131 { 00132 std::swap(ref_, other.ref_); 00133 } 00134 00135 template <class REF> 00136 inline 00137 void 00138 RefHolder<REF>::setRef(REF const& r) 00139 { 00140 ref_ = r; 00141 } 00142 00143 template <class REF> 00144 void const* 00145 RefHolder<REF>::pointerToType(TypeWithDict const& iToType) const 00146 { 00147 typedef typename REF::value_type contained_type; 00148 static TypeWithDict const s_type(typeid(contained_type)); 00149 00150 return iToType.pointerToContainedType(ref_.get(), s_type); 00151 } 00152 } // namespace reftobase 00153 } 00154 00155 #endif