00001 #ifndef SMART_POINTER_H 00002 #define SMART_POINTER_H 00003 00004 namespace buffy { 00005 00006 template<class ITEM> 00007 class SmartPointer 00008 { 00009 protected: 00010 ITEM* impl; 00011 00012 public: 00013 SmartPointer() throw () : impl(0) {} 00014 00015 SmartPointer(const SmartPointer& sp) throw () 00016 { 00017 if (sp.impl) 00018 sp.impl->ref(); 00019 impl = sp.impl; 00020 } 00021 00022 SmartPointer(ITEM* otherimpl) throw () 00023 { 00024 if (otherimpl) 00025 otherimpl->ref(); 00026 impl = otherimpl; 00027 } 00028 00029 ~SmartPointer() throw () 00030 { 00031 if (impl && impl->unref()) 00032 delete impl; 00033 } 00034 00035 SmartPointer& operator=(const SmartPointer& sp) throw () 00036 { 00037 if (sp.impl) 00038 sp.impl->ref(); // Do it early to correctly handle the case of x = x; 00039 if (impl && impl->unref()) 00040 delete impl; 00041 impl = sp.impl; 00042 return *this; 00043 } 00044 00045 operator bool() const throw () { return impl != 0; } 00046 }; 00047 00048 class SmartPointerItem 00049 { 00050 protected: 00051 int _ref; 00052 00053 public: 00054 SmartPointerItem() throw () : _ref(0) {} 00055 00057 void ref() throw () { ++_ref; } 00058 00061 bool unref() throw () { return --_ref == 0; } 00062 }; 00063 00064 } 00065 00066 // vim:set ts=3 sw=3: 00067 #endif