00001 #ifndef DataFormats_Common_Handle_h
00002 #define DataFormats_Common_Handle_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <typeinfo>
00029
00030 #include "DataFormats/Provenance/interface/ProductID.h"
00031 #include "DataFormats/Common/interface/BasicHandle.h"
00032 #include "FWCore/Utilities/interface/EDMException.h"
00033
00034 namespace edm
00035 {
00036 class EDProduct;
00037 template <typename T> class Wrapper;
00038
00039 template <typename T>
00040 class Handle
00041 {
00042 public:
00043 typedef T element_type;
00044
00045
00046 Handle();
00047
00048 Handle(const Handle<T>& h);
00049
00050 Handle(T const* prod, Provenance const* prov);
00051
00052 Handle(const boost::shared_ptr<cms::Exception>&);
00053
00054 ~Handle();
00055
00056 void swap(Handle<T>& other);
00057
00058
00059 Handle<T>& operator=(const Handle<T>& rhs);
00060
00061 bool isValid() const;
00062
00064 bool failedToGet() const;
00065
00066 T const* product() const;
00067 T const* operator->() const;
00068 T const& operator*() const;
00069
00070 Provenance const* provenance() const;
00071
00072 ProductID id() const;
00073
00074 void clear();
00075
00076 private:
00077 T const* prod_;
00078 Provenance const* prov_;
00079 ProductID id_;
00080 boost::shared_ptr<cms::Exception> whyFailed_;
00081 };
00082
00083 template <class T>
00084 Handle<T>::Handle() :
00085 prod_(0),
00086 prov_(0),
00087 id_(0)
00088 { }
00089
00090 template <class T>
00091 Handle<T>::Handle(const Handle<T>& h) :
00092 prod_(h.prod_),
00093 prov_(h.prov_),
00094 id_(h.id_),
00095 whyFailed_(h.whyFailed_)
00096 { }
00097
00098 template <class T>
00099 Handle<T>::Handle(T const* prod, Provenance const* prov) :
00100 prod_(prod),
00101 prov_(prov),
00102 id_(prov->productID())
00103 {
00104 assert(prod_);
00105 assert(prov_);
00106 }
00107
00108 template <class T>
00109 Handle<T>::Handle(const boost::shared_ptr<cms::Exception>& iWhyFailed):
00110 prod_(0),
00111 prov_(0),
00112 id_(0),
00113 whyFailed_(iWhyFailed)
00114 { }
00115
00116 template <class T>
00117 Handle<T>::~Handle()
00118 {
00119
00120
00121 clear();
00122 }
00123
00124 template <class T>
00125 void
00126 Handle<T>::swap(Handle<T>& other)
00127 {
00128 using std::swap;
00129 std::swap(prod_, other.prod_);
00130 std::swap(prov_, other.prov_);
00131 swap(id_, other.id_);
00132 swap(whyFailed_,other.whyFailed_);
00133 }
00134
00135 template <class T>
00136 Handle<T>&
00137 Handle<T>::operator=(const Handle<T>& rhs)
00138 {
00139 Handle<T> temp(rhs);
00140 this->swap(temp);
00141 return *this;
00142 }
00143
00144 template <class T>
00145 bool
00146 Handle<T>::isValid() const
00147 {
00148 return prod_ != 0 && prov_ != 0;
00149 }
00150
00151 template <class T>
00152 bool
00153 Handle<T>::failedToGet() const
00154 {
00155 return 0 != whyFailed_.get();
00156 }
00157
00158 template <class T>
00159 T const*
00160 Handle<T>::product() const
00161 {
00162 if(failedToGet()) {
00163 throw *whyFailed_;
00164 }
00165
00166 return prod_;
00167 }
00168
00169 template <class T>
00170 T const*
00171 Handle<T>::operator->() const
00172 {
00173 return product();
00174 }
00175
00176 template <class T>
00177 T const&
00178 Handle<T>::operator*() const
00179 {
00180 return *product();
00181 }
00182
00183 template <class T>
00184 Provenance const*
00185 Handle<T>::provenance() const
00186 {
00187
00188 return prov_;
00189 }
00190
00191 template <class T>
00192 ProductID
00193 Handle<T>::id() const
00194 {
00195 return id_;
00196 }
00197
00198 template <class T>
00199 void
00200 Handle<T>::clear()
00201 {
00202 prod_ = 0;
00203 prov_ = 0;
00204 id_ = ProductID();
00205 whyFailed_.reset();
00206 }
00207
00208
00209
00210
00211
00212 template <class T>
00213 inline
00214 void
00215 swap(Handle<T>& a, Handle<T>& b)
00216 {
00217 a.swap(b);
00218 }
00219
00220
00221 template <class T>
00222 void convert_handle(BasicHandle const& orig,
00223 Handle<T>& result)
00224 {
00225 if(orig.failedToGet()) {
00226 Handle<T> h(orig.whyFailed());
00227 h.swap(result);
00228 return;
00229 }
00230 EDProduct const* originalWrap = orig.wrapper();
00231 if (originalWrap == 0)
00232 throw edm::Exception(edm::errors::InvalidReference,"NullPointer")
00233 << "edm::BasicHandle has null pointer to Wrapper";
00234 Wrapper<T> const* wrap = dynamic_cast<Wrapper<T> const*>(originalWrap);
00235 if (wrap == 0)
00236 throw edm::Exception(edm::errors::LogicError,"ConvertType")
00237 << "edm::Wrapper converting from EDProduct to "
00238 << typeid(*originalWrap).name();
00239
00240 Handle<T> h(wrap->product(), orig.provenance());
00241 h.swap(result);
00242 }
00243
00244 }
00245
00246 #endif