Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

refcount.hpp

Go to the documentation of this file.
00001 // +-------------------------------------------------------------------------+
00002 // |               I__n__t__e__L__i__b           0.6.10 development          |
00003 // | Copyright (c) Andrey Vikt. Stolyarov <crocodil_AT_croco.net> 2000-2007. |
00004 // |                                                                         |
00005 // | This is free software. The library part is available under              |
00006 // |                               GNU LESSER GENERAL PUBLIC LICENSE v.2.1.  |
00007 // | GNU LGPL v2.1 is found in docs/gnu_gpl2.txt,  or at  http://www.gnu.org |
00008 // |     Please see also docs/readme.txt and visit http://www.intelib.org    |
00009 // |                                                                         |
00010 // | !!! THERE IS NO WARRANTY OF ANY KIND, NEITHER EXPRESSED NOR IMPLIED !!! |
00011 // +-------------------------------------------------------------------------+
00012 
00013 
00014 
00015 
00026 #ifndef INTELIB_REFCOUNT_HPP_SENTRY
00027 #define INTELIB_REFCOUNT_HPP_SENTRY
00028 
00030 
00035 class GarbageSafe {
00036     friend class GarbageSafePointer;
00037     friend class GarbageSafeConstPointer;
00039 
00042     mutable int RefCount;
00044     void AddRef() const { RefCount++; }
00046     void Unlink() const { if((--RefCount)<=0) delete this; }
00047 protected:
00049 
00053     bool CanDie() { return RefCount <= 1; }
00054 public:
00056 
00064     GarbageSafe() { RefCount = 0; }
00065 protected:
00070     virtual ~GarbageSafe() {}
00071 private:
00075     void operator =(const GarbageSafe &other) {}
00076 };
00077 
00079 
00088 class GarbageSafePointer {
00089     GarbageSafe *p;
00090 public:
00092     GarbageSafePointer() { p = 0; }
00093 
00095     GarbageSafePointer(const GarbageSafe *pp) 
00096     { if((p = (GarbageSafe*) pp)) p->AddRef(); }
00097 
00099     GarbageSafePointer(const GarbageSafePointer &other)
00100     { if((p = other.p)) p->AddRef(); }
00101 
00103     ~GarbageSafePointer() { if(p) { p->Unlink(); p = 0; } }
00104 
00105 
00107 
00108     GarbageSafePointer& operator =(const GarbageSafePointer &other)
00109     {
00110         GarbageSafe *tmp = p; // this is a workaround for the case
00111         if((p = other.p)) p->AddRef();  // when unlinking p we destroy
00112         if(tmp) tmp->Unlink(); // the structure our operand belongs to
00113         return *this;
00114     }
00115 
00117     GarbageSafePointer& operator =(GarbageSafe *pp)
00118     {
00119         GarbageSafe *tmp = p; 
00120         if((p = pp)) p->AddRef();
00121         if(tmp) tmp->Unlink(); 
00122         return *this;
00123     }
00124 
00126     GarbageSafe* GetPtr() const { return p; }
00127 };
00128 
00129 
00131 inline bool
00132 operator==(const GarbageSafePointer& op1, const GarbageSafePointer& op2)
00133 { return op1.GetPtr() == op2.GetPtr(); }
00134 
00136 inline bool
00137 operator!=(const GarbageSafePointer& op1, const GarbageSafePointer& op2)
00138 { return op1.GetPtr() != op2.GetPtr(); }
00139 
00141 
00145 template <class Tp>
00146 class GenericReference : public GarbageSafePointer {
00147 public:
00149     GenericReference() {}
00151     GenericReference(const Tp *tp) : GarbageSafePointer(tp) {}
00153     GenericReference(const GenericReference &other)
00154             : GarbageSafePointer(other) {}
00156     ~GenericReference() {}
00157 
00159     GenericReference& operator=(Tp *tp)
00160     {
00161         GarbageSafePointer::operator=(tp);
00162         return *this;
00163     }
00165     GenericReference& operator=(const GenericReference &other)
00166     {
00167         GarbageSafePointer::operator=(other);
00168         return *this;
00169     }
00171     Tp* GetPtr() const
00172         { return static_cast<Tp*>(GarbageSafePointer::GetPtr()); }
00173 
00175     Tp* operator ->() const
00176         { return GetPtr(); }
00177 
00179     Tp& operator *() const
00180         { return *(GetPtr()); }
00181 
00182 };
00183 
00184 #endif //sentry

Generated on Tue Dec 18 00:39:44 2007 for InteLib by  doxygen 1.4.1