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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| template<class T>
class b2smart_ptr
{
class intra_counter
{
long f_cnt;
long Keep() { return ++f_cnt; }
long Release() { return --f_cnt; }
public:
static T *Init()
{
char *cptr=new char[sizeof(intra_counter)+sizeof(T)];
intra_counter *pac=reinterpret_cast<intra_counter *>(cptr);
pac->f_cnt=1;
return reinterpret_cast<T *>(pac+1);
}
static T *Copy(T *p)
{
if (p)
(reinterpret_cast<intra_counter *>(p)-1)->Keep();
return p;
}
static void Done(T *p)
{
if (p)
{
intra_counter *pac=(reinterpret_cast<intra_counter *>(p)-1);
if (pac->Release()==0)
{
p->~T();
delete[] reinterpret_cast<char *>(pac);
}
}
}
static void Copy(T **pp,T *p)
{
if (p)
(reinterpret_cast<intra_counter *>(p)-1)->Keep();
Done(*pp);
*pp=p;
}
};
T *f_ptr;
explicit b2smart_ptr(T *ptr)
:f_ptr(ptr) {}
public:
b2smart_ptr()
:f_ptr(0) {}
template<class Y>
b2smart_ptr(const b2smart_ptr<Y> & r)
{ f_ptr=intra_counter::Copy(r.get()); }
b2smart_ptr(const b2smart_ptr<T> & r)
{ f_ptr=intra_counter::Copy(r.f_ptr); }
template<class Y>
b2smart_ptr<T> & operator=(const b2smart_ptr<Y> & r)
{ intra_counter::Copy(&f_ptr,r.get()); return *this; }
b2smart_ptr<T> & operator=(const b2smart_ptr<T> & r)
{ intra_counter::Copy(&f_ptr,r.f_ptr); return *this; }
~b2smart_ptr()
{ intra_counter::Done(f_ptr); }
bool operator,(bool b) const
{ return f_ptr!=0 && bool(*f_ptr)==b; }
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; }
static b2smart_ptr<T> make()
{
T *ptr=intra_counter::Init();
new(ptr)T();// !!!
return b2smart_ptr<T>(ptr);
}
template<class A1>
static b2smart_ptr<T> make(A1 const & a1)
{
T *ptr=intra_counter::Init();
new(ptr)T(a1);// !!!
return b2smart_ptr<T>(ptr);
}
template<class A1,class A2>
static b2smart_ptr<T> make(A1 const & a1,A2 const & a2)
{
T *ptr=intra_counter::Init();
new(ptr)T(a1,a2);// !!!
return b2smart_ptr<T>(ptr);
}
template<class A1,class A2,class A3>
static b2smart_ptr<T> make(A1 const & a1,A2 const & a2,A3 const & a3)
{
T *ptr=intra_counter::Init();
new(ptr)T(a1,a2,a3);// !!!
return b2smart_ptr<T>(ptr);
}
};
#define NEW_PTR(T) b2smart_ptr<T>::make |
Partager