Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

counted_ptr.h

Go to the documentation of this file.
00001 /*
00002  * counted_ptr - simple reference counted pointer.
00003  *
00004  * The is a non-intrusive implementation that allocates an additional
00005  * int and pointer for every counted object.
00006  */
00007 
00008 #ifndef COUNTED_PTR_H
00009 #define COUNTED_PTR_H
00010 
00011 /* For ANSI-challenged compilers, you may want to #define
00012  * NO_MEMBER_TEMPLATES or explicit */
00013 
00014 template <class X> class counted_ptr
00015 {
00016 public:
00017     typedef X element_type;
00018 
00019     explicit counted_ptr(X* p = 0) // allocate a new counter
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     //template <class Y> friend class counted_ptr<Y>;
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     { // increment the count
00071         itsCounter = c;
00072         if (c) ++c->count;
00073     }
00074 
00075     void release()
00076     { // decrement the count, delete if it is 0
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

Generated on Tue Nov 4 01:57:57 2003 for COCONUT API by doxygen1.2.18