00001 #ifndef DataFormats_Common_OrphanHandle_h 00002 #define DataFormats_Common_OrphanHandle_h 00003 00004 /*---------------------------------------------------------------------- 00005 00006 OrphanHandle: Non-owning "smart pointer" for reference to EDProducts. 00007 00008 00009 This is a very preliminary version, and lacks safety features and 00010 elegance. 00011 00012 If the pointed-to EDProduct is destroyed, use of the OrphanHandle 00013 becomes undefined. There is no way to query the OrphanHandle to 00014 discover if this has happened. 00015 00016 OrphanHandles can have: 00017 -- Product pointer null and id == 0; 00018 -- Product pointer valid and id != 0; 00019 00020 To check validity, one can use the isValid() function. 00021 00022 ----------------------------------------------------------------------*/ 00023 00024 #include "DataFormats/Provenance/interface/ProductID.h" 00025 #include "FWCore/Utilities/interface/EDMException.h" 00026 #include <cassert> 00027 00028 namespace edm { 00029 class EDProduct; 00030 00031 template <typename T> 00032 class OrphanHandle { 00033 public: 00034 typedef T element_type; 00035 00036 // Default constructed handles are invalid. 00037 OrphanHandle(); 00038 00039 OrphanHandle(const OrphanHandle<T>& h); 00040 00041 OrphanHandle(T const* prod, ProductID const& id); 00042 00043 ~OrphanHandle(); 00044 00045 void swap(OrphanHandle<T>& other); 00046 00047 00048 OrphanHandle<T>& operator=(const OrphanHandle<T>& rhs); 00049 00050 bool isValid() const; 00051 00052 T const* product() const; 00053 T const* operator->() const; // alias for product() 00054 T const& operator*() const; 00055 00056 ProductID id() const; 00057 00058 void clear(); 00059 00060 private: 00061 T const* prod_; 00062 ProductID id_; 00063 }; 00064 00065 template <class T> 00066 OrphanHandle<T>::OrphanHandle() : 00067 prod_(0), 00068 id_(0) 00069 { } 00070 00071 template <class T> 00072 OrphanHandle<T>::OrphanHandle(const OrphanHandle<T>& h) : 00073 prod_(h.prod_), 00074 id_(h.id_) 00075 { } 00076 00077 template <class T> 00078 OrphanHandle<T>::OrphanHandle(T const* prod, ProductID const& theId) : 00079 prod_(prod), 00080 id_(theId) { 00081 assert(prod_); 00082 } 00083 00084 template <class T> 00085 OrphanHandle<T>::~OrphanHandle() { 00086 // Really nothing to do -- we do not own the things to which we 00087 // point. For help in debugging, we clear the data. 00088 clear(); 00089 } 00090 00091 template <class T> 00092 void 00093 OrphanHandle<T>::clear() 00094 { 00095 prod_ = 0; 00096 id_ = ProductID(); 00097 } 00098 00099 template <class T> 00100 void 00101 OrphanHandle<T>::swap(OrphanHandle<T>& other) { 00102 using std::swap; 00103 std::swap(prod_, other.prod_); 00104 swap(id_, other.id_); 00105 } 00106 00107 template <class T> 00108 OrphanHandle<T>& 00109 OrphanHandle<T>::operator=(const OrphanHandle<T>& rhs) { 00110 OrphanHandle<T> temp(rhs); 00111 this->swap(temp); 00112 return *this; 00113 } 00114 00115 template <class T> 00116 bool 00117 OrphanHandle<T>::isValid() const { 00118 return prod_ != 0 && id_ != ProductID(); 00119 } 00120 00121 template <class T> 00122 T const* 00123 OrphanHandle<T>::product() const { 00124 // Should we throw if the pointer is null? 00125 return prod_; 00126 } 00127 00128 template <class T> 00129 T const* 00130 OrphanHandle<T>::operator->() const { 00131 return product(); 00132 } 00133 00134 template <class T> 00135 T const& 00136 OrphanHandle<T>::operator*() const { 00137 return *product(); 00138 } 00139 00140 template <class T> 00141 ProductID 00142 OrphanHandle<T>::id() const { 00143 return id_; 00144 } 00145 00146 // Free swap function 00147 template <class T> 00148 inline 00149 void 00150 swap(OrphanHandle<T>& a, OrphanHandle<T>& b) 00151 { 00152 a.swap(b); 00153 } 00154 } 00155 00156 #endif