base.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * Copyright (C) 2008-2011 Adam <Adam@anope.org>
00004  * Copyright (C) 2008-2013 Anope Team <team@anope.org>
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  */
00009 
00010 #ifndef BASE_H
00011 #define BASE_H
00012 
00013 #include "services.h"
00014 
00017 class CoreExport Base
00018 {
00019         /* References to this base class */
00020         std::set<ReferenceBase *> *references;
00021  public:
00022         Base();
00023         virtual ~Base();
00024 
00029         void AddReference(ReferenceBase *r);
00030 
00031         void DelReference(ReferenceBase *r);
00032 };
00033 
00034 class ReferenceBase
00035 {
00036  protected:
00037         bool invalid;
00038  public:
00039         ReferenceBase() : invalid(false) { }
00040         ReferenceBase(const ReferenceBase &other) : invalid(other.invalid) { }
00041         virtual ~ReferenceBase() { }
00042         inline void Invalidate() { this->invalid = true; }
00043 };
00044 
00048 template<typename T>
00049 class Reference : public ReferenceBase
00050 {
00051  protected:
00052         T *ref;
00053  public:
00054         Reference() : ref(NULL)
00055         {
00056         }
00057 
00058         Reference(T *obj) : ref(obj)
00059         {
00060                 if (ref)
00061                         ref->AddReference(this);
00062         }
00063 
00064         Reference(const Reference<T> &other) : ReferenceBase(other), ref(other.ref)
00065         {
00066                 if (operator bool())
00067                         ref->AddReference(this);
00068         }
00069 
00070         virtual ~Reference()
00071         {
00072                 if (operator bool())
00073                         ref->DelReference(this);
00074         }
00075 
00076         inline Reference<T>& operator=(const Reference<T> &other)
00077         {
00078                 if (this != &other)
00079                 {
00080                         if (*this)
00081                                 this->ref->DelReference(this);
00082 
00083                         this->ref = other.ref;
00084                         this->invalid = other.invalid;
00085 
00086                         if (*this)
00087                                 this->ref->AddReference(this);
00088                 }
00089                 return *this;
00090         }
00091 
00092         /* We explicitly call operator bool here in several places to prevent other
00093          * operators, such operator T*, from being called instead, which will mess
00094          * with any class inheriting from this that overloads this operator.
00095          */
00096         virtual operator bool()
00097         {
00098                 if (!this->invalid)
00099                         return this->ref != NULL;
00100                 return false;
00101         }
00102 
00103         inline operator T*()
00104         {
00105                 if (operator bool())
00106                         return this->ref;
00107                 return NULL;
00108         }
00109 
00110         inline T* operator->()
00111         {
00112                 if (operator bool())
00113                         return this->ref;
00114                 return NULL;
00115         }
00116 
00117         inline T* operator*()
00118         {
00119                 if (operator bool())
00120                         return this->ref;
00121                 return NULL;
00122         }
00123 
00136         inline bool operator==(const Reference<T> &other)
00137         {
00138                 if (!this->invalid)
00139                         return this->ref == other;
00140                 return false;
00141         }
00142 };
00143 
00144 #endif // BASE_H
00145