
#ifndef DKUTIL_POLICY_ALLOCATE_HPP
#define DKUTIL_POLICY_ALLOCATE_HPP

#include <dkutil/config.hpp>
#include <dkutil/macro.hpp>
#include <malloc.h>
#ifdef WIN32
#	include <windows.h>
#else

#endif

namespace dkutil{


//ゴメ〜ン。ちとundefさせてもらいmath.
/*#ifdef malloc
#	undef malloc
#endif

#ifdef free
#	undef free
#endif

#ifdef realloc
#	undef realloc
#endif
*/

namespace policy{



struct allocate_policy_malloc{
	typedef allocate_policy_malloc self_type;

	static inline void *malloc(const size_t bytes)
	//void * malloc(const size_t bytes)const
  { 
		void *p = DKUTIL_SAFE_MALLOC(bytes);//::malloc(bytes); 
		if(!p) return NULL;
		memset(p,0,bytes);
		return p; 
	}
	static inline void free(void * block)
	//void free(void * block)const
  { 
		DKUTIL_SAFE_FREE(block);
		//if(block){		free(block);}
	}
	static inline void *realloc(void *block,size_t size){
	//void *realloc(void *block,size_t size)const{
		return (void *)DKUTIL_SAFE_REALLOC(block,size);
		//return (void *)realloc(block,size);
	}
	/*void *operator new(size_t size,self_type x)
	{
		return malloc(size);
	}
	void operator delete(void *p,self_type x){
		free(p);
	}
	void *New(size_t size)const{
		return new self_type(self_type());
	}
	void Delete(void * block){
		delete(self_type()) block;
	}*/
};

struct allocate_policy_malloc_uninitialize_block{
	typedef allocate_policy_malloc_uninitialize_block self_type;
	static inline void *malloc(size_t bytes)
  { 
		return DKUTIL_SAFE_MALLOC(bytes); 
		//return malloc(bytes);
	}
	
	static inline void free(void * block)
  { 
		DKUTIL_SAFE_FREE(block);
		//if(block){	free(block);}
	}
	static inline void *realloc(void *block,size_t size)
	{
		return (void *)DKUTIL_SAFE_REALLOC(block,size);
		//return (void *)realloc(block,size);
	}

};
#ifdef WIN32

struct allocate_policy_globalalloc{
	void * malloc(const size_t bytes)const
  { return ::GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,bytes); }

	void free(void * block)const
  { 
		if(block){
			::GlobalFree(block);
		}
	}
	void *realloc(void *block,size_t size)const{
		if(block){
			return (void *)::GlobalReAlloc(block,size,NULL);//わからないから第三引数はNULLで^^；
		}else{
			return malloc(size);
		}
	}

};
#endif
#if 0 



//タブン、もう使わない。でも載せておく。DxExで使うかも？
///< アライメントマクロ
#define ALIGNED(N1,N2)			(((N1)+((N2)-1))&(~((N2)-1)))	


struct allocate_policy_virtualalloc{
	///< VirtuakAllocメモリ確保
	void * malloc(const size_t Size)const
  {
		void *pData = ::VirtualAlloc( NULL, ALIGNED(Size,4096), MEM_COMMIT, PAGE_READWRITE );
		::FillMemory(pData,Size,0x00)
		return pData;
	}
	///< VirtualAllocメモリ開放
	void free(void * P)const
  { 
		if ( (P) != NULL ) {
			::VirtualFree( (P), 0, MEM_RELEASE ); (P) = NULL; 
		}	

	}
/*	void *realloc(void *block,size_t size)const{
		if(block){
			return (void *)::GlobalReAlloc(block,size,NULL);//わからないから第三引数はNULLで^^；
		}else{
			return malloc(size);
		}
	}
*/
};
#undef ALIGNED

#endif

/*!
インターフェイスが大量にあって御免。互換性のためなんだ。
*/
	#if 0
///密かにyaneSDK3rdのyaneAllocator.hのアロケーターインターフェイスと互換性あり^^;(だと思う･･･)
template<class IMPL>
class AllocatorInterface{
public:
	typedef std::size_t size_type;
  typedef std::ptrdiff_t difference_type;
private:
	IMPL ma;
public:
	/*///@return 0に初期化したメモリ領域へのポインタを返す
	BYTE *Alloc(int size)const{
		return ma.malloc(size);
	}
	///GlobalFreeを使用してAlloc()で確保したメモリ領域を開放する
	void Free(BYTE *pb)const{
		ma.free(pb);
	}
	BYTE* ReAlloc(BYTE *ptr,int size)const{
		return (BYTE *)ma.realloc(ptr,size);
	}

	///@return 0に初期化したメモリ領域へのポインタを返す Alloc()と同じ
	char * malloc(const size_type bytes)const
  { return (char *)ma.malloc(bytes); }
  ///mallocで確保したものを開放する Free()と同じ。
	void free(char * const block)const
  { ma.free(block); }

	char *realloc(char *block,size_type size)const{
		return (char *)ma.realloc((void *)block,size);
	}*/
		///@return 0に初期化したメモリ領域へのポインタを返す
	static BYTE *Alloc(int size){
		return ma.malloc(size);
	}
	///GlobalFreeを使用してAlloc()で確保したメモリ領域を開放する
	static void Free(BYTE *pb){
		ma.free(pb);
	}
	static BYTE* ReAlloc(BYTE *ptr,int size){
		return (BYTE *)ma.realloc(ptr,size);
	}

	///@return 0に初期化したメモリ領域へのポインタを返す Alloc()と同じ
	static char * malloc(const size_type bytes)
  { 
		return (char *)ma.malloc(bytes); 
	}
  ///mallocで確保したものを開放する Free()と同じ。
	static void free(char * const block)
  {
		ma.free(block); 
	}

	static char *realloc(char *block,size_type size){
		return (char *)ma.realloc((void *)block,size);
	}
};


typedef AllocatorInterface<allocate_policy_globalalloc> globalalloc_allocator;
typedef AllocatorInterface<allocate_policy_malloc> malloc_allocator; 
#endif

/*

class default_reference_allocator : public reference_allocator_interface{
	allocate_policy_malloc mA;
public:
	default_reference_allocator(){
	}
	///Main側のNewを使う
	virtual void *New(size_t s)const{
		return new BYTE[s];
		}
	///Main側のDeleteを使う
	virtual void Delete(void *p)const{
		delete [] (BYTE *)p;
	}
	///Main側のmalloc(系)を使う
	virtual void *Allocate(size_t size)const{
		return mA.malloc(size);
		}

	///Main側のfree(系)を使う
	virtual void Free(void *p)const {
		mA.free(p);
		}
	///Main側のrealloc(系)を使う
	virtual void *Reallocate(void *p,size_t size)const {
		return mA.realloc(p,size);
		}
};*/

}//end of policy namespace

}//end of dkutil namespace



#endif
