RefCounted.h#

A smart pointer implementation very close to the spec of std::shared_ptr but with some differences and tweaks to make it more suitable for the PowerVR Framework. Note that RefCounted.h has now been made deprecated and is unused throughout the PowerVR SDK.

Includes#

  • atomic

  • memory

  • mutex

  • stdexcept

  • thread

  • type_traits

Included By#

Defines#

Source Code#

#pragma once
#include <thread>
#include <mutex>
#include <atomic>
#include <memory>
#include <type_traits>
#include <stdexcept>

#ifdef debug_assertion
#define DEBUG_ASSERTION_DEFINED = 1
#else
#ifdef DEBUG
#define debug_assertion(condition, message) \
    do \
    { \
        if (!(condition)) { throw std::runtime_error(message); } \
    } while (false);
#else
#define debug_assertion(condition, message)
#endif
#endif

namespace pvr {
template<typename>
class EmbeddedRefCountedResource;
template<typename>
class RefCountedResource;
template<typename>
class RefCountedWeakReference;
template<typename>
class EmbeddedRefCount;

struct IRefCountEntry
{
    template<typename>
    friend class RefCountedResource;
    template<typename>
    friend class EmbeddedRefCountedResource;
    template<typename>
    friend class RefCountedWeakReference;
    template<typename>
    friend class EmbeddedRefCount;

private:
    mutable volatile std::atomic<int32_t> count_;
    mutable volatile std::atomic<int32_t> weakcount_;
    std::mutex mylock;

public:
    int32_t count() { return count_; }
    int32_t weakcount() { return weakcount_; }

protected:
    void increment_count()
    {
        if (std::atomic_fetch_add(&count_, 1) == 0)
        {
            std::lock_guard<std::mutex> lockguard(mylock);
            if (count_.load() == 0) { throw std::runtime_error("RefCounted::increment_count:  Tried to increment the count of an object but it had already been destroyed!"); }
        }
    }
    void increment_weakcount()
    {
        if (std::atomic_fetch_add(&weakcount_, 1) == 0)
        {
            std::lock_guard<std::mutex> lockguard(mylock);
            if (weakcount_.load() == 0) { throw std::runtime_error("RefCounted::increment_count:  Tried to increment the count of an object but it had already been destroyed!"); }
        }
    }

    void decrement_count()
    {
        bool deleter = false; // Track, if it was THIS object that was the one to do the deletion!
        int32_t cnt = 0;
        {
            if ((cnt = std::atomic_fetch_add(&count_, -1)) == 1)
            {
                std::lock_guard<std::mutex> lockguard(mylock);
                destroyObject();
                if (weakcount() == 0) { deleter = true; }
            }
        }
        if (deleter) { deleteEntry(); }
    }

    void decrement_weakcount()
    {
        bool deleter = false; // DO NOT DESTROY THE OBJECT WHILE THE MUTEX IS USED!
        if (((std::atomic_fetch_add(&weakcount_, -1)) == 1))
        {
            std::lock_guard<std::mutex> lockguard(mylock);
            if (count_.load() == 0) { deleter = true; }
        }
        if (deleter) { deleteEntry(); }
    }

    virtual void deleteEntry() = 0;
    virtual void destroyObject() = 0;
    virtual ~IRefCountEntry() {}
    IRefCountEntry() : count_(1), weakcount_(0) {}
};

template<typename MyClass_>
struct RefCountEntryIntrusive : public IRefCountEntry
{
    union
    {
        double _alignment_;
        char entry[sizeof(MyClass_)];
    };
    template<typename... Args>
    RefCountEntryIntrusive(MyClass_*& pointee, Args&&... args)
    {
        pointee = new (entry) MyClass_(std::forward<Args>(args)...);
    }
    void deleteEntry() { delete this; }

    void destroyObject() { reinterpret_cast<MyClass_*>(entry)->~MyClass_(); }
};

template<typename MyClass_>
struct RefCountEntry : public IRefCountEntry
{
    MyClass_* ptr;
    RefCountEntry() : ptr(NULL) {}
    RefCountEntry(MyClass_* ptr) : ptr(ptr) {}
    void deleteEntry() { delete this; }
    void destroyObject() { delete ptr; }
};

template<typename MyClass_>
class Dereferenceable
{
protected:
    MyClass_* _pointee;
    Dereferenceable(const MyClass_* pointee) { this->_pointee = const_cast<MyClass_*>(pointee); }

public:
    MyClass_& operator*()
    {
        debug_assertion(_pointee != 0, "Dereferencing NULL pointer");
        return *_pointee;
    }
    const MyClass_& operator*() const
    {
        debug_assertion(_pointee != 0, "Dereferencing NULL pointer");
        return *_pointee;
    }

    MyClass_* operator->()
    {
        debug_assertion(_pointee != 0, "Dereferencing NULL pointer");
        return _pointee;
    }
    const MyClass_* operator->() const
    {
        debug_assertion(_pointee != 0, "Dereferencing NULL pointer");
        return _pointee;
    }

    bool operator==(const Dereferenceable& rhs) const { return _pointee == rhs._pointee; }

    bool operator!=(const Dereferenceable& rhs) const { return _pointee != rhs._pointee; }

    bool operator<(const Dereferenceable& rhs) const { return _pointee < rhs._pointee; }

    bool operator>(const Dereferenceable& rhs) const { return _pointee > rhs._pointee; }

    bool operator<=(const Dereferenceable& rhs) const { return _pointee <= rhs._pointee; }

    bool operator>=(const Dereferenceable& rhs) const { return _pointee >= rhs._pointee; }
};
template<>
class Dereferenceable<void>
{
protected:
    Dereferenceable(void* pointee) : _pointee(pointee) {}
    void* _pointee;

public:
    bool operator==(const Dereferenceable& rhs) const { return _pointee == rhs._pointee; }

    bool operator!=(const Dereferenceable& rhs) const { return _pointee != rhs._pointee; }

    bool operator<(const Dereferenceable& rhs) const { return _pointee < rhs._pointee; }

    bool operator>(const Dereferenceable& rhs) const { return _pointee > rhs._pointee; }

    bool operator<=(const Dereferenceable& rhs) const { return _pointee <= rhs._pointee; }

    bool operator>=(const Dereferenceable& rhs) const { return _pointee >= rhs._pointee; }
};

template<typename MyClass_>
struct RefcountEntryHolder
{
    template<typename>
    friend class RefCountedResource;
    template<typename>
    friend class EmbeddedRefCountedResource;

protected:
    // Holding the actual entry (pointers, objects and everything). Use directly in the subclass.
    IRefCountEntry* refCountEntry;

    // Create a new intrusive refcount entry, and on it, construct a new object with its constructor.
    template<typename... Args>
    void construct(MyClass_*& pointee, Args&&... args)
    {
        RefCountEntryIntrusive<MyClass_>* ptr = new RefCountEntryIntrusive<MyClass_>(pointee, std::forward<Args>(args)...);
        refCountEntry = ptr;
    }

    // Create this entry with an already constructed reference-counted entry.
    RefcountEntryHolder(IRefCountEntry* refCountEntry) : refCountEntry(refCountEntry) {}
};

template<>
struct RefcountEntryHolder<void>
{
protected:
    IRefCountEntry* refCountEntry;
    RefcountEntryHolder(IRefCountEntry* refCountEntry) : refCountEntry(refCountEntry) {}
};

template<typename MyClass_>
class EmbeddedRefCountedResource : public Dereferenceable<MyClass_>, public RefcountEntryHolder<MyClass_>
{
    template<typename>
    friend class EmbeddedRefCount;
    template<typename>
    friend class RefCountedResource;
    template<typename>
    friend class EmbeddedRefCountedResource;
    template<typename>
    friend class RefCountedWeakReference;

public:
    typedef MyClass_ ElementType;

    bool isValid() const { return RefcountEntryHolder<MyClass_>::refCountEntry != NULL && RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0; }

    bool isNull() const { return RefcountEntryHolder<MyClass_>::refCountEntry == NULL || RefcountEntryHolder<MyClass_>::refCountEntry->count() == 0; }

    MyClass_* get() { return Dereferenceable<MyClass_>::_pointee; }

    const MyClass_* get() const { return Dereferenceable<MyClass_>::_pointee; }

    void swap(EmbeddedRefCountedResource& rhs)
    {
        IRefCountEntry* tmpRefCountEntry = RefcountEntryHolder<MyClass_>::refCountEntry;
        RefcountEntryHolder<MyClass_>::refCountEntry = rhs.refCountEntry;
        rhs.refCountEntry = tmpRefCountEntry;
        MyClass_* tmpPointee = Dereferenceable<MyClass_>::_pointee;
        Dereferenceable<MyClass_>::_pointee = rhs._pointee;
        rhs._pointee = tmpPointee;
    }

    EmbeddedRefCountedResource() : Dereferenceable<MyClass_>(NULL), RefcountEntryHolder<MyClass_>(0) {}

    EmbeddedRefCountedResource(const EmbeddedRefCountedResource& rhs) : Dereferenceable<MyClass_>(rhs), RefcountEntryHolder<MyClass_>(rhs)
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_count();
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
        }
    }

    template<typename MyPointer_>
    explicit EmbeddedRefCountedResource(MyPointer_* ref) : Dereferenceable<MyClass_>(ref), RefcountEntryHolder<MyClass_>(new RefCountEntry<MyPointer_>(ref))
    {
        RefcountEntryHolder<MyClass_>::refCountEntry->count_ = 1;
    }

    EmbeddedRefCountedResource& operator=(EmbeddedRefCountedResource rhs)
    {
        swap(rhs);
        debug_assertion(!RefcountEntryHolder<MyClass_>::refCountEntry ||
                (RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0 && RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0),
            "BUG - Count was negative.");
        return *this;
    }

    template<class OldType_>
    EmbeddedRefCountedResource(const EmbeddedRefCountedResource<OldType_>& rhs, typename std::enable_if<std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(rhs._pointee), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<OldType_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_count();
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
        }
    }

    template<class OldType_>
    explicit EmbeddedRefCountedResource(const EmbeddedRefCountedResource<OldType_>& rhs, typename std::enable_if<!std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(static_cast<MyClass_*>(rhs._pointee)), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<MyClass_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_count();
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
        }
    }

    virtual ~EmbeddedRefCountedResource() { reset(); }

    bool operator!=(const EmbeddedRefCountedResource& rhs) const { return get() != rhs.get(); }

    template<typename MyPointer_>
    void reset(MyPointer_* ref)
    {
        reset();
        RefcountEntryHolder<MyClass_>::refCountEntry = new RefCountEntry<MyPointer_>(ref);
        Dereferenceable<MyClass_>::_pointee = ref;
    }

    void reset() { releaseOne(); }

protected:
    template<typename OriginalType>
    EmbeddedRefCountedResource(IRefCountEntry* entry, OriginalType* pointee) : Dereferenceable<MyClass_>(static_cast<MyClass_*>(pointee)), RefcountEntryHolder<MyClass_>(entry)
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() >= 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_count();
            debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
        }
    }

private:
    void releaseOne()
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            IRefCountEntry* tmp = RefcountEntryHolder<MyClass_>::refCountEntry;
            RefcountEntryHolder<MyClass_>::refCountEntry = 0;
            Dereferenceable<MyClass_>::_pointee = 0;
            tmp->decrement_count();
        }
    }
};

template<typename MyClass_>
class RefCountedResource : public EmbeddedRefCountedResource<MyClass_>
{
    template<typename>
    friend class EmbeddedRefCount;
    template<typename>
    friend class RefCountedResource;
    template<typename>
    friend class EmbeddedRefCountedResource;
    template<typename>
    friend class RefCountedWeakReference;

public:
    typedef typename EmbeddedRefCountedResource<MyClass_>::ElementType ElementType;

    void swap(RefCountedResource& rhs)
    {
        IRefCountEntry* tmpRefCountEntry = RefcountEntryHolder<MyClass_>::refCountEntry;
        RefcountEntryHolder<MyClass_>::refCountEntry = rhs.refCountEntry;
        rhs.refCountEntry = tmpRefCountEntry;
        MyClass_* tmpPointee = Dereferenceable<MyClass_>::_pointee;
        Dereferenceable<MyClass_>::_pointee = rhs._pointee;
        rhs._pointee = tmpPointee;
    }

    RefCountedResource() {}

    RefCountedResource(const RefCountedResource& rhs) : EmbeddedRefCountedResource<MyClass_>(rhs) {}

    template<typename MyPointer_>
    explicit RefCountedResource(MyPointer_* ref) : EmbeddedRefCountedResource<MyClass_>(ref)
    {
        RefcountEntryHolder<MyClass_>::refCountEntry->count_ = 1;
    }

    RefCountedResource& operator=(RefCountedResource rhs)
    {
        swap(rhs);
        return *this;
    }

    template<class OldType_>
    RefCountedResource(const RefCountedResource<OldType_>& rhs, typename std::enable_if<std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* t = 0)
        : EmbeddedRefCountedResource<MyClass_>(rhs, t)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<OldType_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
    }

    template<class OldType_>
    explicit RefCountedResource(const RefCountedResource<OldType_>& rhs, typename std::enable_if<!std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* t = 0)
        : EmbeddedRefCountedResource<MyClass_>(rhs, t)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<MyClass_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
    }

    virtual ~RefCountedResource()
    { /*release called from EmbeddedRefCountedResource*/
    }

    template<typename MyPointer_>
    void reset(MyPointer_* ref)
    {
        EmbeddedRefCountedResource<MyClass_>::reset();
        RefcountEntryHolder<MyClass_>::refCountEntry = new RefCountEntry<MyPointer_>(ref);
        Dereferenceable<MyClass_>::_pointee = ref;
    }

    void reset() { EmbeddedRefCountedResource<MyClass_>::reset(); }

    template<typename... Params>
    void construct(Params&&... params)
    {
        EmbeddedRefCountedResource<MyClass_>::reset();
        RefcountEntryHolder<MyClass_>::construct(Dereferenceable<MyClass_>::_pointee, std::forward<Params>(params)...);
    }

    template<typename OriginalType>
    void shareRefCountFrom(const RefCountedResource<OriginalType>& resource, typename EmbeddedRefCountedResource<MyClass_>::ElementType* pointee)
    {
        shareRefCountingFrom(RefcountEntryHolder<OriginalType>(resource).refCountEntry, pointee);
    }

private:
    void shareRefCountingFrom(IRefCountEntry* entry, ElementType* pointee)
    {
        EmbeddedRefCountedResource<MyClass_>::reset();
        RefcountEntryHolder<ElementType>::refCountEntry = entry;
        entry->increment_count();
        debug_assertion((RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0) && (RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() >= 0), "BUG - Count was negative.");
        Dereferenceable<ElementType>::_pointee = pointee;
    }

    template<typename OriginalType>
    RefCountedResource(const IRefCountEntry* entry, OriginalType* pointee) : EmbeddedRefCountedResource<MyClass_>(entry, pointee)
    {}
};

template<typename MyClass_>
class RefCountedWeakReference : public Dereferenceable<MyClass_>, public RefcountEntryHolder<MyClass_>
{
    template<typename>
    friend class EmbeddedRefCount;
    template<typename>
    friend class RefCountedResource;
    template<typename>
    friend class EmbeddedRefCountedResource;
    template<typename>
    friend class RefCountedWeakReference;

public:
    typedef MyClass_ ElementType;

    bool isValid() const { return RefcountEntryHolder<MyClass_>::refCountEntry != NULL && RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0; }

    bool isNull() const { return RefcountEntryHolder<MyClass_>::refCountEntry == NULL || RefcountEntryHolder<MyClass_>::refCountEntry->count() == 0; }

    MyClass_* get() { return Dereferenceable<MyClass_>::_pointee; }

    const MyClass_* get() const { return Dereferenceable<MyClass_>::_pointee; }

    void swap(RefCountedWeakReference& rhs)
    {
        IRefCountEntry* tmpRefCountEntry = RefcountEntryHolder<MyClass_>::refCountEntry;
        RefcountEntryHolder<MyClass_>::refCountEntry = rhs.refCountEntry;
        rhs.refCountEntry = tmpRefCountEntry;
        MyClass_* tmpPointee = Dereferenceable<MyClass_>::_pointee;
        Dereferenceable<MyClass_>::_pointee = rhs._pointee;
        rhs._pointee = tmpPointee;
    }

    RefCountedWeakReference() : Dereferenceable<MyClass_>(NULL), RefcountEntryHolder<MyClass_>(0) {}

    RefCountedWeakReference(const RefCountedWeakReference& rhs) : Dereferenceable<MyClass_>(rhs), RefcountEntryHolder<MyClass_>(rhs)
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "BUG - Reference count was nonpositive.");
        }
    }

    RefCountedWeakReference(const EmbeddedRefCountedResource<MyClass_>& rhs) : Dereferenceable<MyClass_>(rhs), RefcountEntryHolder<MyClass_>(rhs)
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    RefCountedWeakReference& operator=(RefCountedWeakReference rhs)
    {
        swap(rhs);
        return *this;
    }

    template<class OldType_>
    RefCountedWeakReference(const EmbeddedRefCountedResource<OldType_>& rhs, typename std::enable_if<std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(rhs._pointee), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<OldType_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    template<class OldType_>
    explicit RefCountedWeakReference(const EmbeddedRefCountedResource<OldType_>& rhs, typename std::enable_if<!std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(static_cast<MyClass_*>(rhs._pointee)), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<MyClass_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    template<class OldType_>
    RefCountedWeakReference(const RefCountedWeakReference<OldType_>& rhs, typename std::enable_if<std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(rhs._pointee), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<OldType_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    template<class OldType_>
    explicit RefCountedWeakReference(const RefCountedWeakReference<OldType_>& rhs, typename std::enable_if<!std::is_convertible<OldType_*, MyClass_*>::value, void*>::type* = 0)
        : Dereferenceable<MyClass_>(static_cast<MyClass_*>(rhs._pointee)), RefcountEntryHolder<MyClass_>(rhs.refCountEntry)
    {
        // Compile-time check: are these types compatible?
        OldType_* checkMe = static_cast<MyClass_*>(Dereferenceable<MyClass_>::_pointee);
        (void)checkMe;
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    virtual ~RefCountedWeakReference() { release(); }

    void release()
    {
        releaseOne();
        RefcountEntryHolder<MyClass_>::refCountEntry = 0;
        Dereferenceable<MyClass_>::_pointee = 0;
    }

    void reset() { release(); }

private:
    void retainOne()
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }

    void releaseOne()
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            IRefCountEntry* tmp = RefcountEntryHolder<MyClass_>::refCountEntry;
            RefcountEntryHolder<MyClass_>::refCountEntry = 0;
            Dereferenceable<MyClass_>::_pointee = 0;
            tmp->decrement_weakcount();
        }
    }

    template<typename OriginalType>
    RefCountedWeakReference(IRefCountEntry* entry, OriginalType* pointee) : Dereferenceable<MyClass_>(static_cast<MyClass_*>(pointee)), RefcountEntryHolder<MyClass_>(entry)
    {
        if (RefcountEntryHolder<MyClass_>::refCountEntry)
        {
            RefcountEntryHolder<MyClass_>::refCountEntry->increment_weakcount();
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->weakcount() > 0, "Reference count was not positive");
            debug_assertion(RefcountEntryHolder<MyClass_>::refCountEntry->count() > 0, "Reference count was not positive");
        }
    }
};

template<typename MyClass_>
class EmbeddedRefCount : public IRefCountEntry
{
public:
    typedef EmbeddedRefCount<MyClass_> MyEmbeddedType;
    typedef EmbeddedRefCountedResource<MyClass_> StrongReferenceType;
    typedef RefCountedWeakReference<MyClass_> WeakReferenceType;
    WeakReferenceType getWeakReference() { return WeakReferenceType(static_cast<MyClass_*>(this), static_cast<MyClass_*>(this)); }
    StrongReferenceType getReference() { return StrongReferenceType(static_cast<MyClass_*>(this), static_cast<MyClass_*>(this)); }

protected:
    EmbeddedRefCount() {}

    template<typename... Params>
    static StrongReferenceType createNew(Params&&... params)
    {
        MyClass_* item = new MyClass_(std::forward<Params>(params)...);
        StrongReferenceType ptr(item, item);
        item->decrement_count();
        return ptr;
    }

    void deleteEntry() { delete static_cast<MyClass_*>(this); }
};

template<typename T>
struct IsRefCountedType
{
    template<typename U, void (U::*)()>
    struct SFINAE
    {};
    template<typename U>
    static char Test(SFINAE<U, &U::construct>*);
    template<typename U>
    static int Test(...);
    enum
    {
        value = (sizeof(Test<T>(0)) == sizeof(char))
    };
};
} // namespace pvr
#ifdef DEBUG_ASSERTION_DEFINED
#undef DEBUG_ASSERTION_DEFINED
#else
#undef debug_assertion
#endif