#pragma once
class KRYPtrCount
{
public:
KRYPtrCount() :shared_count(1), weak_count(0){}
void addShared(){ shared_count += 1; }
void addWeak(){ weak_count += 1; }
void subShared(){ shared_count -= 1; }
void subWeak(){ weak_count -= 1; }
public:
int shared_count;
int weak_count;
};
template<typename T>
class KRYRefPtr
{
template<typename U>
friend class KRYRefPtr;
template<typename U>
friend class KRYWeakPtr;
private:
void subShared()
{
if (0 != m_count)
{
m_count->shared_count -= 1;
if (m_count->shared_count <= 0)
{
delete m_ptr; m_ptr = 0;
if (m_count->weak_count <= 0)
{
delete m_count;
m_count = 0;
}
}
}
}
template<typename U>
void init(const U *ptr)
{
m_ptr = (U*)ptr; m_count = 0;
if (0 != ptr){ m_count = new KRYPtrCount(); }
}
template<typename U>
void init(const KRYRefPtr<U> &ptr)
{
m_ptr = ptr.m_ptr; m_count = ptr.m_count;
if (0 != m_count){ m_count->addShared(); }
}
template<typename U>
void reset(const U *ptr)
{
subShared();
m_ptr = (U*)ptr; m_count = 0;
if (0 != ptr){ m_count = new KRYPtrCount(); }
}
template<typename U>
void reset(const KRYRefPtr<U> &ptr)
{
if (0 != ptr.m_count){ ptr.m_count->addShared(); }
subShared();
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
}
template<typename U>
KRYRefPtr(U *ptr, KRYPtrCount *count)
{
m_ptr = 0; m_count = 0;
if (0 != count && count->shared_count > 0)
{
m_ptr = ptr; m_count = count;
m_count->addShared();
}
}
public:
KRYRefPtr(){ m_ptr = 0; m_count = 0; }
~KRYRefPtr() { subShared(); }
KRYRefPtr(const KRYRefPtr& ptr) { init(ptr); }
KRYRefPtr operator=(const KRYRefPtr& ptr) { reset(ptr); return *this; }
template<typename U>
KRYRefPtr(U *ptr) { init(ptr); }
template<typename U>
KRYRefPtr<T>& operator=(U *ptr) { reset(ptr); return *this; }
template<typename U>
KRYRefPtr(const KRYRefPtr<U> &ptr) { init(ptr); }
template<typename U>
KRYRefPtr<T>& operator=(const KRYRefPtr<U> &ptr) { reset(ptr); return *this; }
T* operator->() const{ return m_ptr; }
T& operator*() const { return *m_ptr; }
operator bool() const { return m_ptr != 0; }
T* getPtr() const { return m_ptr; }
void reset(){ subShared(); m_ptr = 0; m_count = 0; }
private:
T *m_ptr;
KRYPtrCount *m_count;
};
template<typename T>
class KRYWeakPtr
{
template<typename U>
friend class KRYWeakPtr;
private:
void subWeak()
{
if (0 != m_count)
{
m_count->weak_count -= 1;
if (m_count->shared_count <= 0 && m_count->weak_count <= 0)
{
delete m_count;
m_count = 0;
}
}
}
template<typename U>
void init(const KRYWeakPtr<U> &ptr)
{
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
if (0 != m_count){ m_count->addWeak(); }
}
template<typename U>
void init(const KRYRefPtr<U> &ptr)
{
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
if (0 != m_count){ m_count->addWeak(); }
}
template<typename U>
void reset(const KRYWeakPtr<U> &ptr)
{
if (0 != ptr.m_count){ ptr.m_count->addWeak(); }
subWeak();
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
}
template<typename U>
void reset(const KRYRefPtr<U> &ptr)
{
if (0 != ptr.m_count){ ptr.m_count->addWeak(); }
subWeak();
m_ptr = ptr.m_ptr;
m_count = ptr.m_count;
}
public:
KRYWeakPtr(){ m_ptr = 0; m_count = 0; }
~KRYWeakPtr(){ subWeak(); }
KRYWeakPtr(const KRYWeakPtr &ptr) { init(ptr); }
KRYWeakPtr& operator=(const KRYWeakPtr &ptr) { reset(ptr); return *this; }
template<typename U>
KRYWeakPtr(const KRYWeakPtr<U> &ptr) { init(ptr); }
template<typename U>
KRYWeakPtr(const KRYRefPtr<U> &ptr) { init(ptr); }
template<typename U>
KRYWeakPtr& operator=(const KRYWeakPtr<U> &ptr) { reset(ptr); return *this; }
template<typename U>
KRYWeakPtr& operator=(const KRYRefPtr<U> &ptr) { reset(ptr); return *this; }
KRYRefPtr<T> lock()const{ return KRYRefPtr<T>(m_ptr, m_count); }
operator bool() const { return 0 != m_count && m_count->shared_count > 0; }
T* getPtr()const
{
T* ptr = 0;
if (0 != m_count && m_count->shared_count > 0) { ptr = m_ptr; }
return ptr;
}
private:
T *m_ptr;
KRYPtrCount *m_count;
};
template<typename T, typename U>
bool operator==(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() == b.getPtr()); }
template<typename T, typename U>
bool operator==(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() == b); }
template<typename T, typename U>
bool operator==(const U* a, const KRYRefPtr<T>& b) { return (a == b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() != b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() != b); }
template<typename T, typename U>
bool operator!=(const U* a, const KRYRefPtr<T>& b) { return (a != b.getPtr()); }
template<typename T, typename U>
bool operator==(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() == b.getPtr()); }
template<typename T, typename U>
bool operator==(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() == b); }
template<typename T, typename U>
bool operator==(const U* a, const KRYWeakPtr<T>& b) { return (a == b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() != b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() != b); }
template<typename T, typename U>
bool operator!=(const U* a, const KRYWeakPtr<T>& b) { return (a != b.getPtr()); }