![]() |
![]() |
00001 #ifndef FWCore_Utilities_value_ptr_h 00002 #define FWCore_Utilities_value_ptr_h 00003 00004 // ---------------------------------------------------------------------- 00005 // 00006 // value_ptr.h - Smart pointer permitting copying of pointed-to object. 00007 // 00008 // Purpose: value_ptr provides a smart pointer template that provides 00009 // sole ownership of the pointed-to object. When a value_ptr object is 00010 // copied, the new value_ptr object is given a copy of the object pointed 00011 // to by the original value_ptr object. 00012 // 00013 // The value_ptr_traits template is provided to allow specialization 00014 // of the copying behavior. See the notes below. 00015 // 00016 // Use value_ptr only when deep-copying of the pointed-to object is 00017 // desireable. Use boost::shared_ptr when sharing of the pointed-to 00018 // object is desireable. Use boost::scoped_ptr when no copying is 00019 // desireable. 00020 // 00021 // The design of value_ptr is taken from Herb Sutter's More 00022 // Exceptional C++, with modifications by Marc Paterno and further 00023 // modifications by Walter Brown. This version is based on the 00024 // ValuePtr found in the Fermilab ZOOM library. 00025 // 00026 // 00027 // Supports the following syntax 00028 // value_ptr<T> ptr(...); 00029 // if (ptr) { ... 00030 // Where the conditional will evaluate as true if and only if the 00031 // pointer the value_ptr contains is not null. 00032 // 00033 // ---------------------------------------------------------------------- 00034 00035 #include <algorithm> // for std::swap() 00036 #include <memory> 00037 00038 namespace edm { 00039 00040 // -------------------------------------------------------------------- 00041 // 00042 // Auxiliary traits class template providing default clone() 00043 // Users should specialize this template for types that have their 00044 // own self-copy operations; failure to do so may lead to slicing! 00045 // 00046 // -------------------------------------------------------------------- 00047 00048 00049 template <typename T> 00050 struct value_ptr_traits { 00051 static T * clone(T const* p) { return new T(*p); } 00052 }; 00053 00054 // -------------------------------------------------------------------- 00055 // 00056 // Copyable smart pointer class template 00057 // 00058 // -------------------------------------------------------------------- 00059 00060 00061 template <typename T> 00062 class value_ptr { 00063 00064 public: 00065 00066 // -------------------------------------------------- 00067 // Default constructor/destructor: 00068 // -------------------------------------------------- 00069 00070 explicit value_ptr(T* p = 0) : myP(p) { } 00071 ~value_ptr() { delete myP; } 00072 00073 // -------------------------------------------------- 00074 // Copy constructor/copy assignment: 00075 // -------------------------------------------------- 00076 00077 value_ptr(value_ptr const& orig) : 00078 myP(createFrom(orig.myP)) { 00079 } 00080 00081 value_ptr& operator= (value_ptr const& orig) { 00082 value_ptr<T> temp(orig); 00083 swap(temp); 00084 return *this; 00085 } 00086 00087 // -------------------------------------------------- 00088 // Access mechanisms: 00089 // -------------------------------------------------- 00090 00091 T& operator*() const { return *myP; } 00092 T* operator->() const { return myP; } 00093 00094 // -------------------------------------------------- 00095 // Manipulation: 00096 // -------------------------------------------------- 00097 00098 void swap(value_ptr& orig) { std::swap(myP, orig.myP); } 00099 00100 // -------------------------------------------------- 00101 // Copy-like construct/assign from compatible value_ptr<>: 00102 // -------------------------------------------------- 00103 00104 template <typename U> 00105 value_ptr(value_ptr<U> const& orig) : 00106 myP(createFrom(orig.operator->())) { 00107 } 00108 00109 template <typename U> 00110 value_ptr& operator=(value_ptr<U> const& orig) { 00111 value_ptr<T> temp(orig); 00112 swap(temp); 00113 return *this; 00114 } 00115 00116 // -------------------------------------------------- 00117 // Copy-like construct/assign from auto_ptr<>: 00118 // -------------------------------------------------- 00119 00120 value_ptr(std::auto_ptr<T> orig) : 00121 myP(orig.release()) { 00122 } 00123 00124 value_ptr& operator=(std::auto_ptr<T> orig) { 00125 value_ptr<T> temp(orig); 00126 swap(temp); 00127 return *this; 00128 } 00129 00130 // The following typedef, function, and operator definition 00131 // support the following syntax: 00132 // value_ptr<T> ptr(..); 00133 // if (ptr) { ... 00134 // Where the conditional will evaluate as true if and only if the 00135 // pointer value_ptr contains is not null. 00136 private: 00137 typedef void (value_ptr::*bool_type)() const; 00138 void this_type_does_not_support_comparisons() const {} 00139 00140 public: 00141 operator bool_type() const { 00142 return myP != 0 ? 00143 &value_ptr<T>::this_type_does_not_support_comparisons : 0; 00144 } 00145 00146 private: 00147 00148 // -------------------------------------------------- 00149 // Implementation aid: 00150 // -------------------------------------------------- 00151 00152 template <typename U> 00153 T* 00154 createFrom(U const* p) const { 00155 return p 00156 ? value_ptr_traits<U>::clone(p) 00157 : 0; 00158 } 00159 00160 // -------------------------------------------------- 00161 // Member data: 00162 // -------------------------------------------------- 00163 00164 T * myP; 00165 00166 }; // value_ptr 00167 00168 00169 // -------------------------------------------------------------------- 00170 // 00171 // Free-standing swap() 00172 // 00173 // -------------------------------------------------------------------- 00174 00175 template <typename T> 00176 inline 00177 void 00178 swap(value_ptr<T>& vp1, value_ptr<T>& vp2) { vp1.swap(vp2); } 00179 00180 // Do not allow nonsensical comparisons that the bool_type 00181 // conversion operator definition above would otherwise allow. 00182 // The function call inside the next 4 operator definitions is 00183 // private, so compilation will fail if there is an attempt to 00184 // instantiate these 4 operators. 00185 template <typename T, typename U> 00186 bool operator==(value_ptr<T> const& lhs, U const& rhs) { 00187 lhs.this_type_does_not_support_comparisons(); 00188 return false; 00189 } 00190 00191 template <typename T, typename U> 00192 bool operator!=(value_ptr<T> const& lhs, U const& rhs) { 00193 lhs.this_type_does_not_support_comparisons(); 00194 return false; 00195 } 00196 00197 template <typename T, typename U> 00198 bool operator==(U const& lhs, value_ptr<T> const& rhs) { 00199 rhs.this_type_does_not_support_comparisons(); 00200 return false; 00201 } 00202 00203 template <typename T, typename U> 00204 bool operator!=(U const& lhs, value_ptr<T> const& rhs) { 00205 rhs.this_type_does_not_support_comparisons(); 00206 return false; 00207 } 00208 } 00209 00210 00211 #endif // FWCoreUtilities_value_ptr_h