/*Copyright (C) 2010, Wei,Bing. Created 2006 All rights reserved.
/*Feel free to use and distribute. May not be sold for profit.
/*License to copy and use this software is granted provided that it
/*is identified as the "Wei,Bing. prototype-independently
/*embedded reference counting" in all material mentioning or referencing
/*this software or this function.
/*License is also granted to make and use derivative works provided
/*that such works are identified as "derived from Wei,Bing.
/*prototype-independently embedded reference counting" in all material
/*mentioning or referencing the derived work.
/*Wei,Bing makes no representations concerning either the merchantability
/*of this software or the suitability of this software for any particular
/*purpose. It is provided "as is" without express or implied warranty
/*of any kind.
/*These notices must be retained in any copies of any part of this
/*documentation and/or software.
*/
#pragma once
//#include <IComMemory.h> ���������������Ӧ����Ԥ����ͷ��
/*���̰߳�ȫ������ָ��ֻ�ܱ�֤����̹߳�������ָ�벢��ȡ(����ָ�븴��)�������д�룬��������⣬COM����ָ��Ҳ�����
/*�������������ͨ����������Ա���������Դ�����ܴ������
*/
/*����ṩ��������Ĺؼ���(��Ҫ���������)������ʹ��������ָ��ֻ��4���ֽ�
/*ptr single_shift(ptr) �ɶ���ָ��õ��ѵ�ͷ��
/*size_t array_shift(T) �����͵õ���ͷ����ƫ��
/*ptr array_shift(ptr) �ɶ���ָ��õ��ѵ�ͷ��
/*����ָ�뼴ʹ������������£�����ʹָ����С����ͬʱҲ�кܴ��: 1.��ռ�þ�̬�ռ� 2.�������ü���Ч�ʻ�ܵ�
*/
//
#if _MSC_VER<1400 //VC8
template<typename T>
struct IsClassType
{
static const bool m_value = true;
};
template<typename T>
struct IsClassType<T*>
{
static const bool m_value = false;
};
template<typename T, typename U>
struct IsClassType<T U::*>
{
static const bool m_value = false;
};
template<typename T, int n>
struct IsClassType<T[n]>
{
static const bool m_value = false;
};
template<>
struct IsClassType<int>
{
static const bool m_value = false;
};
template<>
struct IsClassType<double>
{
static const bool m_value = false;
};
template<>
struct IsClassType<char>
{
static const bool m_value = false;
};
template<>
struct IsClassType<float>
{
static const bool m_value = false;
};
template<>
struct IsClassType<__int64>
{
static const bool m_value = false;
};
#ifdef _NATIVE_WCHAR_T_DEFINED
template<>
struct IsClassType<wchar_t>
{
static const bool m_value = false;
};
#endif
template<>
struct IsClassType<long>
{
static const bool m_value = false;
};
template<>
struct IsClassType<short>
{
static const bool m_value = false;
};
template<>
struct IsClassType<unsigned>
{
static const bool m_value = false;
};
template<>
struct IsClassType<long double>
{
static const bool m_value = false;
};
template<>
struct IsClassType<unsigned short>
{
static const bool m_value = false;
};
template<>
struct IsClassType<unsigned __int64>
{
static const bool m_value = false;
};
template<>
struct IsClassType<unsigned long>
{
static const bool m_value = false;
};
#else //������ж��Ƿ���������������������struct(���Dz����ų�����������,����������Ҫ������.�жϳ��������л�ʵ��).
//Ŀǰ�����ж�"�����������̳���û��"������
template<typename T>
struct IsClassType //������֧��enum
{
static const bool m_value = __is_class(T);
};
#endif
template<bool>
struct StaticAssert;
template<>
struct StaticAssert<true>
{
};
//
extern "C"
{
//#ifdef _M_CEE_PURE
// long __clrcall _InterlockedIncrement(volatile long*);
// long __clrcall _InterlockedDecrement(volatile long*);
//#else
// long __stdcall _InterlockedIncrement(volatile long*);
// long __stdcall _InterlockedDecrement(volatile long*);
//#endif
long _InterlockedIncrement(volatile long*);
long _InterlockedDecrement(volatile long*);
}
//���� 2003 DEBUG��������
#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)
inline size_t GetTypeCombineOffset(size_t size, size_t align)
{
size_t remain = size%align;
if(0 == remain)
return size;
else
return size+align-remain;//(1+size/align)*align;
}
inline void* operator new(size_t size, long*& ref, void* (*allocator)(size_t) = operator new, void (*cleaner)(void*)=operator delete)
{
size_t refOffset = GetTypeCombineOffset(size, __alignof(long));
char* head = reinterpret_cast<char*>(allocator(refOffset+sizeof(long)));
ref = reinterpret_cast<long*>(head+refOffset);
*ref = 1;
return head;
}
inline void* operator new(size_t size, long*& ref, size_t alignement, void* (*allocator)(size_t, size_t) = _aligned_malloc, void (*cleaner)(void*)=_aligned_free)
{
size_t refOffset = GetTypeCombineOffset(size, __alignof(long));
char* head = reinterpret_cast<char*>(allocator(refOffset+sizeof(long), alignement));
ref = reinterpret_cast<long*>(head+refOffset);
*ref = 1;
return head;
}
inline void operator delete(void* p, long*& ref, void* (*allocator)(size_t), void (*cleaner)(void*))
{
cleaner(p);
}
inline void operator delete(void* p, long*& ref, size_t alignment, void* (*allocator)(size_t, size_t), void (*cleaner)(void*))
{
cleaner(p);
}
//////////new[]����Ҫ������ͱ���Ļ��ͻ//////////////
inline void* operator new[](size_t size, long*& ref, void* (*allocator)(size_t) = operator new, void (*cleaner)(void*)=operator delete)
{
return operator new(size, ref, allocator, cleaner);
}
inline void operator delete[](void* p, long*& ref, void* (*allocator)(size_t), void (*cleaner)(void*))
{
cleaner(p);
}
enum CommonMem{commonMem};
enum CommonAligned{commonAligned};
inline void* operator new(size_t size, const CommonMem&)
{
return cm::CommonAlloc(unsigned(size));
}
inline void* operator new(size_t size, size_t alignment)
{
return _aligned_malloc(size, alignment);
}
inline void* operator new(size_t size, const CommonAligned&, size_t alignment)
{
return cm::CommonAlignedAlloc(size, alignment);
}
inline void operator delete(void* p, const CommonMem&)
{
cm::CommonFree(p);
}
inline void operator delete(void* p, size_t alignment)
{
_aligned_free(p);
}
inline void operator delete(void* p, const CommonAligned&, size_t alignment)
{
cm::CommonAlignedFree(p);
}
inline void* operator new(size_t size, void (*cleaner)(void*), void* p)
{
return p;
}
inline void operator delete(void* p, void (*cleaner)(void*), void*)
{
cleaner(p);
}
template<typename T>
inline void DelSingle(T& p)
{
::delete p; //���������ã�����֧��delete���ء����֧�֣���Ա��������ȫ�ֺ���ҲҪ����"::"�汾
}
template<typename T>
inline void DelArray(T& p)
{
::delete[] p;
}
/////��������Ȼrefû���õ����������ڹ�����չ���ܿ������ǻ�䶯���ü�����λ��////
template<void (*cleaner)(void*), typename T>
inline void DelEmbedSingleCustom(T*& p, long*)
{
delete reinterpret_cast<CusMem<T, cleaner>*>(p);
}
template<typename T>
inline void DelEmbedSingleCom(T*& p, long* ref)
{
DelEmbedSingleCustom<cm::CommonFree, T>(p, ref);
}
template<typename T>
inline void DelEmbedSingleAligned(T*& p, long* ref)
{
DelEmbedSingleCustom<_aligned_free, T>(p, ref);
}
template<typename T>
inline void DelEmbedSingleComAligned(T*& p, long* ref)
{
DelEmbedSingleCustom<cm::CommonAlignedFree, T>(p, ref);
}
template<void (*cleaner)(void*), typename T>
inline void DelEmbedArrayCustom(T*& p, long*)
{
delete[] reinterpret_cast<CusMem<T, cleaner>*>(p);
}
template<typename T>
inline void DelEmbedArrayCom(T*& p, long* ref)
{
DelEmbedArrayCustom<cm::CommonFree, T>(p, ref);
}
template<typename T>
inline void DelEmbedArrayAligned(T*& p, long* ref)
{
DelEmbedArrayCustom<_aligned_free, T>(p, ref);
}
template<typename T>
inline void DelEmbedArrayComAligned(T*& p, long* ref)
{
DelEmbedArrayCustom<cm::CommonAlignedFree, T>(p, ref);
}
template<typename T>
inline void DelEmbedSingle(T& p, long* ref)
{
::delete p;
}
template<typename T>
inline void DelEmbedArray(T& p, long* ref)
{
::delete[] p;
}
template<typename T>
inline void DelOuterSingle(T& p, long* ref)
{
::delete p;
cm::CommonFree(ref);
}
template<typename T>
inline void DelOuterArray(T& p, long* ref)
{
::delete[] p;
cm::CommonFree(ref);
}
template<typename T>
struct RefData
{
RefData(T* ptr, long* ref): m_ptr(ptr), m_ref(ref)
{
}
T* m_ptr;
long* m_ref;
};
template<typename T>
inline RefData<T> SingleAlloc()
{
long* ref;
T* ptr = ::new(ref) T; //���������ã�����֧��new���ء����֧�֣���Ա��������ȫ�ֺ���ҲҪ����"::"�汾
return RefData<T>(ptr, ref);
}
template<typename T>
inline RefData<T> ArrayAlloc(unsigned int total)
{
long* ref;
T* ptr = ::new(ref) T[total];
return RefData<T>(ptr, ref);
}
////nothing. defined as policy
struct MultiThread;
struct SingleThread;
template<typename ThreadModal> long AddRefCount(long* refCount);
template<typename ThreadModal> long ReleaseRefCount(long* refCount);
template<>
inline long AddRefCount<SingleThread>(long* refCount)
{
return ++*refCount;
}
template<>
inline long ReleaseRefCount<SingleThread>(long* refCount)
{
return --*refCount;
}
template<>
inline long AddRefCount<MultiThread>(long* refCount)
{
#ifndef LINUX_PLATFORM
return _InterlockedIncrement(refCount);
#else
long prev;
__asm__ volatile ("lock; xadd %1, %2"
: "=a" (prev)
: "a" (1), "m" (*refCount)
: "memory" );
return prev+1;
#endif
}
template<>
inline long ReleaseRefCount<MultiThread>(long* refCount)
{
#ifndef LINUX_PLATFORM
return _InterlockedDecrement(refCount);
#else
long prev;
__asm__ volatile ("lock; xadd %1, %2"
: "=a" (prev)
: "a" (-1), "m" (*refCount)
: "memory" );
return prev-1;
#endif
}
template<typename T>
inline void ReleaseSingle(T& p, long* ref) //���ڶ������������
{
p->ReleaseSingle();
}
template<typename T>
inline void ReleaseSingle(T& p) //���ڶ������������
{
p->ReleaseSingle();
}
template<typename T>
inline void ReleaseArray(T& p, long* ref) //���ڶ������������
{
p->ReleaseArray();
}
template<typename T>
inline void ReleaseArray(T& p) //���ڶ������������
{
p->ReleaseArray();
}
template<typename T>
inline void ReleaseOuterSingle(T& p, long* ref) //���ڶ������������
{
p->ReleaseSingle();
cm::CommonFree(ref);
}
template<typename T>
inline void ReleaseOuterArray(T& p, long* ref) //���ڶ������������
{
p->ReleaseArray();
cm::CommonFree(ref);
}
template<typename T, void(*release)(T&, long*), typename ThreadModal = ::MultiThread>
struct RefCtrl
{
template<typename U>
RefCtrl(const U& ptr, long* ref, bool manRef = true):m_ptr(ptr), m_ref(ref)
{
if(manRef && m_ptr)
AddRefCount<ThreadModal>(m_ref);
}
template<typename U>
RefCtrl& Assign(const U& ptr, long* ref, bool manRef = true)
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
m_ptr = ptr;
m_ref = ref;
if(manRef && m_ptr)
AddRefCount<ThreadModal>(m_ref);
return *this;
}
template<typename U>
explicit RefCtrl(const U& ptr): m_ptr(ptr), m_ref(0)
{
if(m_ptr)
m_ref = new(::commonMem) long(1);
}
template<typename U>
RefCtrl& operator=(const U& ptr)
{
if(m_ptr)
{
if(ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
{
*m_ref = 1;
release(m_ptr, 0);
m_ptr = ptr;
}
else
{
m_ptr = ptr;
m_ref = new(::commonMem) long(1);
}
}
else
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
{
release(m_ptr, m_ref);
m_ptr = 0;
}
else
m_ptr = 0;
}
}
else if(ptr)
{
m_ptr = ptr;
m_ref = new(::commonMem) long(1);
}
return *this;
}
template<typename U>
RefCtrl(const RefData<U>& refData): m_ptr(refData.m_ptr),
m_ref(refData.m_ref)
{
}
RefCtrl(): m_ptr(0), m_ref(0)
{
}
RefCtrl(const RefCtrl& ptr): m_ptr(ptr.m_ptr), m_ref(0)
{
if(m_ptr)
{
m_ref = ptr.m_ref;
AddRefCount<ThreadModal>(m_ref);
}
}
template<typename U, void(*re)(U&, long*), typename V>
RefCtrl(const RefCtrl<U, re, V>& ptr): m_ptr(ptr.m_ptr), m_ref(0)
{
if(m_ptr)
{
m_ref = ptr.m_ref;
AddRefCount<ThreadModal>(m_ref);
}
}
#if _MSC_VER>1500 //VC10
template<typename U, void(*re)(U&, long*), typename V>
RefCtrl(RefCtrl<U, re, V>&& ptr): m_ptr(ptr.m_ptr), m_ref(ptr.m_ref)
{
ptr.m_ptr = 0;
}
#endif
RefCtrl& operator=(const RefCtrl& ptr)
{
//���������ü���, ���� �Լ�=�Լ������(a=a)
if(ptr.m_ptr)
AddRefCount<ThreadModal>(ptr.m_ref);
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
m_ptr = ptr.m_ptr;
m_ref = ptr.m_ref;
return *this;
}
template<typename U>
RefCtrl& operator=(const RefData<U>& refData)
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
m_ptr = refData.m_ptr;
m_ref = refData.m_ref;
return *this;
}
template<typename U, void(*re)(U&, long*), typename V>
RefCtrl& operator=(const RefCtrl<U, re, V>& ptr)
{
//���������ü���, ���� �Լ�=�Լ������
if(ptr.m_ptr)
AddRefCount<ThreadModal>(ptr.m_ref);
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
m_ptr = ptr.m_ptr;
m_ref = ptr.m_ref;
return *this;
}
#if _MSC_VER>1500 //VC10
template<typename U, void(*re)(U&, long*), typename V>
RefCtrl& operator=(RefCtrl<U, re, V>&& ptr)
{
U bk = ptr.m_ptr; //�����Լ�=�Լ�
ptr.m_ptr = 0;
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
m_ptr = bk;
m_ref = ptr.m_ref;
return *this;
}
#endif
~RefCtrl()
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
}
}
T& operator->()
{
return m_ptr;
}
operator T&()
{
return m_ptr;
}
void Empty()
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(m_ref))
release(m_ptr, m_ref);
m_ptr = 0;
}
}
long GetRefCount()const
{
return *m_ref;
}
T& GetDataAddRef(long*& ref)
{
if(m_ptr)
{
ref = m_ref;
AddRefCount<ThreadModal>(ref);
}
return m_ptr;
}
T m_ptr;
long* m_ref; //û�������̳н����Ѵ���
};
template<typename T, size_t align>
struct NativeCore
{
NativeCore(T* p, size_t align): m_ptr(p), m_align(align)
{
}
T* m_ptr;
size_t m_align;
};
template<typename T, void (*release)(void*) = operator delete, size_t align = __alignof(T), typename ThreadModal = ::MultiThread>
struct NativeRef
{
NativeRef(): m_ptr(0)
{
//�����Ƿ��Զ�������, ������Ҫ��ʹ������Ĵ�����չ����
//template<>
//struct IsClassType<SomeType>
//{
// static const bool m_value = false;
//};
StaticAssert<!IsClassType<T>::m_value>();
}
NativeRef(const NativeCore<T, align>& ptr): m_ptr(ptr.m_ptr)
{
}
NativeRef(const NativeRef& ptr): m_ptr(ptr.m_ptr)
{
if(m_ptr)
{
AddRefCount<ThreadModal>(GetNativePtr<T, align>(ptr));
}
}
#if _MSC_VER>1500 //VC10
NativeRef(NativeRef&& ptr): m_ptr(ptr.m_ptr)
{
ptr.m_ptr = 0;
}
#endif
NativeRef& operator=(const NativeCore<T, align>& ptr)
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(GetNativePtr<T, align>(m_ptr)))
release(GetNativePtr<T, align>(m_ptr));
}
m_ptr = ptr.m_ptr;
return *this;
}
NativeRef& operator=(const NativeRef& ptr)
{
//���������ü���, ���� �Լ�=�Լ������
if(ptr.m_ptr)
AddRefCount<ThreadModal>(GetNativePtr<T, align>(ptr.m_ptr));
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(GetNativePtr<T, align>(m_ptr)))
release(GetNativePtr<T, align>(m_ptr));
}
m_ptr = ptr.m_ptr;
return *this;
}
#if _MSC_VER>1500 //VC10
NativeRef& operator = (NativeRef&& ptr)
{
T* bk = ptr.m_ptr;
ptr.m_ptr = 0;
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(GetNativePtr<T, align>(m_ptr)))
release(GetNativePtr<T, align>(m_ptr));
}
m_ptr = bk;
return *this;
}
#endif
~NativeRef()
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(GetNativePtr<T, align>(m_ptr)))
release(GetNativePtr<T, align>(m_ptr));
}
}
T* operator->()const
{
return m_ptr;
}
operator T*()const
{
return m_ptr;
}
void Empty()
{
if(m_ptr)
{
if(0 == ReleaseRefCount<ThreadModal>(GetNativePtr<T, align>(m_ptr)))
release(GetNativePtr<T, align>(m_ptr));
m_ptr = 0;
}
}
long GetRefCount()const
{
return *GetNativePtr<T, align>(m_ptr);
}
T* m_ptr;
};
//������Ϊ�����ͷ���ֵʹ��
template<typename T, void (*release)(T&)>
struct ScopeCtrl
{
ScopeCtrl(const T& ptr = 0):m_ptr(ptr)
{
}
#if _MSC_VER>1500 //VC10
template<typename U, void (*release)(U&)>
ScopeCtrl(ScopeCtrl<U, release>&& sp): m_ptr(sp.m_ptr)
{
sp.m_ptr = 0;
}
#endif
//////manage resource manually/////////
T Detach()
{
T oldPtr = m_ptr;
m_ptr = 0;
return oldPtr;
}
void operator =(const T& ptr)
{
release(m_ptr);
m_ptr=ptr;
}
#if _MSC_VER>1500 //VC10
template<typename U, void (*release)(U&)>
ScopeCtrl& operator=(ScopeCtrl<U, release>&& sp)
{
U bk = sp.m_ptr;
sp.m_ptr = 0;
release(m_ptr);
m_ptr = bk;
return *this;
}
#endif
T& operator->()
{
return m_ptr;
}
operator T&()
{
return m_ptr;
}
~ScopeCtrl()
{
release(m_ptr);
}
T m_ptr; //���������Դ
///////////declare/////////////////////
///û�ж��壬��ֹ����
ScopeCtrl(const ScopeCtrl& sp);
private:
ScopeCtrl& operator = (const ScopeCtrl& sp);
template<typename U, void (*release)(U&)>
ScopeCtrl(const ScopeCtrl<U, release>& sp);
template<typename U, void (*release)(U&)>
ScopeCtrl& operator=(const ScopeCtrl<U, release>& sp);
template<typename T, void(*release)(T&, long*), typename ThreadModal>
ScopeCtrl(const RefCtrl<T, release, ThreadModal>&);
template<typename T, void(*release)(T&, long*), typename ThreadModal>
ScopeCtrl& operator = (const RefCtrl<T, release, ThreadModal>&);
template<typename T, void (*release)(void*), size_t align, typename ThreadModal>
ScopeCtrl(const NativeRef<T, release, align, ThreadModal>&);
template<typename T, void (*release)(void*), size_t align, typename ThreadModal>
ScopeCtrl& operator = (const NativeRef<T, release, align, ThreadModal>&);
////////////end declare//////////////////
};
/*����ջ����*/
template<typename T>
inline void Destructor(T* p)
{
p->Destructor();
}
template<typename T>
inline void Constructor(T* p)
{
p->Constructor();
}
template<typename T, void (*ctor)(T*)=Constructor, void (*dtor)(T*) = Destructor>
struct StackMgr
{
StackMgr(): m_p(0)
{
}
StackMgr(void* p): m_p(reinterpret_cast<T*>(p))
{
ctor(m_p);
}
~StackMgr()
{
assert(m_p);
dtor(m_p);
}
void Construct(void* p)
{
assert(0 == m_p);
m_p = reinterpret_cast<T*>(p);
ctor(m_p);
}
void ConstructArray(void* p, unsigned size, unsigned count) //����Ƕ�ά����,count�����±�ij˻�
{
for(unsigned i = 0; i<count; i++)
{
this[i].Construct(reinterpret_cast<char*>(p)+i*size);
}
}
operator T*()const
{
return m_p;
}
T* operator->()const
{
return m_p;
}
T* m_p;
};
#define PLACEMENT_CORE \
void operator delete(void* p)\
{\
cleaner(p);\
}\
\
void operator delete[](void* p)\
{\
cleaner(p);\
}\
void operator delete(void* p, const CommonMem&)\
{\
cleaner(p);\
}\
void operator delete(void* p, size_t alignment)\
{\
cleaner(p);\
}\
void operator delete(void* p, const CommonAligned&, size_t alignment)\
{\
cleaner(p);\
}\
template<typename T, void (*cleaner)(void*), bool isClassType = IsClassType<T>::m_value >
struct CusMem;
template<typename T, void (*cleaner)(void*)>
struct CusMem<T, cleaner, true>: T
{
PLACEMENT_CORE
};
template<typename T, void (*cleaner)(void*)>
struct CusMem<T, cleaner, false>
{
CusMem() //������Ĺ��캯���͵���default
{
}
CusMem(const T& v):m_v(v) //Ϊ��֧�ַ����ʱ���ʼ��
{
}
T m_v;
PLACEMENT_CORE
};
template<typename T, int n, void (*cleaner)(void*)>
struct CusMem<T[n], cleaner, false>
{
T m_v[n];
PLACEMENT_CORE
};
template<void (*cleaner)(void*)>
struct CusMem<void, cleaner, false>
{
PLACEMENT_CORE
};
template<typename T>
struct Mem
{
typedef CusMem<T, cm::CommonFree> Com;
typedef CusMem<T, _aligned_free> Aligned;
typedef CusMem<T, cm::CommonAlignedFree> ComAligned;
};
//
template<void (*cleaner)(void*), typename T>
inline void DelSingleCustom(T*& p)
{
delete reinterpret_cast<CusMem<T, cleaner>*>(p);
}
template<typename T>
inline void DelSingleCom(T*& p)
{
DelSingleCustom<cm::CommonFree, T>(p);
}
template<typename T>
inline void DelSingleAligned(T*& p)
{
DelSingleCustom<_aligned_free, T>(p);
}
template<typename T>
inline void DelSingleComAligned(T*& p)
{
DelSingleCustom<cm::CommonAlignedFree, T>(p);
}
//
template<void (*cleaner)(void*), typename T>
inline void DelOuterSingleCustom(T*& p, long* ref)
{
delete reinterpret_cast<CusMem<T, cleaner>*>(p);
cm::CommonFree(ref);
}
template<typename T>
inline void DelOuterSingleCom(T*& p, long* ref)
{
DelOuterSingleCustom<cm::CommonFree, T>(p, ref);
}
template<typename T>
inline void DelOuterSingleAligned(T*& p, long* ref)
{
DelOuterSingleCustom<_aligned_free, T>(p, ref);
}
template<typename T>
inline void DelOuterSingleComAligned(T*& p, long* ref)
{
DelOuterSingleCustom<cm::CommonAlignedFree, T>(p, ref);
}
//
template<void (*cleaner)(void*), typename T>
inline void DelArrayCustom(T*& p)
{
delete[] reinterpret_cast<CusMem<T, cleaner>*>(p);
}
template<typename T>
inline void DelArrayCom(T*& p)
{
DelArrayCustom<cm::CommonFree, T>(p);
}
template<typename T>
inline void DelArrayAligned(T*& p)
{
DelArrayCustom<_aligned_free, T>(p);
}
template<typename T>
inline void DelArrayComAligned(T*& p)
{
DelArrayCustom<cm::CommonAlignedFree, T>(p);
}
//
template<void (*cleaner)(void*), typename T>
inline void DelOuterArrayCustom(T*& p, long* ref)
{
delete[] reinterpret_cast<CusMem<T, cleaner>*>(p);
cm::CommonFree(ref);
}
template<typename T>
inline void DelOuterArrayCom(T*& p, long* ref)
{
DelOuterArrayCustom<cm::CommonFree, T>(p, ref);
}
template<typename T>
inline void DelOuterArrayAligned(T*& p, long* ref)
{
DelOuterArrayCustom<_aligned_free, T>(p, ref);
}
template<typename T>
inline void DelOuterArrayComAligned(T*& p, long* ref)
{
DelOuterArrayCustom<cm::CommonAlignedFree, T>(p, ref);
}
//��Ƕ��typedef���Ա���ʹ�ú꣬���鲻ʹ�ú�
template<typename T>
struct Single
{
typedef ScopeCtrl<T, ::DelSingle> Scope;
typedef RefCtrl<T, ::DelEmbedSingle> Ref;
typedef RefCtrl<T, ::DelOuterSingle> OutRef;
typedef ScopeCtrl<T, ::ReleaseSingle> IScope;
typedef RefCtrl<T, ::ReleaseSingle> IRef;
typedef RefCtrl<T, ::ReleaseOuterSingle> IOutRef;
};
template<typename T>
struct SingleCom;
template<typename T>
struct SingleCom<T*> //����Ҫƫ�ػ������VC2003����
{
typedef ScopeCtrl<T*, ::DelSingleCom> Scope;
typedef RefCtrl<T*, ::DelEmbedSingleCom> Ref;
typedef RefCtrl<T*, ::DelOuterSingleCom> OutRef;
};
template<typename T>
struct SingleAligned;
template<typename T>
struct SingleAligned<T*>
{
typedef ScopeCtrl<T*, ::DelSingleAligned> Scope;
typedef RefCtrl<T*, ::DelEmbedSingleAligned> Ref;
typedef RefCtrl<T*, ::DelOuterSingleAligned> OutRef;
};
template<typename T>
struct SingleComAligned;
template<typename T>
struct SingleComAligned<T*>
{
typedef ScopeCtrl<T*, ::DelSingleComAligned> Scope;
typedef RefCtrl<T*, ::DelEmbedSingleComAligned> Ref;
typedef RefCtrl<T*, ::DelOuterSingleComAligned> OutRef;
};
template<typename T>
struct Array
{
typedef ScopeCtrl<T, ::DelArray> Scope;
typedef RefCtrl<T, ::DelEmbedArray> Ref;
typedef RefCtrl<T, ::DelOuterArray> OutRef;
typedef ScopeCtrl<T, ::ReleaseArray> IScope;
typedef RefCtrl<T, ::ReleaseArray> IRef;
typedef RefCtrl<T, ::ReleaseOuterArray> IOutRef;
};
template<typename T>
struct ArrayCom;
template<typename T>
struct ArrayCom<T*>
{
typedef ScopeCtrl<T*, ::DelArrayCom> Scope;
typedef RefCtrl<T*, ::DelEmbedArrayCom> Ref;
typedef RefCtrl<T*, ::DelOuterArrayCom> OutRef;
};
template<typename T>
struct ArrayAligned;
template<typename T>
struct ArrayAligned<T*>
{
typedef ScopeCtrl<T*, ::DelArrayAligned> Scope;
typedef RefCtrl<T*, ::DelEmbedArrayAligned> Ref;
typedef RefCtrl<T*, ::DelOuterArrayAligned> OutRef;
};
template<typename T>
struct ArrayComAligned;
template<typename T>
struct ArrayComAligned<T*>
{
typedef ScopeCtrl<T*, ::DelArrayComAligned> Scope;
typedef RefCtrl<T*, ::DelEmbedArrayComAligned> Ref;
typedef RefCtrl<T*, ::DelOuterArrayComAligned> OutRef;
};
template<typename T, size_t alignment = __alignof(T)>
struct RefNative //ʹ��ͨ���ڴ�
{
typedef NativeRef<T, operator delete, alignment> Normal;
typedef NativeRef<T, cm::CommonFree, alignment> Com;
typedef NativeRef<T, _aligned_free, alignment> Aligned;
typedef NativeRef<T, cm::CommonAlignedFree, alignment> ComAligned;
};
//�����������
#define SINGLE_INIT(p, t, init)\
{\
long* ref;\
t* ptr = ::new(ref) t init;\
p = RefData<t >(ptr, ref);\
}\
#define SINGLE_INIT_CUSTOM(p, t, init, allocator, cleaner)\
{\
long* ref;\
t* ptr = reinterpret_cast<t*>(::new(ref, allocator, cleaner) CusMem<t, cleaner> init);/*PlacementDelete�ɼӶ�����캯���������ij�ʼ��*/\
p = RefData<t >(ptr, ref);\
}\
#define SINGLE_INIT_ALIGNED_CUSTOM(p, t, init, alignment, allocator, cleaner)\
{\
long* ref;\
t* ptr = reinterpret_cast<t*>(::new(ref, alignment, allocator, cleaner) CusMem<t, cleaner> init);/*PlacementDelete�ɼӶ�����캯���������ij�ʼ��*/\
p = RefData<t >(ptr, ref);\
}\
#define SINGLE_INIT_COM(p, t, init) SINGLE_INIT_CUSTOM(p, t, init, cm::CommonAlloc, cm::CommonFree)
#define SINGLE_INIT_ALIGNED(p, t, init, alignment) SINGLE_INIT_ALIGNED_CUSTOM(p, t, init, alignment, _aligned_malloc, _aligned_free)
#define SINGLE_INIT_COM_ALIGNED(p, t, init, alignment) SINGLE_INIT_ALIGNED_CUSTOM(p, t, init, alignment, cm::CommonAlignedAlloc, cm::CommonAlignedFree)
#define B_CHECK(index, total) assert((index)>=0 && int(index)<int(total))
//����ͬ�ϣ�û���ú�
template<typename T1, typename T2>
inline void BCheck(const T1& index, const T2& total)
{
assert(index>=0 && index<total);
}
//2005���ϰ汾���Բ��ã�ʹ��abstract�ؼ��ּ���
#define INTERFACE_DECLARE(t) \
private:\
t();\
~t();\
void operator=(const t&)const;\
public:\
t(const t&);
/*�ɴ����������������ջ��ʽ. �������ü�����ֱ�ӷ������ڹ������ޣ����һ����ӵ����ӿڵ������Լ�dll�������û�з���Ĭ�ϵ�����
/*�����Ҫ���ֶ���ӵ���
*/
#define INTERFACE_CREATE(t) \
void _cdecl Constructor();/*�涨��������*/\
void _cdecl Destructor()const;/*�涨��������*/\
static int Size();\
static Single<t*>::IRef Create();\
static Array<t*>::IRef CreateArray(unsigned count);\
void _cdecl ReleaseSingle()const;/*�涨��������*/\
void _cdecl ReleaseArray()const;/*�涨��������*/\
static t* NewSingle();\
static t* NewArray(unsigned int count);
//��ʱʹ�ã��õ�����������������
#define INTERFACE_CREATE_EXPORT(t) \
_declspec(dllexport) void _cdecl Constructor();/*�涨��������*/\
_declspec(dllexport) void _cdecl Destructor()const;/*�涨��������*/\
_declspec(dllexport) static int Size();\
_declspec(dllexport) static Single<t*>::IRef Create();\
_declspec(dllexport) static Array<t*>::IRef CreateArray(unsigned int count);\
_declspec(dllexport) void _cdecl ReleaseSingle()const;/*�涨��������*/\
_declspec(dllexport) void _cdecl ReleaseArray()const;/*�涨��������*/\
_declspec(dllexport) static t* NewSingle();\
_declspec(dllexport) static t* NewArray(unsigned int count);
//��һ�£�����֧�ְѶ������Զ����ڴ���
#define IMPLEMENT_CREATE(t, i) \
Single<t*>::IRef t::Create()\
{\
return reinterpret_cast<RefData<t >&>(SingleAlloc<i >());\
}\
\
void t::ReleaseSingle()const\
{\
const i* p = reinterpret_cast<const i*>(this);\
::delete p;\
}\
\
Array<t*>::IRef t::CreateArray(unsigned int count)\
{\
return reinterpret_cast<RefData<t >&>(ArrayAlloc<i >(count));\
}\
\
void t::ReleaseArray()const\
{\
const i* p = reinterpret_cast<const i*>(this);\
::delete[] p;\
}\
\
int t::Size()\
{\
return sizeof(i);\
}\
\
void t::Constructor()\
{\
::new(this) i;\
}\
\
void t::Destructor()const\
{\
const i* dp = reinterpret_cast<const i*>(this);\
dp->~i();\
}\
t* t::NewSingle()\
{\
return reinterpret_cast<t*>(::new i);\
}\
t* t::NewArray(unsigned int count)\
{\
return reinterpret_cast<t*>(::new i[count]);\
}
//��i�������ֿռ��ʱ�������������Ҫ�����������ֿռ�����ͣ��Ե�����������(������typedefҲ���ƹ�ȥ���겻��)
#define IMPLEMENT_CREATE2(t, i, rit) \
Single<t*>::IRef t::Create()\
{\
return reinterpret_cast<RefData<t >&>(SingleAlloc<i >());\
}\
\
void t::ReleaseSingle()const\
{\
const i* p = reinterpret_cast<const i*>(this);\
::delete p;\
}\
\
Array<t*>::IRef t::CreateArray(unsigned int count)\
{\
return reinterpret_cast<RefData<t >&>(ArrayAlloc<i >(count));\
}\
\
void t::ReleaseArray()const\
{\
const i* p = reinterpret_cast<const i*>(this);\
::delete[] p;\
}\
\
int t::Size()\
{\
return sizeof(i);\
}\
\
void t::Constructor()\
{\
::new(this) i;\
}\
\
void t::Destructor()const\
{\
const i* dp = reinterpret_cast<const i*>(this);\
dp->~rit();\
}\
t* t::NewSingle()\
{\
return reinterpret_cast<t*>(::new i);\
}\
t* t::NewArray(unsigned int count)\
{\
return reinterpret_cast<t*>(::new i[count]);\
}
//�����Զ��������ͷţ�����"�̳�"�ķ�ʽģ��placement delete, �������C++ new/delete�ڲ�"���죬����"����
template<typename T, void*(*allocator)(size_t), void (*cleaner)(void*)>
inline RefData<T> SingleAllocCustom()
{
long* ref;
T* ptr = reinterpret_cast<T*>(::new(ref, allocator, cleaner) CusMem<T, cleaner>);
return RefData<T>(ptr, ref);
}
template<typename T>
inline RefData<T> SingleAllocCom()
{
return SingleAllocCustom<T, cm::CommonAlloc, cm::CommonFree>();
}
template<typename T, void*(*allocator)(size_t, size_t), void (*cleaner)(void*)>
inline RefData<T> SingleAllocAlignedCustom(size_t alignment = __alignof(T))
{
long* ref;
T* ptr = reinterpret_cast<T*>(::new(ref, alignment, allocator, cleaner) CusMem<T, cleaner>);
return RefData<T>(ptr, ref);
}
template<typename T>
inline RefData<T> SingleAllocAligned(size_t alignment = __alignof(T))
{
return SingleAllocAlignedCustom<T, _aligned_malloc, _aligned_free>(alignment);
}
template<typename T>
inline RefData<T> SingleAllocComAligned(size_t alignment = __alignof(T))
{
return SingleAllocAlignedCustom<T, cm::CommonAlignedAlloc, cm::CommonAlignedFree>(alignment);
}
template<typename T, void*(*allocator)(size_t), void (*cleaner)(void*)>
inline RefData<T> ArrayAllocCustom(unsigned int total)
{
long* ref;
T* ptr = reinterpret_cast<T*>(::new(ref, allocator, cleaner) CusMem<T, cleaner>[total]);
return RefData<T>(ptr, ref);
}
template<typename T>
inline RefData<T> ArrayAllocCom(unsigned int total)
{
return ArrayAllocCustom<T, cm::CommonAlloc, cm::CommonFree>(total);
}
template<typename T, void*(*allocator)(size_t, size_t), void (*cleaner)(void*)>
inline RefData<T> ArrayAllocAlignedCustom(unsigned int total, size_t alignment = __alignof(T))
{
long* ref;
T* ptr = reinterpret_cast<T*>(::new(ref, alignment, allocator, cleaner) CusMem<T, cleaner>[total]);
return RefData<T>(ptr, ref);
}
template<typename T>
inline RefData<T> ArrayAllocAligned(unsigned int total, size_t alignment = __alignof(T))
{
return ArrayAllocAlignedCustom<T, _aligned_malloc, _aligned_free>(total, alignment);
}
template<typename T>
inline RefData<T> ArrayAllocComAligned(unsigned int total, size_t alignment = __alignof(T))
{
return ArrayAllocAlignedCustom<T, cm::CommonAlignedAlloc, cm::CommonAlignedFree>(total, alignment);
}
template<typename T, size_t align>
inline long* GetNativePtr(T* p)
{
size_t remain = sizeof(long)%align;
if(0 == remain)
{
return reinterpret_cast<long*>(p)-1;
}
else
{
return reinterpret_cast<long*>(reinterpret_cast<char*>(p)-sizeof(long)-(align-remain));
}
}
template<typename T, void*(*allocator)(size_t), void(*cleaner)(void*), size_t align>
inline NativeCore<T, align> NativeAllocMemOnly(size_t total)
{
size_t remain = sizeof(long)%align;
if(0 == remain)
{
long* p = reinterpret_cast<long*>(allocator(sizeof(T)*total + sizeof(long)));
*p = 1;
::new(cleaner, p+1) T[total]; //���ù��캯��
return NativeCore<T, align>(reinterpret_cast<T*>(p+1), align);
}
else
{
char* p = reinterpret_cast<char*>(allocator(sizeof(T)*total + sizeof(long) + align - remain));
*reinterpret_cast<long*>(p) = 1;
::new(cleaner, p+sizeof(long) + align - remain) T[total]; //���ù��캯��
return NativeCore<T, align>(reinterpret_cast<T*>(p+sizeof(long) + align - remain), align);
}
}
template<typename T, void*(*allocator)(size_t, size_t), void(*cleaner)(void*), size_t align>
inline NativeCore<T, align> NativeAllocAlignedMemOnly(size_t total, size_t heapAlignment)
{
size_t remain = sizeof(long)%align;
if(0 == remain)
{
long* p = reinterpret_cast<long*>(allocator(sizeof(T)*total + sizeof(long), heapAlignment));
*p = 1;
::new(cleaner, p+1) T[total]; //���ù��캯��
return NativeCore<T, align>(reinterpret_cast<T*>(p+1), align);
}
else
{
char* p = reinterpret_cast<char*>(allocator(sizeof(T)*total + sizeof(long) + align - remain, heapAlignment));
*reinterpret_cast<long*>(p) = 1;
::new(cleaner, p+sizeof(long) + align - remain) T[total]; //���ù��캯��
return NativeCore<T, align>(reinterpret_cast<T*>(p+sizeof(long) + align - remain), align);
}
}
template<typename T, void*(*allocator)(size_t), void(*cleaner)(void*), size_t alignment>
inline NativeCore<T, alignment> NativeAllocCustom(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, allocator, cleaner, alignment>(total);
}
template<typename T, void*(*allocator)(size_t), void(*cleaner)(void*)>
inline NativeCore<T, __alignof(T)> NativeAllocCustom(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, allocator, cleaner, __alignof(T)>(total);
}
template<typename T, void*(*allocator)(size_t, size_t), void(*cleaner)(void*), size_t alignment>
inline NativeCore<T, alignment> NativeAllocAlignedCustom(size_t total, size_t heapAlignment)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, allocator, cleaner, alignment>(total, heapAlignment);
}
template<typename T, void*(*allocator)(size_t, size_t), void(*cleaner)(void*)>
inline NativeCore<T, __alignof(T)> NativeAllocAlignedCustom(size_t total, size_t heapAlignment)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, allocator, cleaner, __alignof(T)>(total, heapAlignment);
}
template<typename T, size_t alignment>
inline NativeCore<T, alignment> NativeAlloc(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, operator new, operator delete, alignment>(total);
}
template<typename T>
inline NativeCore<T, __alignof(T)> NativeAlloc(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, operator new, operator delete, __alignof(T)>(total);
}
template<typename T, size_t alignment>
inline NativeCore<T, alignment> NativeAllocCom(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, cm::CommonAlloc, cm::CommonFree, alignment>(total);
}
template<typename T>
inline NativeCore<T, __alignof(T)> NativeAllocCom(size_t total)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocMemOnly<T, cm::CommonAlloc, cm::CommonFree, __alignof(T)>(total);
}
template<typename T, size_t alignment>
inline NativeCore<T, alignment> NativeAllocAligned(size_t total, size_t heapAlignment = alignment)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, _aligned_malloc, _aligned_free, alignment>(total, heapAlignment);
}
template<typename T>
inline NativeCore<T, __alignof(T)> NativeAllocAligned(size_t total, size_t heapAlignment = __alignof(T))
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, _aligned_malloc, _aligned_free, __alignof(T)>(total, heapAlignment);
}
template<typename T, size_t alignment>
inline NativeCore<T, alignment> NativeAllocComAligned(size_t total, size_t heapAlignment)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, cm::CommonAlignedAlloc, cm::CommonAlignedFree, alignment>(total, heapAlignment);
}
template<typename T>
inline NativeCore<T, __alignof(T)> NativeAllocComAligned(size_t total, size_t heapAlignment)
{
StaticAssert<!IsClassType<T>::m_value>(); //ֻ����buildin����
return NativeAllocAlignedMemOnly<T, cm::CommonAlignedAlloc, cm::CommonAlignedFree, __alignof(T)>(total, heapAlignment);
}
#ifdef __cplusplus_cli
/*����������Ϊ�й����ͳ�Ա
/*�����������ǿת���Գ���������д���
/* ref obj;
/* pin_ptr<NativeMgr<Native>> p = &obj.gg;
/* *reinterpret_cast<SingleRef(Native*)*>(p) = SingleAlloc<Native>();
*/
template<typename T>
value struct NativeMgr
{
T* m_p;
long* m_ref;
};
#endif