summaryrefslogtreecommitdiffstats
path: root/source/core/smart-pointer.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/smart-pointer.h')
-rw-r--r--source/core/smart-pointer.h593
1 files changed, 161 insertions, 432 deletions
diff --git a/source/core/smart-pointer.h b/source/core/smart-pointer.h
index d307e4e13..c31cdefe0 100644
--- a/source/core/smart-pointer.h
+++ b/source/core/smart-pointer.h
@@ -3,462 +3,191 @@
#include "type-traits.h"
+#include <assert.h>
+
namespace Slang
{
- class RefPtrDefaultDestructor
- {
- public:
- template<typename T>
- void operator ()(T * ptr)
- {
- delete ptr;
- }
- };
-
- class RefPtrArrayDestructor
- {
- public:
- template<typename T>
- void operator() (T * ptr)
- {
- delete [] ptr;
- }
- };
+ // TODO: Need to centralize these typedefs
+ typedef uintptr_t UInt;
+
+ // Base class for all reference-counted objects
+ class RefObject
+ {
+ private:
+ UInt referenceCount;
+
+ public:
+ RefObject()
+ : referenceCount(0)
+ {}
+
+ RefObject(const RefObject &)
+ : referenceCount(0)
+ {}
+
+ virtual ~RefObject()
+ {}
+
+ void addReference()
+ {
+ referenceCount++;
+ }
+
+ void releaseReference()
+ {
+ assert(referenceCount != 0);
+ if(--referenceCount == 0)
+ {
+ delete this;
+ }
+ }
+
+ bool isUniquelyReferenced()
+ {
+ assert(referenceCount != 0);
+ return referenceCount == 1;
+ }
+ };
+
+ inline void addReference(RefObject* obj)
+ {
+ if(obj) obj->addReference();
+ }
+
+ inline void releaseReference(RefObject* obj)
+ {
+ if(obj) obj->releaseReference();
+ }
+
+ // "Smart" pointer to a reference-counted object
+ template<typename T>
+ struct RefPtr
+ {
+ RefPtr()
+ : pointer(0)
+ {}
+
+ RefPtr(T* p)
+ : pointer(p)
+ {
+ addReference(p);
+ }
+
+ RefPtr(RefPtr<T> const& p)
+ : pointer(p.pointer)
+ {
+ addReference(p.pointer);
+ }
+
+ RefPtr(RefPtr<T>&& p)
+ : pointer(p.pointer)
+ {
+ p.pointer = 0;
+ }
+
+ template <typename U>
+ RefPtr(RefPtr<U> const& p,
+ typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
+ : pointer((U*) p)
+ {
+ addReference((U*) p);
+ }
+
+#if 0
+ void operator=(T* p)
+ {
+ T* old = pointer;
+ addReference(p);
+ pointer = p;
+ releaseReference(old);
+ }
+#endif
+
+ void operator=(RefPtr<T> const& p)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
+
+ void operator=(RefPtr<T>&& p)
+ {
+ T* old = pointer;
+ pointer = p.pointer;
+ p.pointer = old;
+ }
+
+ template <typename U>
+ typename EnableIf<IsConvertible<T*, U*>::value, void>::type
+ operator=(RefPtr<U> const& ptr)
+ {
+ T* old = pointer;
+ addReference(p.pointer);
+ pointer = p.pointer;
+ releaseReference(old);
+ }
- class ReferenceCounted
- {
- template<typename T, bool b, typename Destructor>
- friend class RefPtrImpl;
- private:
- int _refCount = 0;
- public:
- ReferenceCounted() {}
- ReferenceCounted(const ReferenceCounted &)
+ int GetHashCode()
{
- _refCount = 0;
+ return (int)(long long)(void*)pointer;
}
- };
-
- class RefObject : public ReferenceCounted
- {
- public:
- virtual ~RefObject()
- {}
- };
+ bool operator==(const T * ptr) const
+ {
+ return pointer == ptr;
+ }
- template<typename T, bool HasBuiltInCounter, typename Destructor>
- class RefPtrImpl
- {
- };
+ bool operator!=(const T * ptr) const
+ {
+ return pointer != ptr;
+ }
- template<typename T, typename Destructor = RefPtrDefaultDestructor>
- using RefPtr = RefPtrImpl<T, IsBaseOf<ReferenceCounted, T>::Value, Destructor>;
-
- template<typename T, typename Destructor>
- class RefPtrImpl<T, 0, Destructor>
- {
- template<typename T1, bool b, typename Destructor1>
- friend class RefPtrImpl;
- private:
- T * pointer;
- int * refCount;
-
- public:
- RefPtrImpl()
- {
- pointer = 0;
- refCount = 0;
- }
- RefPtrImpl(T * ptr)
- : pointer(0), refCount(0)
+ bool operator==(RefPtr<T> const& ptr) const
{
- this->operator=(ptr);
- }
- RefPtrImpl(const RefPtrImpl<T, 0, Destructor> & ptr)
- : pointer(0), refCount(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(RefPtrImpl<T, 0, Destructor> && str)
- : pointer(0), refCount(0)
- {
- this->operator=(static_cast<RefPtrImpl<T, 0, Destructor> &&>(str));
+ return pointer == ptr.pointer;
}
- template <typename U>
- RefPtrImpl(const RefPtrImpl<U, 0, Destructor>& ptr,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : pointer(0), refCount(0)
+ bool operator!=(RefPtr<T> const& ptr) const
{
- pointer = ptr.pointer;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
+ return pointer != ptr.pointer;
}
- template <typename U>
- typename EnableIf<IsConvertible<T*, U*>::value, RefPtrImpl<T, 0, Destructor>>::type&
- operator=(const RefPtrImpl<U,0,Destructor> & ptr)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
- return *this;
- }
+ template<typename U>
+ RefPtr<U> As() const
+ {
+ RefPtr<U> result(dynamic_cast<U*>(pointer));
+ return result;
+ }
- RefPtrImpl<T, 0, Destructor>& operator=(const RefPtrImpl<T, 0, Destructor> & ptr)
- {
- Unreference();
- pointer = ptr.pointer;
- if (ptr)
- {
- refCount = ptr.refCount;
- (*refCount)++;
- }
- else
- refCount = 0;
- return *this;
- }
+ ~RefPtr()
+ {
+ releaseReference(pointer);
+ }
- RefPtrImpl<T, 0, Destructor>& operator=(T * ptr)
- {
- if (ptr != pointer)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- refCount = new int;
- (*refCount) = 1;
- }
- else
- refCount = 0;
- }
- return *this;
- }
- int GetHashCode()
- {
- return (int)(long long)(void*)pointer;
- }
- bool operator == (const T * ptr) const
- {
- return pointer == ptr;
- }
- bool operator != (const T * ptr) const
- {
- return pointer != ptr;
- }
- template<typename U>
- bool operator == (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer == ptr.pointer;
- }
- template<typename U>
- bool operator != (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer != ptr.pointer;
- }
- template<typename U>
- RefPtrImpl<U, 0, Destructor> As() const
- {
- RefPtrImpl<U, 0, Destructor> result;
- if (pointer)
- {
- result.pointer = dynamic_cast<U*>(pointer);
- if (result.pointer)
- {
- result.refCount = refCount;
- (*refCount)++;
- }
- }
- return result;
- }
+ T& operator*() const
+ {
+ return *pointer;
+ }
- T* operator +(int offset) const
- {
- return pointer+offset;
- }
- T& operator [](int idx) const
- {
- return *(pointer + idx);
- }
- RefPtrImpl<T, 0, Destructor>& operator=(RefPtrImpl<T, 0, Destructor> && ptr)
- {
- if(ptr.pointer != pointer)
- {
- Unreference();
- pointer = ptr.pointer;
- refCount = ptr.refCount;
- ptr.pointer = 0;
- ptr.refCount = 0;
- }
- return *this;
- }
- T* Release()
- {
- if(pointer)
- {
- if((*refCount) > 1)
- {
- (*refCount)--;
- }
- else
- {
- delete refCount;
- }
- }
- auto rs = pointer;
- refCount = 0;
- pointer = 0;
- return rs;
- }
- ~RefPtrImpl()
- {
- Unreference();
- }
+ T* operator->() const
+ {
+ return pointer;
+ }
- void Unreference()
- {
- if(pointer)
- {
- if((*refCount) > 1)
- {
- (*refCount)--;
- }
- else
- {
- Destructor destructor;
- destructor(pointer);
- delete refCount;
- }
- }
- }
- T & operator *() const
- {
- return *pointer;
- }
- T * operator->() const
- {
- return pointer;
- }
T * Ptr() const
{
return pointer;
}
- public:
- explicit operator bool() const
- {
- if (pointer)
- return true;
- else
- return false;
- }
- };
-
-
- template<typename T, typename Destructor>
- class RefPtrImpl<T, 1, Destructor>
- {
- template<typename T1, bool b, typename Destructor1>
- friend class RefPtrImpl;
-
- private:
- T * pointer;
- public:
- RefPtrImpl()
- {
- pointer = 0;
- }
- RefPtrImpl(T * ptr)
- : pointer(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(const RefPtrImpl<T, 1, Destructor> & ptr)
- : pointer(0)
- {
- this->operator=(ptr);
- }
- RefPtrImpl(RefPtrImpl<T, 1, Destructor> && str)
- : pointer(0)
- {
- this->operator=(static_cast<RefPtrImpl<T, 1, Destructor> &&>(str));
- }
- template <typename U>
- RefPtrImpl(const RefPtrImpl<U, 1, Destructor>& ptr,
- typename EnableIf<IsConvertible<T*, U*>::Value, void>::type * = 0)
- : pointer(0)
- {
- pointer = ptr.pointer;
- if (ptr)
- {
- ptr->_refCount++;
- }
- }
- template <typename U>
- typename EnableIf<IsConvertible<T*, U*>::value, RefPtrImpl<T, 1, Destructor>&>::type
- operator=(const RefPtrImpl<U, 1, Destructor> & ptr)
- {
- Unreference();
-
- pointer = ptr.pointer;
- if (ptr)
- {
- ptr->_refCount++;
- }
- return *this;
- }
- RefPtrImpl<T, 1, Destructor>& operator=(T * ptr)
- {
- if (ptr != pointer)
- {
- Unreference();
-
- pointer = ptr;
- if (ptr)
- {
- ptr->_refCount++;
- }
- }
- return *this;
- }
- RefPtrImpl<T, 1, Destructor>& operator=(const RefPtrImpl<T, 1, Destructor> & ptr)
- {
- // Note: It is possible that the object this pointer references owns
- // (directly or indirectly) the storage for the argument `ptr`. If
- // that is the case and the `Unreference()` call below frees this
- // object, then the argument would become invalid.
- //
- // We copy the pointer value out of the argument first, in order
- // to protected against this case.
- T* ptrPointer = ptr.pointer;
- if (ptrPointer != pointer)
- {
- if (ptrPointer)
- ptrPointer->_refCount++;
- Unreference();
- pointer = ptrPointer;
- }
- return *this;
- }
- int GetHashCode()
- {
- return (int)(long long)(void*)pointer;
- }
- bool operator == (const T * ptr) const
- {
- return pointer == ptr;
- }
- bool operator != (const T * ptr) const
- {
- return pointer != ptr;
- }
- template<typename U>
- bool operator == (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer == ptr.pointer;
- }
- template<typename U>
- bool operator != (const RefPtr<U, Destructor> & ptr) const
- {
- return pointer != ptr.pointer;
- }
- template<typename U>
- RefPtrImpl<U, 1, Destructor> As() const
- {
- RefPtrImpl<U, 1, Destructor> result;
- if (pointer)
- {
- result.pointer = dynamic_cast<U*>(pointer);
- if (result.pointer)
- {
- result.pointer->_refCount++;
- }
- }
- return result;
- }
- T* operator +(int offset) const
- {
- return pointer + offset;
- }
- T& operator [](int idx) const
- {
- return *(pointer + idx);
- }
- RefPtrImpl<T, 1, Destructor>& operator=(RefPtrImpl<T, 1, Destructor> && ptr)
- {
- if (ptr.pointer != pointer)
- {
- Unreference();
- pointer = ptr.pointer;
- ptr.pointer = nullptr;
- }
- return *this;
- }
- T* Release()
- {
- if (pointer)
- {
- pointer->_refCount--;
- }
- auto rs = pointer;
- pointer = 0;
- return rs;
- }
- ~RefPtrImpl()
- {
- Unreference();
- }
+ operator T*() const
+ {
+ return pointer;
+ }
- void Unreference()
- {
- if (pointer)
- {
- if (pointer->_refCount > 1)
- {
- pointer->_refCount--;
- }
- else
- {
- Destructor destructor;
- destructor(pointer);
- }
- }
- }
- T & operator *() const
- {
- return *pointer;
- }
- T * operator->() const
- {
- return pointer;
- }
- T * Ptr() const
- {
- return pointer;
- }
- public:
- explicit operator bool() const
- {
- if (pointer)
- return true;
- else
- return false;
- }
+ private:
+ T* pointer;
+
};
}