00001 #ifndef DataFormats_Common_IndirectHolder_h 00002 #define DataFormats_Common_IndirectHolder_h 00003 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" 00004 #include "DataFormats/Common/interface/BaseHolder.h" 00005 #include "DataFormats/Common/interface/RefHolderBase.h" 00006 #include "DataFormats/Provenance/interface/ProductID.h" 00007 00008 #include "boost/shared_ptr.hpp" 00009 #include <memory> 00010 00011 namespace edm { 00012 template<typename T> class RefToBase; 00013 00014 namespace reftobase { 00015 00016 template<typename T> class IndirectVectorHolder; 00017 class RefVectorHolderBase; 00018 class RefHolderBase; 00019 00020 //------------------------------------------------------------------ 00021 // Class template IndirectHolder<T> 00022 //------------------------------------------------------------------ 00023 00024 template <typename T> 00025 class IndirectHolder : public BaseHolder<T> { 00026 public: 00027 // It may be better to use auto_ptr<RefHolderBase> in 00028 // this constructor, so that the cloning can be avoided. I'm not 00029 // sure if use of auto_ptr here causes any troubles elsewhere. 00030 IndirectHolder() : BaseHolder<T>(), helper_( 0 ) { } 00031 IndirectHolder(boost::shared_ptr<RefHolderBase> p); 00032 IndirectHolder(IndirectHolder const& other); 00033 IndirectHolder& operator= (IndirectHolder const& rhs); 00034 void swap(IndirectHolder& other); 00035 virtual ~IndirectHolder(); 00036 00037 virtual BaseHolder<T>* clone() const; 00038 virtual T const* getPtr() const; 00039 virtual ProductID id() const; 00040 virtual size_t key() const; 00041 virtual bool isEqualTo(BaseHolder<T> const& rhs) const; 00042 00043 virtual bool fillRefIfMyTypeMatches(RefHolderBase& fillme, 00044 std::string& msg) const; 00045 virtual std::auto_ptr<RefHolderBase> holder() const; 00046 virtual std::auto_ptr<BaseVectorHolder<T> > makeVectorHolder() const; 00047 virtual std::auto_ptr<RefVectorHolderBase> makeVectorBaseHolder() const; 00048 virtual EDProductGetter const* productGetter() const; 00049 virtual bool hasProductCache() const; 00050 virtual void const * product() const; 00051 00054 virtual bool isAvailable() const { return helper_->isAvailable(); } 00055 00056 //Used by ROOT storage 00057 CMS_CLASS_VERSION(10) 00058 00059 private: 00060 friend class RefToBase<T>; 00061 friend class IndirectVectorHolder<T>; 00062 RefHolderBase* helper_; 00063 }; 00064 //------------------------------------------------------------------ 00065 // Implementation of IndirectHolder<T> 00066 //------------------------------------------------------------------ 00067 00068 template <typename T> 00069 inline 00070 IndirectHolder<T>::IndirectHolder(boost::shared_ptr<RefHolderBase> p) : 00071 BaseHolder<T>(), helper_(p->clone()) 00072 { } 00073 00074 template <typename T> 00075 inline 00076 IndirectHolder<T>::IndirectHolder(IndirectHolder const& other) : 00077 BaseHolder<T>(other), helper_(other.helper_->clone()) 00078 { } 00079 00080 template <typename T> 00081 inline 00082 void 00083 IndirectHolder<T>::swap(IndirectHolder& other) 00084 { 00085 this->BaseHolder<T>::swap(other); 00086 std::swap(helper_, other.helper_); 00087 } 00088 00089 template <typename T> 00090 inline 00091 IndirectHolder<T>& 00092 IndirectHolder<T>::operator= (IndirectHolder const& rhs) 00093 { 00094 IndirectHolder temp(rhs); 00095 swap(temp); 00096 return *this; 00097 } 00098 00099 template <typename T> 00100 IndirectHolder<T>::~IndirectHolder() 00101 { 00102 delete helper_; 00103 } 00104 00105 template <typename T> 00106 BaseHolder<T>* 00107 IndirectHolder<T>::clone() const 00108 { 00109 return new IndirectHolder<T>(*this); 00110 } 00111 00112 template <typename T> 00113 T const* 00114 IndirectHolder<T>::getPtr() const 00115 { 00116 return helper_-> template getPtr<T>(); 00117 } 00118 00119 template <typename T> 00120 ProductID 00121 IndirectHolder<T>::id() const 00122 { 00123 return helper_->id(); 00124 } 00125 00126 template <typename T> 00127 size_t 00128 IndirectHolder<T>::key() const 00129 { 00130 return helper_->key(); 00131 } 00132 00133 template <typename T> 00134 inline 00135 EDProductGetter const* IndirectHolder<T>::productGetter() const { 00136 return helper_->productGetter(); 00137 } 00138 00139 template <typename T> 00140 inline 00141 bool IndirectHolder<T>::hasProductCache() const { 00142 return helper_->hasProductCache(); 00143 } 00144 00145 template <typename T> 00146 inline 00147 void const * IndirectHolder<T>::product() const { 00148 return helper_->product(); 00149 } 00150 00151 template <typename T> 00152 bool 00153 IndirectHolder<T>::isEqualTo(BaseHolder<T> const& rhs) const 00154 { 00155 IndirectHolder const* h = dynamic_cast<IndirectHolder const*>(&rhs); 00156 return h && helper_->isEqualTo(*h->helper_); 00157 } 00158 00159 template <typename T> 00160 bool 00161 IndirectHolder<T>::fillRefIfMyTypeMatches(RefHolderBase& fillme, 00162 std::string& msg) const 00163 { 00164 return helper_->fillRefIfMyTypeMatches(fillme, msg); 00165 } 00166 00167 template <typename T> 00168 std::auto_ptr<RefHolderBase> IndirectHolder<T>::holder() const { 00169 return std::auto_ptr<RefHolderBase>( helper_->clone() ); 00170 } 00171 00172 // Free swap function 00173 template <typename T> 00174 inline 00175 void 00176 swap(IndirectHolder<T>& lhs, IndirectHolder<T>& rhs) { 00177 lhs.swap(rhs); 00178 } 00179 } 00180 00181 } 00182 00183 #include "DataFormats/Common/interface/IndirectVectorHolder.h" 00184 #include "DataFormats/Common/interface/RefVectorHolderBase.h" 00185 00186 namespace edm { 00187 namespace reftobase { 00188 template <typename T> 00189 std::auto_ptr<BaseVectorHolder<T> > IndirectHolder<T>::makeVectorHolder() const { 00190 std::auto_ptr<RefVectorHolderBase> p = helper_->makeVectorHolder(); 00191 boost::shared_ptr<RefVectorHolderBase> sp( p ); 00192 return std::auto_ptr<BaseVectorHolder<T> >( new IndirectVectorHolder<T>( sp ) ); 00193 } 00194 00195 template <typename T> 00196 std::auto_ptr<RefVectorHolderBase> IndirectHolder<T>::makeVectorBaseHolder() const { 00197 return helper_->makeVectorHolder(); 00198 } 00199 } 00200 } 00201 00202 #endif