CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/DataFormats/Common/interface/RefToBaseProd.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_RefToBaseProd_h
00002 #define DataFormats_Common_RefToBaseProd_h
00003 
00004 /* \class edm::RefToBaseProd<T>
00005  *
00006  * \author Luca Lista, INFN
00007  *
00008  */
00009 
00010 #include "DataFormats/Common/interface/EDProductfwd.h"
00011 #include "DataFormats/Common/interface/RefCore.h"
00012 #include "DataFormats/Provenance/interface/ProductID.h"
00013 #include "DataFormats/Common/interface/ConstPtrCache.h"
00014 
00015 namespace edm {
00016   template<typename T> class View;
00017   template<typename C> class Handle;
00018 
00019   template <typename T>
00020   class RefToBaseProd {
00021   public:
00022     typedef View<T> product_type;
00023 
00025     RefToBaseProd() : product_(), viewCache_(0) {}
00026 
00028     // The templating is artificial.
00029     // HandleC must have the following methods:
00030     //   id(),      returning a ProductID,
00031    //   product(), returning a C*.
00032     template <class HandleC>
00033     explicit RefToBaseProd(HandleC const& handle);
00034     explicit RefToBaseProd(Handle<View<T> > const& handle);
00036     template <typename C, typename F>
00037     explicit RefToBaseProd(Ref<C, T, F> const& ref);
00038     explicit RefToBaseProd(RefToBase<T> const& ref);
00039     explicit RefToBaseProd( const View<T> & );
00040     RefToBaseProd( const RefToBaseProd<T> & );
00041     template<typename C>
00042     RefToBaseProd( const RefProd<C> & );
00043 
00045     ~RefToBaseProd() { delete viewPtr();}
00046 
00048     product_type const&  operator*() const;
00049 
00051     product_type const* operator->() const;
00052 
00055     product_type const* get() const {
00056       return isNull() ? 0 : this->operator->();
00057     }
00058 
00061     product_type const* product() const {
00062       return isNull() ? 0 : this->operator->();
00063     }
00064 
00065     RefCore const& refCore() const {
00066       return product_;
00067     }
00068 
00070     bool isNull() const {return !isNonnull(); }
00071 
00073     bool isNonnull() const {return id().isValid(); }
00074 
00076     bool operator!() const {return isNull(); }
00077 
00079     ProductID id() const {return product_.id();}
00080 
00082     EDProductGetter const* productGetter() const {return product_.productGetter();}
00083 
00085     bool hasCache() const {return product_.productPtr() != 0;}
00086 
00087     RefToBaseProd<T> & operator=( const RefToBaseProd<T> & other );
00088 
00089     void swap(RefToBaseProd<T> &);
00090 
00091   private:
00092     View<T> const* viewPtr() const {
00093       return reinterpret_cast<const View<T>*>(viewCache_.ptr_);
00094     }
00095     RefCore product_;
00096     mutable ConstPtrCache viewCache_;
00097   };
00098 }
00099 
00100 #include "DataFormats/Common/interface/View.h"
00101 #include "DataFormats/Common/interface/Handle.h"
00102 #include "DataFormats/Common/interface/Ref.h"
00103 #include "DataFormats/Common/interface/RefCoreGet.h"
00104 #include "DataFormats/Common/interface/RefVectorHolder.h"
00105 #include "DataFormats/Common/interface/RefVector.h"
00106 #include "DataFormats/Common/interface/RefTraits.h"
00107 
00108 namespace edm {
00109 
00110   namespace refhelper {
00111     template<typename C,
00112              typename T = typename refhelper::ValueTrait<C>::value,
00113              typename F = typename refhelper::FindTrait<C, T>::value>
00114     struct RefToBaseProdTrait {
00115       typedef RefVector<C, T, F> ref_vector_type;
00116     };
00117 
00118     template<typename C, typename T, typename F, typename T1, typename F1>
00119     struct RefToBaseProdTrait<RefVector<C, T, F>, T1, F1> {
00120       typedef RefVector<C, T, F> ref_vector_type;
00121     };
00122   }
00123 
00124   template <typename T>
00125   inline
00126   RefToBaseProd<T>::RefToBaseProd(Handle<View<T> > const& handle) :
00127     product_(handle->id(), 0, handle->productGetter(), false ),
00128     viewCache_( new View<T>( * handle ) ) {
00129     assert( handle->productGetter() == 0 );
00130   }
00131 
00132   template <typename T>
00133   inline
00134   RefToBaseProd<T>::RefToBaseProd( const View<T> & view ) :
00135     product_( view.id(), 0, view.productGetter(), false ),
00136     viewCache_( new View<T>( view ) ) {
00137   }
00138 
00139   template <typename T>
00140   inline
00141   RefToBaseProd<T>::RefToBaseProd( const RefToBaseProd<T> & ref ) :
00142     product_( ref.product_ ),
00143     viewCache_( ref.viewPtr() ? (new View<T>( * ref ) ) : 0 ) {
00144   }
00145 
00146   template <typename T>
00147   inline
00148   RefToBaseProd<T> & RefToBaseProd<T>::operator=( const RefToBaseProd<T> & other ) {
00149     RefToBaseProd<T> temp(other);
00150     this->swap(temp);
00151     return *this;
00152   }
00153 
00155   template <typename T>
00156   inline
00157   View<T> const& RefToBaseProd<T>::operator*() const {
00158     return * operator->();
00159   }
00160 
00162   template <typename T>
00163   inline
00164   View<T> const* RefToBaseProd<T>::operator->() const {
00165     if ( viewCache_.ptr_ == 0 ) {
00166       if ( product_.isNull() ) {
00167         Exception::throwThis(errors::InvalidReference,
00168           "attempting get view from a null RefToBaseProd.\n");
00169       }
00170       ProductID id = product_.id();
00171       std::vector<void const*> pointers;
00172       helper_vector_ptr helpers;
00173       product_.productGetter()->getIt(id)->fillView(id, pointers, helpers);
00174       viewCache_.ptr_ =( new View<T>( pointers, helpers ) );
00175     }
00176     return viewPtr();
00177   }
00178 
00179   template<typename T>
00180   inline
00181   void RefToBaseProd<T>::swap(RefToBaseProd<T> & other) {
00182     std::swap( product_, other.product_ );
00183     std::swap( viewCache_.ptr_, other.viewCache_.ptr_);
00184   }
00185 
00186   template <typename T>
00187   inline
00188   bool
00189   operator== (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00190     return lhs.refCore() == rhs.refCore();
00191   }
00192 
00193   template <typename T>
00194   inline
00195   bool
00196   operator!= (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00197     return !(lhs == rhs);
00198   }
00199 
00200   template <typename T>
00201   inline
00202   bool
00203   operator< (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00204     return (lhs.refCore() < rhs.refCore());
00205   }
00206 
00207   template<typename T>
00208   inline void swap( edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs ) {
00209     lhs.swap( rhs );
00210   }
00211 }
00212 
00213 #include "DataFormats/Common/interface/FillView.h"
00214 
00215 namespace edm {
00216   template <typename T>
00217   template <typename C>
00218   inline
00219   RefToBaseProd<T>::RefToBaseProd(const RefProd<C> & ref) :
00220     product_( ref.refCore() ) {
00221     std::vector<void const*> pointers;
00222     typedef typename refhelper::RefToBaseProdTrait<C>::ref_vector_type ref_vector;
00223     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00224     helper_vector_ptr helpers( new holder_type );
00225     detail::reallyFillView( * ref.product(), ref.id(), pointers, * helpers );
00226     viewCache_.ptr_=( new View<T>( pointers, helpers ) );
00227   }
00228 
00229   template <typename T>
00230   template <class HandleC>
00231   inline
00232   RefToBaseProd<T>::RefToBaseProd(HandleC const& handle) :
00233     product_(handle.id(), handle.product(), 0, false) {
00234     std::vector<void const*> pointers;
00235     typedef typename refhelper::RefToBaseProdTrait<typename HandleC::element_type>::ref_vector_type ref_vector;
00236     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00237     helper_vector_ptr helpers( new holder_type );
00238     detail::reallyFillView( * handle, handle.id(), pointers, * helpers );
00239     viewCache_.ptr_=( new View<T>( pointers, helpers ) );
00240   }
00241 
00243   template <typename T>
00244   template <typename C, typename F>
00245   inline
00246   RefToBaseProd<T>::RefToBaseProd(Ref<C, T, F> const& ref) :
00247       product_(ref.id(),
00248                ref.hasProductCache() ?  ref.product() : 0,
00249                ref.productGetter(),
00250                false) {
00251     std::vector<void const*> pointers;
00252     typedef typename refhelper::RefToBaseProdTrait<C>::ref_vector_type ref_vector;
00253     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00254     helper_vector_ptr helpers( new holder_type );
00255     detail::reallyFillView( * ref.product(), ref.id(), pointers, * helpers );
00256     viewCache_.ptr_=( new View<T>( pointers, helpers ) );
00257   }
00258 
00260   template <typename T>
00261   inline
00262   RefToBaseProd<T>::RefToBaseProd(RefToBase<T> const& ref) :
00263     product_(ref.id(),
00264              ref.hasProductCache() ?  ref.product() : 0,
00265              ref.productGetter(),
00266              false) {
00267     std::vector<void const*> pointers;
00268     helper_vector_ptr helpers( ref.holder_->makeVectorBaseHolder().release() );
00269     helpers->reallyFillView( ref.product(), ref.id(), pointers );
00270     viewCache_.ptr_=( new View<T>( pointers, helpers ) );
00271   }
00272 
00273 }
00274 
00275 #endif