00001 #ifndef DataFormats_Common_RefToBaseProd_h
00002 #define DataFormats_Common_RefToBaseProd_h
00003
00004
00005
00006
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
00031
00032
00033
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
00090 CMS_CLASS_VERSION(10)
00091 private:
00092
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
00101
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