00001 #ifndef UTILITIES_GENERAL_OWN_PTR_H 00002 #define UTILITIES_GENERAL_OWN_PTR_H 00003 // 00004 // a pointer which "owns" the pointed object 00005 // similar to std auto_ptr but does allow standard copy constructor 00006 // that passes ownership when copied 00007 // lost ownership = zero pointer (safer...) 00008 // 00009 00010 // 00011 // Version 1.0 V.I. 6/4/99 00012 // Version 2.0 V.I. 23/4/2001 00013 // Version 3.0 V.I. 29/1/2004 00014 // policies introduced... 00015 // 00016 00017 namespace OwnerPolicy { 00018 struct Transfer{ 00019 template <class X> static X * copy(X * &p) { X* it=p; p=0; return it;} 00020 template <class X> static void remove(X * p) { delete p;} 00021 }; 00022 struct Copy{ 00023 template <class X> static X * copy(X *p) { return (p) ? new X(*p) : 0;} 00024 template <class X> static void remove(X * p) { delete p;} 00025 }; 00026 struct Clone{ 00027 template <class X> static X * copy(X *p) { return (p) ? (*p).clone() : 0;} 00028 template <class X> static void remove(X * p) { delete p;} 00029 }; 00030 struct Replica{ 00031 template <class X> static X * copy(X *p) { return (p) ? (*p).replica() : 0;} 00032 template <class X> static void remove(X * p) { delete p;} 00033 }; 00034 } 00035 00036 00039 template <class X, typename P=OwnerPolicy::Transfer> class own_ptr { 00040 private: 00041 X* ptr; 00042 public: 00043 typedef X element_type; 00045 explicit own_ptr(X* p = 0) : ptr(p) {} 00046 00048 own_ptr(const own_ptr& a) : ptr(a.release()) {} 00049 00050 #ifndef CMS_NO_TEMPLATE_MEMBERS 00051 00052 template <class T, typename Q> own_ptr(const own_ptr<T,Q>& a) 00053 : ptr(a.release()) {} 00054 #endif 00055 00056 own_ptr& operator=(const own_ptr& a) { 00057 if (a.get() != ptr) { 00058 P::remove(ptr); 00059 ptr = a.release(); 00060 } 00061 return *this; 00062 } 00063 00064 #ifndef CMS_NO_TEMPLATE_MEMBERS 00065 00066 template <class T, typename Q> own_ptr& operator=(const own_ptr<T,Q>& a) { 00067 if (a.get() != ptr) { 00068 P::remove(ptr); 00069 ptr = a.release(); 00070 } 00071 return *this; 00072 } 00073 #endif 00074 00075 ~own_ptr() { 00076 P::remove(ptr); 00077 } 00079 X& operator*() const { return *ptr; } 00081 X* operator->() const { return ptr; } 00083 X* get() const { return ptr; } 00085 X* release() const { 00086 return P::copy(const_cast<own_ptr<X,P>*>(this)->ptr); 00087 } 00088 00090 void reset(X* p = 0) { 00091 if (p != ptr) { 00092 P::remove(ptr); 00093 ptr = p; 00094 } 00095 } 00096 }; 00097 00098 #endif // UTILITIES_GENERAL_OWN_PTR_H