00001
00002
00003
00004
00005
00006
00007
00008 #ifndef COUNTED_PTR_H
00009 #define COUNTED_PTR_H
00010
00011
00012
00013
00014 template <class X> class counted_ptr
00015 {
00016 public:
00017 typedef X element_type;
00018
00019 explicit counted_ptr(X* p = 0)
00020 : itsCounter(0) {if (p) itsCounter = new counter(p);}
00021 ~counted_ptr()
00022 {release();}
00023 counted_ptr(const counted_ptr& r) throw()
00024 {acquire(r.itsCounter);}
00025 counted_ptr& operator=(const counted_ptr& r)
00026 {
00027 if (this != &r) {
00028 release();
00029 acquire(r.itsCounter);
00030 }
00031 return *this;
00032 }
00033 counted_ptr& operator=(element_type* r)
00034 {
00035 release();
00036 if(itsCounter) delete itsCounter;
00037 if(r) itsCounter = new counter(r); else itsCounter = 0;
00038 return *this;
00039 }
00040
00041 #ifndef NO_MEMBER_TEMPLATES
00042
00043 template <class Y> counted_ptr(const counted_ptr<Y>& r) throw()
00044 {acquire(r.itsCounter);}
00045 template <class Y> counted_ptr& operator=(const counted_ptr<Y>& r)
00046 {
00047 if (this != &r) {
00048 release();
00049 acquire(r.itsCounter);
00050 }
00051 return *this;
00052 }
00053 #endif // NO_MEMBER_TEMPLATES
00054
00055 X& operator*() const throw() {return *itsCounter->ptr;}
00056 X* operator->() const throw() {return itsCounter->ptr;}
00057 X* get() const throw() {return itsCounter ? itsCounter->ptr : 0;}
00058 bool unique() const throw()
00059 {return (itsCounter ? itsCounter->count == 1 : true);}
00060
00061 private:
00062
00063 struct counter {
00064 counter(X* p = 0, unsigned c = 1) : ptr(p), count(c) {}
00065 X* ptr;
00066 unsigned count;
00067 }* itsCounter;
00068
00069 void acquire(counter* c) throw()
00070 {
00071 itsCounter = c;
00072 if (c) ++c->count;
00073 }
00074
00075 void release()
00076 {
00077 if (itsCounter) {
00078 if (--itsCounter->count == 0) {
00079 delete itsCounter->ptr;
00080 delete itsCounter;
00081 }
00082 itsCounter = 0;
00083 }
00084 }
00085 };
00086
00087 #endif // COUNTED_PTR_H