blob: fd7d741b831f012b93e82a3628323f76ac96db35 [file]
/**
* Copyright (C) 2013 kangliqiang ,kangliq@163.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __KPR_REFHANDLET_H__
#define __KPR_REFHANDLET_H__
#include "KPRTypes.h"
#include "AtomicValue.h"
#include "Exception.h"
namespace kpr
{
class RefCount
{
public:
RefCount& operator=(const RefCount&)
{
return *this;
}
void incRef()
{
m_refCount++;
}
void decRef()
{
if (--m_refCount == 0 && !m_noDelete)
{
m_noDelete = true;
delete this;
}
}
int getRef() const
{
return m_refCount.get();
}
void setNoDelete(bool b)
{
m_noDelete = b;
}
protected:
RefCount()
: m_refCount(0), m_noDelete(false)
{
}
RefCount(const RefCount&)
: m_refCount(0), m_noDelete(false)
{
}
virtual ~RefCount()
{
}
protected:
AtomicInteger m_refCount;
bool m_noDelete;
};
template <class T>
class RefHandleT
{
public:
RefHandleT(T* p = 0)
{
m_ptr = p;
if (m_ptr)
{
m_ptr->incRef();
}
}
template<typename Y>
RefHandleT(const RefHandleT<Y>& v)
{
m_ptr = v.m_ptr;
if (m_ptr)
{
m_ptr->incRef();
}
}
RefHandleT(const RefHandleT& v)
{
m_ptr = v.m_ptr;
if (m_ptr)
{
m_ptr->incRef();
}
}
~RefHandleT()
{
if (m_ptr)
{
m_ptr->decRef();
}
}
RefHandleT<T>& operator=(T* p)
{
if (m_ptr != p)
{
if (p)
{
p->incRef();
}
T* ptr = m_ptr;
m_ptr = p;
if (ptr)
{
ptr->decRef();
}
}
return *this;
}
template<typename Y>
RefHandleT<T>& operator=(const RefHandleT<Y>& v)
{
if (m_ptr != v.m_ptr)
{
if (v.m_ptr)
{
v.m_ptr->incRef();
}
T* ptr = m_ptr;
m_ptr = v.m_ptr;
if (ptr)
{
ptr->decRef();
}
}
return *this;
}
RefHandleT<T>& operator=(const RefHandleT<T>& v)
{
if (m_ptr != v.m_ptr)
{
if (v.m_ptr)
{
v.m_ptr->incRef();
}
T* ptr = m_ptr;
m_ptr = v.m_ptr;
if (ptr)
{
ptr->decRef();
}
}
return *this;
}
T* operator->() const
{
if (!m_ptr)
{
THROW_EXCEPTION(RefHandleNullException, "autoptr null handle error", -1);
}
return m_ptr;
}
T& operator*() const
{
if (!m_ptr)
{
THROW_EXCEPTION(RefHandleNullException, "autoptr null handle error", -1);
}
return *m_ptr;
}
operator T* () const
{
return m_ptr;
}
T* ptr() const
{
return m_ptr;
}
T* retn()
{
T* p = m_ptr;
m_ptr = 0;
return p;
}
bool operator==(const RefHandleT<T>& v) const
{
return m_ptr == v.m_ptr;
}
bool operator==(T* p) const
{
return m_ptr == p;
}
bool operator!=(const RefHandleT<T>& v) const
{
return m_ptr != v.m_ptr;
}
bool operator!=(T* p) const
{
return m_ptr != p;
}
bool operator!() const
{
return m_ptr == 0;
}
operator bool() const
{
return m_ptr != 0;
}
void swap(RefHandleT& other)
{
std::swap(m_ptr, other._ptr);
}
template<class Y>
static RefHandleT dynamicCast(const RefHandleT<Y>& r)
{
return RefHandleT(dynamic_cast<T*>(r._ptr));
}
template<class Y>
static RefHandleT dynamicCast(Y* p)
{
return RefHandleT(dynamic_cast<T*>(p));
}
public:
T* m_ptr;
};
template<typename T, typename U>
inline bool operator==(const RefHandleT<T>& lhs, const RefHandleT<U>& rhs)
{
T* l = lhs.ptr();
U* r = rhs.ptr();
if(l && r)
{
return *l == *r;
}
else
{
return !l && !r;
}
}
template<typename T, typename U>
inline bool operator!=(const RefHandleT<T>& lhs, const RefHandleT<U>& rhs)
{
T* l = lhs.ptr();
U* r = rhs.ptr();
if(l && r)
{
return *l != *r;
}
else
{
return l || r;
}
}
template<typename T, typename U>
inline bool operator<(const RefHandleT<T>& lhs, const RefHandleT<U>& rhs)
{
T* l = lhs.ptr();
U* r = rhs.ptr();
if(l && r)
{
return *l < *r;
}
else
{
return !l && r;
}
}
}
#define DECLAREVAR(T) typedef kpr::RefHandleT<T> T ## Ptr;
#endif