CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/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 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
00010 
00011 #include "DataFormats/Common/interface/WrapperHolder.h"
00012 #include "DataFormats/Common/interface/EDProductfwd.h"
00013 #include "DataFormats/Common/interface/RefCore.h"
00014 #include "DataFormats/Provenance/interface/ProductID.h"
00015 #include "DataFormats/Common/interface/ConstPtrCache.h"
00016 
00017 namespace edm {
00018   template<typename T> class View;
00019   template<typename C> class Handle;
00020 
00021   template<typename T>
00022   class RefToBaseProd {
00023   public:
00024     typedef View<T> product_type;
00025 
00027     RefToBaseProd() : product_(){}
00028 
00030     // The templating is artificial.
00031     // HandleC must have the following methods:
00032     //   id(),      returning a ProductID,
00033    //   product(), returning a C*.
00034     template<class HandleC>
00035     explicit RefToBaseProd(HandleC const& handle);
00036     explicit RefToBaseProd(Handle<View<T> > const& handle);
00038     template<typename C, typename F>
00039     explicit RefToBaseProd(Ref<C, T, F> const& ref);
00040     explicit RefToBaseProd(RefToBase<T> const& ref);
00041     explicit RefToBaseProd(const View<T>&);
00042     RefToBaseProd(const RefToBaseProd<T>&);
00043     template<typename C>
00044     RefToBaseProd(const RefProd<C>&);
00045 
00047     ~RefToBaseProd() { delete viewPtr();}
00048 
00050     product_type const&  operator*() const;
00051 
00053     product_type const* operator->() const;
00054 
00057     product_type const* get() const {
00058       return isNull() ? 0 : this->operator->();
00059     }
00060 
00063     product_type const* product() const {
00064       return isNull() ? 0 : this->operator->();
00065     }
00066 
00068     bool isNull() const {return !isNonnull(); }
00069 
00071     bool isNonnull() const {return id().isValid(); }
00072 
00074     bool operator!() const {return isNull(); }
00075 
00077     ProductID id() const {return product_.id();}
00078 
00080     EDProductGetter const* productGetter() const {return product_.productGetter();}
00081 
00083     bool hasCache() const {return product_.productPtr() != 0;}
00084 
00085     RefToBaseProd<T>& operator=(const RefToBaseProd<T>& other);
00086 
00087     void swap(RefToBaseProd<T>&);
00088 
00089     //Needed for ROOT storage
00090     CMS_CLASS_VERSION(10)
00091   private:
00092     //NOTE: Access to RefCore should be private since we modify the use of productPtr
00093     RefCore const& refCore() const {
00094       return product_;
00095     }
00096     
00097     View<T> const* viewPtr() const {
00098       return reinterpret_cast<const View<T>*>(product_.productPtr());
00099     }
00100     //needs to be mutable so we can modify the 'productPtr' it holds
00101     // so that 'productPtr' can hold our View
00102     mutable RefCore product_;
00103   };
00104 }
00105 
00106 #include "DataFormats/Common/interface/View.h"
00107 #include "DataFormats/Common/interface/Handle.h"
00108 #include "DataFormats/Common/interface/Ref.h"
00109 #include "DataFormats/Common/interface/RefCoreGet.h"
00110 #include "DataFormats/Common/interface/RefVectorHolder.h"
00111 #include "DataFormats/Common/interface/RefVector.h"
00112 #include "DataFormats/Common/interface/RefTraits.h"
00113 
00114 namespace edm {
00115 
00116   namespace refhelper {
00117     template<typename C,
00118              typename T = typename refhelper::ValueTrait<C>::value,
00119              typename F = typename refhelper::FindTrait<C, T>::value>
00120     struct RefToBaseProdTrait {
00121       typedef RefVector<C, T, F> ref_vector_type;
00122     };
00123 
00124     template<typename C, typename T, typename F, typename T1, typename F1>
00125     struct RefToBaseProdTrait<RefVector<C, T, F>, T1, F1> {
00126       typedef RefVector<C, T, F> ref_vector_type;
00127     };
00128   }
00129 
00130   template<typename T>
00131   inline
00132   RefToBaseProd<T>::RefToBaseProd(Handle<View<T> > const& handle) :
00133     product_(handle->id(), 0, handle->productGetter(), false){
00134     product_.setProductPtr(new View<T>(* handle));
00135     assert(handle->productGetter() == 0);
00136   }
00137 
00138   template<typename T>
00139   inline
00140   RefToBaseProd<T>::RefToBaseProd(const View<T>& view) :
00141     product_(view.id(), 0, view.productGetter(), false) {
00142       product_.setProductPtr(new View<T>(view));
00143   }
00144 
00145   template<typename T>
00146   inline
00147   RefToBaseProd<T>::RefToBaseProd(const RefToBaseProd<T>& ref) :
00148     product_(ref.product_) {
00149       if(product_.productPtr()) {
00150         product_.setProductPtr(ref.viewPtr() ? (new View<T>(* ref)) : 0);
00151       }
00152   }
00153 
00154   template<typename T>
00155   inline
00156   RefToBaseProd<T>& RefToBaseProd<T>::operator=(const RefToBaseProd<T>& other) {
00157     RefToBaseProd<T> temp(other);
00158     this->swap(temp);
00159     return *this;
00160   }
00161 
00163   template<typename T>
00164   inline
00165   View<T> const& RefToBaseProd<T>::operator*() const {
00166     return * operator->();
00167   }
00168 
00170   template<typename T>
00171   inline
00172   View<T> const* RefToBaseProd<T>::operator->() const {
00173     if(product_.productPtr() == 0) {
00174       if(product_.isNull()) {
00175         Exception::throwThis(errors::InvalidReference,
00176           "attempting get view from a null RefToBaseProd.\n");
00177       }
00178       ProductID tId = product_.id();
00179       std::vector<void const*> pointers;
00180       helper_vector_ptr helpers;
00181       WrapperHolder it = product_.productGetter()->getIt(tId);
00182       if(!it.isValid()) {
00183         Exception::throwThis(errors::InvalidReference,
00184                              "attempting to get view from an unavailable RefToBaseProd.");
00185       }
00186       it.fillView(tId, pointers, helpers);
00187       product_.setProductPtr((new View<T>(pointers, helpers)));
00188     }
00189     return viewPtr();
00190   }
00191 
00192   template<typename T>
00193   inline
00194   void RefToBaseProd<T>::swap(RefToBaseProd<T>& other) {
00195     std::swap(product_, other.product_);
00196   }
00197 
00198   template<typename T>
00199   inline
00200   bool
00201   operator== (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00202     return lhs.refCore() == rhs.refCore();
00203   }
00204 
00205   template<typename T>
00206   inline
00207   bool
00208   operator!= (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00209     return !(lhs == rhs);
00210   }
00211 
00212   template<typename T>
00213   inline
00214   bool
00215   operator< (RefToBaseProd<T> const& lhs, RefToBaseProd<T> const& rhs) {
00216     return (lhs.refCore() < rhs.refCore());
00217   }
00218 
00219   template<typename T>
00220   inline void swap(edm::RefToBaseProd<T> const& lhs, edm::RefToBaseProd<T> const& rhs) {
00221     lhs.swap(rhs);
00222   }
00223 }
00224 
00225 #include "DataFormats/Common/interface/FillView.h"
00226 
00227 namespace edm {
00228   template<typename T>
00229   template<typename C>
00230   inline
00231   RefToBaseProd<T>::RefToBaseProd(const RefProd<C>& ref) :
00232     product_(ref.refCore()) {
00233     std::vector<void const*> pointers;
00234     typedef typename refhelper::RefToBaseProdTrait<C>::ref_vector_type ref_vector;
00235     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00236     helper_vector_ptr helpers(new holder_type);
00237     detail::reallyFillView(* ref.product(), ref.id(), pointers, * helpers);
00238     product_.setProductPtr(new View<T>(pointers, helpers));
00239   }
00240 
00241   template<typename T>
00242   template<class HandleC>
00243   inline
00244   RefToBaseProd<T>::RefToBaseProd(HandleC const& handle) :
00245     product_(handle.id(), handle.product(), 0, false) {
00246     std::vector<void const*> pointers;
00247     typedef typename refhelper::RefToBaseProdTrait<typename HandleC::element_type>::ref_vector_type ref_vector;
00248     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00249     helper_vector_ptr helpers(new holder_type);
00250     detail::reallyFillView(* handle, handle.id(), pointers, * helpers);
00251     product_.setProductPtr(new View<T>(pointers, helpers));
00252   }
00253 
00255   template<typename T>
00256   template<typename C, typename F>
00257   inline
00258   RefToBaseProd<T>::RefToBaseProd(Ref<C, T, F> const& ref) :
00259       product_(ref.id(),
00260                ref.hasProductCache() ? ref.product() : 0,
00261                ref.productGetter(),
00262                false) {
00263     std::vector<void const*> pointers;
00264     typedef typename refhelper::RefToBaseProdTrait<C>::ref_vector_type ref_vector;
00265     typedef reftobase::RefVectorHolder<ref_vector> holder_type;
00266     helper_vector_ptr helpers(new holder_type);
00267     detail::reallyFillView(* ref.product(), ref.id(), pointers, * helpers);
00268     product_.setProductPtr(new View<T>(pointers, helpers));
00269   }
00270 
00272   template<typename T>
00273   inline
00274   RefToBaseProd<T>::RefToBaseProd(RefToBase<T> const& ref) :
00275     product_(ref.id(),
00276              ref.hasProductCache() ? ref.product() : 0,
00277              ref.productGetter(),
00278              false) {
00279     std::vector<void const*> pointers;
00280     helper_vector_ptr helpers(ref.holder_->makeVectorBaseHolder().release());
00281     helpers->reallyFillView(ref.product(), ref.id(), pointers);
00282     product_.setProductPtr(new View<T>(pointers, helpers));
00283   }
00284 
00285 }
00286 
00287 #endif