CMS 3D CMS Logo

RefToBase.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefToBase_h
00002 #define DataFormats_Common_RefToBase_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Common
00006 // Class  :     RefToBase
00007 // 
00028 //
00029 // Original Author:  Chris Jones
00030 //         Created:  Mon Apr  3 16:37:59 EDT 2006
00031 // $Id: RefToBase.h,v 1.32 2008/05/15 22:59:06 chrjones Exp $
00032 //
00033 
00034 // system include files
00035 
00036 // user include files
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   // Class template RefToBase<T>
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   // Implementation of RefToBase<T>
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     // OUT: holder_( new reftobase::Holder<T,RefToBase<T1> >(iRef ) )  { 
00159     // Forcing the conversion through IndirectHolder,
00160     //   as Holder<T,RefToBase<T1>> would need dictionaries we will never have.
00161     // In this way we only need the IndirectHolder<T> and the RefHolder of the real type of the item
00162     // This might cause a small performance penalty.
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   // Free swap function
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

Generated on Tue Jun 9 17:29:57 2009 for CMSSW by  doxygen 1.5.4