00001 #ifndef AUTOPTR_H 00002 #define AUTOPTR_H 00003 #include <assert.h> 00004 00005 namespace GMapping{ 00006 00007 template <class X> 00008 class autoptr{ 00009 protected: 00010 00011 public: 00012 struct reference{ 00013 X* data; 00014 unsigned int shares; 00015 }; 00016 inline autoptr(X* p=(X*)(0)); 00017 inline autoptr(const autoptr<X>& ap); 00018 inline autoptr& operator=(const autoptr<X>& ap); 00019 inline ~autoptr(); 00020 inline operator int() const; 00021 inline X& operator*(); 00022 inline const X& operator*() const; 00023 //p 00024 reference * m_reference; 00025 protected: 00026 }; 00027 00028 template <class X> 00029 autoptr<X>::autoptr(X* p){ 00030 m_reference=0; 00031 if (p){ 00032 m_reference=new reference; 00033 m_reference->data=p; 00034 m_reference->shares=1; 00035 } 00036 } 00037 00038 template <class X> 00039 autoptr<X>::autoptr(const autoptr<X>& ap){ 00040 m_reference=0; 00041 reference* ref=ap.m_reference; 00042 if (ap.m_reference){ 00043 m_reference=ref; 00044 m_reference->shares++; 00045 } 00046 } 00047 00048 template <class X> 00049 autoptr<X>& autoptr<X>::operator=(const autoptr<X>& ap){ 00050 reference* ref=ap.m_reference; 00051 if (m_reference==ref){ 00052 return *this; 00053 } 00054 if (m_reference && !(--m_reference->shares)){ 00055 delete m_reference->data; 00056 delete m_reference; 00057 m_reference=0; 00058 } 00059 if (ref){ 00060 m_reference=ref; 00061 m_reference->shares++; 00062 } 00063 //20050802 nasty changes begin 00064 else 00065 m_reference=0; 00066 //20050802 nasty changes end 00067 return *this; 00068 } 00069 00070 template <class X> 00071 autoptr<X>::~autoptr(){ 00072 if (m_reference && !(--m_reference->shares)){ 00073 delete m_reference->data; 00074 delete m_reference; 00075 m_reference=0; 00076 } 00077 } 00078 00079 template <class X> 00080 autoptr<X>::operator int() const{ 00081 return m_reference && m_reference->shares && m_reference->data; 00082 } 00083 00084 template <class X> 00085 X& autoptr<X>::operator*(){ 00086 assert(m_reference && m_reference->shares && m_reference->data); 00087 return *(m_reference->data); 00088 } 00089 00090 template <class X> 00091 const X& autoptr<X>::operator*() const{ 00092 assert(m_reference && m_reference->shares && m_reference->data); 00093 return *(m_reference->data); 00094 } 00095 00096 }; 00097 #endif