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