00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00015 #ifndef __DERS__SH_PTR_HPP__
00016 #define __DERS__SH_PTR_HPP__
00017
00018 #include <ders/config.hpp>
00019 #include <ders/destroy.hpp>
00020
00021 namespace ders {
00022
00023 namespace detail {
00024
00025 template<class T>
00026 struct sh_ptr_core {
00027 mem_pool& mp;
00028 T* ptr;
00029 int refs;
00030
00031 sh_ptr_core(mem_pool& m, T* p) : mp(m), ptr(p), refs(1) {}
00032 ~sh_ptr_core() { ders::destroy(ptr, mp); }
00033 };
00034
00035 }
00036
00040 template<class T>
00041 class sh_ptr {
00042 typedef detail::sh_ptr_core<T> core;
00043 core* cr;
00044
00045 public:
00046 sh_ptr(mem_pool& mp, T* ptr);
00047
00048 sh_ptr(const sh_ptr& shp)
00049 {
00050 cr=shp.cr;
00051 cr->refs++;
00052 }
00053
00054 ~sh_ptr();
00055
00056 sh_ptr& operator=(const sh_ptr& shp);
00057
00058 mem_pool& pool() const { return cr->mp; }
00059
00060 void swap(sh_ptr& shp)
00061 {
00062 core* tmp=cr;
00063 cr=shp.cr;
00064 shp.cr=tmp;
00065 }
00066
00067 T& operator*() { return *cr->ptr; }
00068 const T& operator*() const { return *cr->ptr; }
00069
00070 T* operator->() { return cr->ptr; }
00071 const T* operator->() const { return cr->ptr; }
00072
00073 T* get() { return cr->ptr; }
00074 const T* get() const { return cr->ptr; }
00075
00076 void set(T* ptr) { cr->ptr=ptr; }
00077
00078 int refs() const { return cr->refs; }
00079 };
00080
00081 template<class T>
00082 sh_ptr<T>::sh_ptr(mem_pool& mp, T* ptr)
00083 {
00084 try { cr=new(mp.allocate(sizeof(core))) core(mp, ptr); }
00085 catch (...) {
00086 destroy(ptr, mp);
00087 throw;
00088 }
00089 }
00090
00091 template<class T>
00092 sh_ptr<T>::~sh_ptr()
00093 {
00094 if (--cr->refs==0) destroy(cr, cr->mp);
00095 }
00096
00097 template<class T>
00098 sh_ptr<T>& sh_ptr<T>::operator=(const sh_ptr& shp)
00099 {
00100 shp.cr->refs++;
00101 if (--cr->refs==0) destroy(cr, cr->mp);
00102 cr=shp.cr;
00103
00104 return *this;
00105 }
00106
00107 }
00108
00109 #endif // __DERS__SH_PTR_HPP__
00110