00001 #ifndef DataFormats_Common_RefToBaseProd_h
00002 #define DataFormats_Common_RefToBaseProd_h
00003
00004
00005
00006
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
00029
00030
00031
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