Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version
Go to top

Ideas from a smart pointer(part 2). size == sizeof(std::shared_ptr)/2

, 3 Jun 2012
embedded ref-counted resource management
/*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

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

weibing

China China
No Biography provided

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 3 Jun 2012
Article Copyright 2012 by weibing
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid