00001 #ifndef FWCoreUtilities_value_ptr_h 00002 #define FWCoreUtilities_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 00028 #include <algorithm> // for std::swap() 00029 00030 namespace edm 00031 { 00032 00033 // -------------------------------------------------------------------- 00034 // 00035 // Auxiliary traits class template providing default clone() 00036 // Users should specialize this template for types that have their 00037 // own self-copy operations; failure to do so may lead to slicing! 00038 // 00039 // -------------------------------------------------------------------- 00040 00041 00042 template <class T> 00043 struct value_ptr_traits 00044 { 00045 static T * clone( T const * p ) { return new T( *p ); } 00046 }; 00047 00048 // -------------------------------------------------------------------- 00049 // 00050 // Copyable smart pointer class template 00051 // 00052 // -------------------------------------------------------------------- 00053 00054 00055 template <class T> 00056 class value_ptr 00057 { 00058 00059 public: 00060 00061 // -------------------------------------------------- 00062 // Default constructor/destructor: 00063 // -------------------------------------------------- 00064 00065 explicit value_ptr(T* p = 0) : myP(p) { } 00066 ~value_ptr() { delete myP; } 00067 00068 // -------------------------------------------------- 00069 // Copy constructor/copy assignment: 00070 // -------------------------------------------------- 00071 00072 value_ptr( value_ptr const & orig ) : 00073 myP( createFrom(orig.myP)) 00074 { } 00075 00076 value_ptr & operator = ( value_ptr const & orig ) 00077 { 00078 value_ptr<T> temp(orig); 00079 swap(temp); 00080 return *this; 00081 } 00082 00083 // -------------------------------------------------- 00084 // Access mechanisms: 00085 // -------------------------------------------------- 00086 00087 T& operator*() const { return *myP; } 00088 T* operator->() const { return myP; } 00089 00090 // -------------------------------------------------- 00091 // Manipulation: 00092 // -------------------------------------------------- 00093 00094 void swap( value_ptr & orig ) { std::swap( myP, orig.myP ); } 00095 00096 // -------------------------------------------------- 00097 // Copy-like construct/assign from compatible value_ptr<>: 00098 // -------------------------------------------------- 00099 00100 template <class U> 00101 value_ptr( value_ptr<U> const & orig ) : 00102 myP(createFrom(orig.operator->())) 00103 { } 00104 00105 template <class U> 00106 value_ptr & operator = ( value_ptr<U> const & orig ) 00107 { 00108 value_ptr<T> temp( orig ); 00109 swap(temp); 00110 return *this; 00111 } 00112 00113 private: 00114 00115 // -------------------------------------------------- 00116 // Implementation aid: 00117 // -------------------------------------------------- 00118 00119 template <class U> 00120 T* 00121 createFrom( U const * p ) const 00122 { 00123 return p 00124 ? value_ptr_traits<U>::clone( p ) 00125 : 0; 00126 } 00127 00128 // -------------------------------------------------- 00129 // Member data: 00130 // -------------------------------------------------- 00131 00132 T * myP; 00133 00134 }; // value_ptr 00135 00136 00137 // -------------------------------------------------------------------- 00138 // 00139 // Free-standing swap() 00140 // 00141 // -------------------------------------------------------------------- 00142 00143 template <class T> 00144 inline 00145 void 00146 swap( value_ptr<T> & vp1, value_ptr<T> & vp2 ) { vp1.swap( vp2 ); } 00147 00148 } 00149 00150 00151 #endif // FWCoreUtilities_value_ptr_h