#ifndef __ALLOCATOR_AMV
	#define __ALLOCATOR_AMV

#include "exception.h"
#include <new>
#include <limits>

namespace amv	{

template <class type>
class allocator	{
	public:
		typedef size_t size_type;
		typedef ptrdiff_t difference_type;
		typedef type *pointer;
		typedef const type *const_pointer;
		typedef type &reference;
		typedef const type &const_reference;
		typedef type value_type;

		pointer address(reference sourceObject) const;
		const_pointer address(const_reference sourceObject) const;
		pointer allocate(size_type n, const void *hint=0);
		void deallocate(void *p, size_type n=0);
		void construct(pointer p, const_reference sourceObject);
		void destroy(pointer p);
		void destroy(pointer p, size_type n);
		void *allocateBytes(size_type n);
		size_type max_size() const;

};

template <class type>
inline allocator<type>::pointer allocator<type>::address(reference sourceObject) const
{
return &sourceObject;
}

template <class type>
inline allocator<type>::const_pointer allocator<type>::address(const_reference sourceObject) const
{
return &sourceObject;
}

template <class type>
inline allocator<type>::pointer allocator<type>::allocate(size_type n, const void *hint)
{
type *p=static_cast<type *>(::operator new(n*sizeof(type)));
if(p)
	return p;
else
	throw bad_alloc();
}

template <class type>
inline void allocator<type>::deallocate(void *p, size_type n)
{
::operator delete(p);
}

template <class type>
inline void allocator<type>::construct(pointer p, const_reference sourceObject)
{
new (p) type(sourceObject);
}

template <class type>
inline void allocator<type>::destroy(pointer p)
{
p->~type();
}

template <class type>
inline void allocator<type>::destroy(pointer p, size_type n)
{
type *pEnd=p+n, *pTemp=p;
while(pTemp!=pEnd)
	{
	pTemp->~type();
	++pTemp;
	}
}

template <class type>
inline void *allocator<type>::allocateBytes(size_type n)
{
void *p=(::operator new(n));
if(p)
	return p;
else
	throw bad_alloc();
}

template <class type>
inline allocator<type>::size_type allocator<type>::max_size() const
{
size_type n=std::numeric_limits<int>::max()/sizeof(type);
return (n>0? n: 1);
}

}

#endif