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