Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #ifndef __refcount_h__
  2. #define __refcount_h__
  3.  
  4. #include "lispassert.h"
  5. #include "yacasbase.h"
  6.  
  7. //------------------------------------------------------------------------------
  8. // RefPtr - Smart pointer for (intrusive) reference counting.
  9. // Simply, an object's reference count is the number of RefPtrs refering to it.
  10. // The RefPtr will delete the referenced object when the count reaches zero.
  11.  
  12. /*TODO: this might be improved a little by having RefPtr wrap the object being
  13.   pointed to so the user of RefPtr does not need to add ReferenceCount explicitly.
  14.   One can use RefPtr on any arbitrary object from that moment on.
  15.  */
  16.  
  17. typedef ReferenceType ReferenceCount;
  18.  
  19. template<class T>
  20. class RefPtr : public YacasBase  // derived, so we can 'NEW LispPtr[nnn]'
  21. {
  22. public:
  23.   // Default constructor (not explicit, so it auto-initializes)
  24.   inline RefPtr() : iPtr(NULL) {}
  25.   // Construct from pointer to T
  26.   explicit RefPtr(T *ptr) : iPtr(ptr) { if (ptr) { ptr->iReferenceCount++; } }
  27.   // Copy constructor
  28.   RefPtr(const RefPtr &refPtr) : iPtr(refPtr.ptr()) { if (iPtr) { iPtr->iReferenceCount++; } }
  29.   // Destructor
  30.   ~RefPtr()
  31.   {
  32.     if (iPtr)
  33.     {
  34.       iPtr->iReferenceCount--;
  35.       if (iPtr->iReferenceCount == 0)
  36.       {
  37.         delete iPtr;
  38.       }
  39.     }
  40.   }
  41.   // Assignment from pointer
  42.   RefPtr &operator=(T *ptr)
  43.   {
  44.     if (ptr)
  45.     {
  46.       ptr->iReferenceCount++;
  47.     }
  48.     if (iPtr)
  49.     {
  50.       iPtr->iReferenceCount--;
  51.       if (iPtr->iReferenceCount == 0)
  52.       {
  53.         delete iPtr;
  54.       }
  55.     }
  56.     iPtr = ptr;
  57.     return *this;
  58.   }
  59.   // Assignment from another
  60.   RefPtr &operator=(const RefPtr &refPtr) { return this->operator=(refPtr.ptr()); }
  61.  
  62.   operator T*()    const { return  iPtr; }  // implicit conversion to pointer to T
  63.   T &operator*()   const { return *iPtr; }  // so (*refPtr) is a reference to T
  64.   T *operator->()  const { return  iPtr; }  // so (refPtr->member) accesses T's member
  65.   T *ptr()         const { return  iPtr; }  // so (refPtr.ptr()) returns the pointer to T (boost calls this method 'get')
  66.   bool operator!() const { return !iPtr; }  // is null pointer
  67.  
  68. private:
  69.    T *iPtr;
  70. };
  71.  
  72.  
  73. #endif
  74.  
  75.