1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| template<class T>
class detached_auto_counter
{
struct counter_ptr
{
long s_cnt;
T *s_ptr;
counter_ptr(T *ptr=NULL)
:s_cnt(0l),s_ptr(ptr) {}
bool operator<(const counter_ptr & r) const
{ return unsigned(s_ptr)<unsigned(r.s_ptr); }
};
std::set<counter_ptr> f_counterset;
public:
detached_auto_counter()
{ Keep(NULL); }
~detached_auto_counter()
{ Release(NULL); }
long Keep(T *ptr)
{
counter_ptr cp(ptr);
std::pair<std::set<counter_ptr>::iterator,bool> p=f_counterset.insert(cp);
return ++p.first->s_cnt;
}
long Release(T *ptr)
{
counter_ptr cp(ptr);
std::set<counter_ptr>::iterator it=f_counterset.find(cp);
long r=--it->s_cnt;
if (r==0)
f_counterset.erase(it);
return r;
}
};
extern detached_auto_counter<void> g_detached_auto_counter;
template<class T>
class dsmart_ptr
{
T *f_ptr;
public:
explicit dsmart_ptr(T *ptr=NULL)
:f_ptr(ptr)
{
std::auto_ptr<T> ap(ptr);
g_detached_auto_counter.Keep(ptr);
ap.release();
}
dsmart_ptr(const dsmart_ptr<T> & r)
:f_ptr(r.f_ptr)
{
g_detached_auto_counter.Keep(f_ptr);
}
dsmart_ptr<T> & operator=(const dsmart_ptr<T> & r)
{
T *ptr=r.f_ptr;
g_detached_auto_counter.Keep(ptr);
if (g_detached_auto_counter.Release(f_ptr)==0)
delete f_ptr;
f_ptr=ptr;
return *this;
}
~dsmart_ptr()
{
if (g_detached_auto_counter.Release(f_ptr)==0)
delete f_ptr;
}
operator bool() const
{ return f_ptr!=0; }
T & operator*() const
{ return *f_ptr; }
T *operator->() const
{ return f_ptr; }
T *get() const
{ return f_ptr; }
}; |