Go to the documentation of this file.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
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
00064 else
00065 m_reference=0;
00066
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