00001 #ifndef DataFormats_Common_BaseHolder_h 00002 #define DataFormats_Common_BaseHolder_h 00003 00004 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" 00005 #include "DataFormats/Common/interface/EDProductGetter.h" 00006 00007 #include <memory> 00008 #include <string> 00009 00010 namespace edm { 00011 class ProductID; 00012 class RefHolderBase; 00013 00014 namespace reftobase { 00015 template<typename T> class BaseVectorHolder; 00016 class RefVectorHolderBase; 00017 00018 //------------------------------------------------------------------ 00019 // Class template BaseHolder<T> 00020 // 00021 // BaseHolder<T> is an abstract base class that manages a single 00022 // edm::Ref to an element of type T in a collection in the Event; 00023 // the purpose of this abstraction is to hide the type of the 00024 // collection from code that can not know about that type. 00025 // 00026 //------------------------------------------------------------------ 00027 template <typename T> 00028 class BaseHolder { 00029 public: 00030 BaseHolder(); 00031 virtual ~BaseHolder(); 00032 virtual BaseHolder<T>* clone() const = 0; 00033 00034 void swap(BaseHolder&); 00035 00036 // Return the address of the element to which the hidden Ref 00037 // refers. 00038 virtual T const* getPtr() const = 0; 00039 00040 // Return the ProductID of the collection to which the hidden 00041 // Ref refers. 00042 virtual ProductID id() const = 0; 00043 virtual size_t key() const = 0; 00044 // Check to see if the Ref hidden in 'rhs' is equal to the Ref 00045 // hidden in 'this'. They can not be equal if they are of 00046 // different types. Note that the equality test also returns 00047 // false if dynamic type of 'rhs' is different from the dynamic 00048 // type of 'this', *even when the hiddens Refs are actually 00049 // equivalent*. 00050 virtual bool isEqualTo(BaseHolder<T> const& rhs) const = 0; 00051 00052 // If the type of Ref I contain matches the type contained in 00053 // 'fillme', set the Ref in 'fillme' equal to mine and return 00054 // true. If not, write the name of the type I really contain to 00055 // msg, and return false. 00056 virtual bool fillRefIfMyTypeMatches(RefHolderBase& fillme, 00057 std::string& msg) const = 0; 00058 virtual std::auto_ptr<RefHolderBase> holder() const = 0; 00059 00060 virtual std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() const = 0; 00061 virtual std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() const = 0; 00062 00063 virtual EDProductGetter const* productGetter() const = 0; 00064 virtual bool hasProductCache() const = 0; 00065 virtual void const* product() const = 0; 00066 00069 virtual bool isAvailable() const = 0; 00070 00071 //Used by ROOT storage 00072 CMS_CLASS_VERSION(10) 00073 00074 protected: 00075 // We want the following called only by derived classes. 00076 BaseHolder(BaseHolder const& other); 00077 BaseHolder& operator=(BaseHolder const& rhs); 00078 00079 private: 00080 }; 00081 00082 //------------------------------------------------------------------ 00083 // Implementation of BaseHolder<T> 00084 //------------------------------------------------------------------ 00085 00086 template <typename T> 00087 BaseHolder<T>::BaseHolder() { 00088 } 00089 00090 template <typename T> 00091 BaseHolder<T>::BaseHolder(BaseHolder const& /*other*/) { 00092 // Nothing to do. 00093 } 00094 00095 template <typename T> 00096 BaseHolder<T>& 00097 BaseHolder<T>::operator=(BaseHolder<T> const& /*other*/) { 00098 // No data to assign. 00099 return *this; 00100 } 00101 00102 template <typename T> 00103 BaseHolder<T>::~BaseHolder() { 00104 // nothing to do. 00105 } 00106 00107 template <typename T> 00108 void 00109 BaseHolder<T>::swap(BaseHolder<T>& /*other*/) { 00110 // nothing to do. 00111 } 00112 00113 // Free swap function 00114 template <typename T> 00115 inline 00116 void 00117 swap(BaseHolder<T>& lhs, BaseHolder<T>& rhs) { 00118 lhs.swap(rhs); 00119 } 00120 } 00121 } 00122 00123 #endif