
/*!
@author d金魚
@since 2005/01/28
@note

*/
#ifndef DKUTIL_DKTL_ALIGNED_ALLOCATOR_HPP
#define DKUTIL_DKTL_ALIGNED_ALLOCATOR_HPP


#include <dkutil/dktl/allocator.hpp>
#include <dkutil_cstd/malloc.h>

namespace dkutil{


/**
つくりかけ
*/
template <class T,size_t ALIGN__ = 64> 
class aligned_allocator{
public:
	BOOST_STATIC_CONSTANT(size_t,memory_align = ALIGN__);
	BOOST_STATIC_CONSTANT(size_t,block_rest = memory_align % sizeof(T));
	BOOST_STATIC_ASSERT(block_rest == 0);

  template <class U>
		struct rebind { typedef aligned_allocator<U> other; };
	
	pointer       address(reference x) const
    { return &x; }
  const_pointer address(const_reference x) const
    { return &x; }
  pointer       allocate(size_type n, const void* hint = 0) {
    //cout << "allocate " << n << " of " << typeid(T).name() << endl;
    //return a.allocate(n * sizeof(value_type));//new(n * sizeof(value_type));
		
		//dkutil_allocator_base
		return _Allocate(n, ( pointer ) 0 );
		
	}
  void deallocate(pointer p, size_type n = 0) {
    //cout << "deallocate " << n << " of " << typeid(T).name() << endl;
    //if( (p == 0) == (n == 0) ) MB("WHAT!!! deallocate error");
		if(p==NULL){
			
			//DEBUGASSERT(!DKUTIL_BAKAMON);
			//DEBUGMB("WHAT!!! deallocate error please break.!!");
		}
		_Deallocate(p);
    //a.deallocate(p);
  }
  size_type max_size() const
    { return (size_t)-1 / sizeof(T); }
  void construct(pointer p, const T& val) {
    //cout << "construct " << typeid(T).name()<< '(' << val << ')' << endl;
    new ((void*)p) T(val);
  }
  void destroy(pointer p) {
   // cout << "destroy " << typeid(T).name() << endl;
		((T*)p)->~T();
  }


	//STLPort用

	///私の環境ではSTLPort4.5.3ではこれが必要です。
	template <class _Tp1, class _Tp2>
		inline aligned_allocator<_Tp2>& __stl_alloc_rebind(aligned_allocator<_Tp1>& __a, const _Tp2*) 
	{
		return (aligned_allocator<_Tp2>&)(__a);
	}
	///STLPortではこれも必要だと思います。
	template <class _Tp1, class _Tp2>
	inline aligned_allocator<_Tp2> __stl_alloc_create(
			const aligned_allocator<_Tp1>&, const _Tp2*
	){ 
		return aligned_allocator<_Tp2>(); 
	}


};



}//end of dkutil namespace

#undef DKUTIL_BAKAMON 

#endif//end of include once