00001 #ifndef DataFormats_Common_RefToBase_h
00002 #define DataFormats_Common_RefToBase_h
00003
00004
00005
00006
00007
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "boost/shared_ptr.hpp"
00039 #include "boost/static_assert.hpp"
00040 #include "boost/type_traits/is_base_of.hpp"
00041 #include "DataFormats/Common/interface/EDProductfwd.h"
00042 #include "FWCore/Utilities/interface/EDMException.h"
00043 #include "DataFormats/Common/interface/BaseHolder.h"
00044
00045 #include "DataFormats/Common/interface/Holder.h"
00046 #include "DataFormats/Common/interface/IndirectHolder.h"
00047 #include "DataFormats/Common/interface/RefHolder.h"
00048
00049 namespace edm {
00050
00051
00052
00053
00057
00058 template<typename T> class RefToBaseVector;
00059 template<typename C, typename T, typename F> class Ref;
00060 template<typename C> class RefProd;
00061 template<typename T> class RefToBaseProd;
00062 template<typename T> class View;
00063
00064 template <class T>
00065 class RefToBase
00066 {
00067 public:
00068 typedef T value_type;
00069
00070 RefToBase();
00071 RefToBase(RefToBase const& other);
00072 template <typename C1, typename T1, typename F1>
00073 explicit RefToBase(Ref<C1, T1, F1> const& r);
00074 template <typename C>
00075 explicit RefToBase(RefProd<C> const& r);
00076 RefToBase(RefToBaseProd<T> const& r, size_t i);
00077 RefToBase(Handle<View<T> > const& handle, size_t i);
00078 template <typename T1>
00079 explicit RefToBase(RefToBase<T1> const & r );
00080 RefToBase(boost::shared_ptr<reftobase::RefHolderBase> p);
00081 ~RefToBase();
00082
00083 RefToBase const& operator= (RefToBase const& rhs);
00084
00085 value_type const& operator*() const;
00086 value_type const* operator->() const;
00087 value_type const* get() const;
00088
00089 ProductID id() const;
00090 size_t key() const;
00091
00092 template <class REF> REF castTo() const;
00093
00094 bool isNull() const;
00095 bool isNonnull() const;
00096 bool operator!() const;
00097
00098 bool operator==(RefToBase const& rhs) const;
00099 bool operator!=(RefToBase const& rhs) const;
00100
00101 void swap(RefToBase& other);
00102
00103 std::auto_ptr<reftobase::RefHolderBase> holder() const;
00104
00105 EDProductGetter const* productGetter() const;
00106 bool hasProductCache() const;
00107 void const * product() const;
00108
00111 bool isAvailable() const { return holder_->isAvailable(); }
00112 private:
00113 value_type const* getPtrImpl() const;
00114 reftobase::BaseHolder<value_type>* holder_;
00115 friend class RefToBaseVector<T>;
00116 friend class RefToBaseProd<T>;
00117 template<typename B> friend class RefToBase;
00118 };
00119
00120
00121
00122
00123
00124 template <class T>
00125 inline
00126 RefToBase<T>::RefToBase() :
00127 holder_(0)
00128 { }
00129
00130 template <class T>
00131 inline
00132 RefToBase<T>::RefToBase(RefToBase const& other) :
00133 holder_(other.holder_ ? other.holder_->clone() : 0)
00134 { }
00135
00136 template <class T>
00137 template <typename C1, typename T1, typename F1>
00138 inline
00139 RefToBase<T>::RefToBase(Ref<C1, T1, F1> const& iRef) :
00140 holder_(new reftobase::Holder<T,Ref<C1, T1, F1> >(iRef))
00141 { }
00142
00143 template <class T>
00144 template <typename C>
00145 inline
00146 RefToBase<T>::RefToBase(RefProd<C> const& iRef) :
00147 holder_(new reftobase::Holder<T,RefProd<C> >(iRef))
00148 { }
00149
00150 template <class T>
00151 template <typename T1>
00152 inline
00153 RefToBase<T>::RefToBase(RefToBase<T1> const& iRef) :
00154 holder_(new reftobase::IndirectHolder<T> (
00155 boost::shared_ptr< edm::reftobase::RefHolderBase>(iRef.holder().release())
00156 ) )
00157 {
00158
00159
00160
00161
00162
00163 BOOST_STATIC_ASSERT( ( boost::is_base_of<T, T1>::value ) );
00164 }
00165
00166 template <class T>
00167 inline
00168 RefToBase<T>::RefToBase(boost::shared_ptr<reftobase::RefHolderBase> p) :
00169 holder_(new reftobase::IndirectHolder<T>(p))
00170 { }
00171
00172 template <class T>
00173 inline
00174 RefToBase<T>::~RefToBase()
00175 {
00176 delete holder_;
00177 }
00178
00179 template <class T>
00180 inline
00181 RefToBase<T> const&
00182 RefToBase<T>:: operator= (RefToBase<T> const& iRHS)
00183 {
00184 RefToBase<T> temp( iRHS);
00185 temp.swap(*this);
00186 return *this;
00187 }
00188
00189 template <class T>
00190 inline
00191 T const&
00192 RefToBase<T>::operator*() const
00193 {
00194 return *getPtrImpl();
00195 }
00196
00197 template <class T>
00198 inline
00199 T const*
00200 RefToBase<T>::operator->() const
00201 {
00202 return getPtrImpl();
00203 }
00204
00205 template <class T>
00206 inline
00207 T const*
00208 RefToBase<T>::get() const
00209 {
00210 return getPtrImpl();
00211 }
00212
00213 template <class T>
00214 inline
00215 ProductID
00216 RefToBase<T>::id() const
00217 {
00218 return holder_ ? holder_->id() : ProductID();
00219 }
00220
00221 template <class T>
00222 inline
00223 size_t
00224 RefToBase<T>::key() const
00225 {
00226 if ( holder_ == 0 )
00227 throw edm::Exception(errors::InvalidReference)
00228 << "attempting get key from null RefToBase;\n"
00229 << "You should check for nullity before calling key().";
00230 return holder_->key();
00231 }
00232
00234 template <class T>
00235 template <class REF>
00236 REF
00237 RefToBase<T>::castTo() const
00238 {
00239 if (!holder_)
00240 {
00241 throw edm::Exception(errors::InvalidReference)
00242 << "attempting to cast a null RefToBase;\n"
00243 << "You should check for nullity before casting.";
00244 }
00245
00246 reftobase::RefHolder<REF> concrete_holder;
00247 std::string hidden_ref_type;
00248 if (!holder_->fillRefIfMyTypeMatches(concrete_holder,
00249 hidden_ref_type))
00250 {
00251 throw edm::Exception(errors::InvalidReference)
00252 << "cast to type: " << typeid(REF).name()
00253 << "\nfrom type: " << hidden_ref_type
00254 << " failed. Catch this exception in case you need to check"
00255 << " the concrete reference type.";
00256 }
00257 return concrete_holder.getRef();
00258 }
00259
00261 template <class T>
00262 inline
00263 bool
00264 RefToBase<T>::isNull() const
00265 {
00266 return !id().isValid();
00267 }
00268
00270 template <class T>
00271 inline
00272 bool
00273 RefToBase<T>::isNonnull() const
00274 {
00275 return !isNull();
00276 }
00277
00279 template <class T>
00280 inline
00281 bool
00282 RefToBase<T>::operator!() const
00283 {
00284 return isNull();
00285 }
00286
00287 template <class T>
00288 inline
00289 bool
00290 RefToBase<T>::operator==(RefToBase<T> const& rhs) const
00291 {
00292 return holder_
00293 ? holder_->isEqualTo(*rhs.holder_)
00294 : holder_ == rhs.holder_;
00295 }
00296
00297 template <class T>
00298 inline
00299 bool
00300 RefToBase<T>::operator!=(RefToBase<T> const& rhs) const
00301 {
00302 return !(*this == rhs);
00303 }
00304
00305 template <class T>
00306 inline
00307 void
00308 RefToBase<T>::swap(RefToBase<T> & other)
00309 {
00310 std::swap(holder_, other.holder_);
00311 }
00312
00313 template <class T>
00314 inline
00315 EDProductGetter const* RefToBase<T>::productGetter() const {
00316 return holder_->productGetter();
00317 }
00318
00319 template <class T>
00320 inline
00321 bool RefToBase<T>::hasProductCache() const {
00322 return holder_->hasProductCache();
00323 }
00324
00325 template <class T>
00326 inline
00327 void const * RefToBase<T>::product() const {
00328 return holder_->product();
00329 }
00330
00331 template <class T>
00332 inline
00333 T const*
00334 RefToBase<T>::getPtrImpl() const
00335 {
00336 return holder_ ? holder_->getPtr() : 0;
00337 }
00338
00339 template <class T>
00340 std::auto_ptr<reftobase::RefHolderBase> RefToBase<T>::holder() const {
00341 return holder_->holder();
00342 }
00343
00344
00345 template <class T>
00346 inline
00347 void
00348 swap(RefToBase<T>& a, RefToBase<T>& b)
00349 {
00350 a.swap(b);
00351 }
00352 }
00353
00354 #include "DataFormats/Common/interface/RefToBaseProd.h"
00355 #include "DataFormats/Common/interface/Handle.h"
00356 #include "DataFormats/Common/interface/View.h"
00357
00358 namespace edm {
00359 template <class T>
00360 inline
00361 RefToBase<T>::RefToBase(RefToBaseProd<T> const& r, size_t i) :
00362 holder_( r.operator->()->refAt( i ).holder_->clone() ) {
00363 }
00364
00365 template<typename T>
00366 inline
00367 RefToBase<T>::RefToBase(Handle<View<T> > const& handle, size_t i) :
00368 holder_( handle.operator->()->refAt( i ).holder_->clone() ) {
00369 }
00370
00371 }
00372
00373 #endif