// xmemory internal header (from <memory>)
#pragma once
#ifndef _XMEMORY_
#define _XMEMORY_
#ifndef RC_INVOKED
#include <cstdlib>
#include <new>
#include <xutility>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)

 #define _ALLOCATOR	allocator

 #pragma push_macro("new")
 #undef new

 #pragma warning(disable: 4100)

#ifndef _FARQ	/* specify standard memory model */
 #define _FARQ
 #define _PDFT	ptrdiff_t
 #define _SIZT	size_t
#endif /* _FARQ */

_STD_BEGIN
		// TEMPLATE FUNCTION _Allocate
template<class _Ty> inline
	_Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
	{	// allocate storage for _Count elements of type _Ty
	void *_Ptr = 0;

	if (_Count <= 0)
		_Count = 0;
	else if (((_SIZT)(-1) / sizeof (_Ty) < _Count)
		|| (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0)
		_THROW_NCEE(bad_alloc, 0);

	return ((_Ty _FARQ *)_Ptr);
	}

		// TEMPLATE FUNCTION _Construct
template<class _Ty1,
	class _Ty2> inline
	void _Construct(_Ty1 _FARQ *_Ptr, _Ty2&& _Val)
	{	// construct object at _Ptr with value _Val
	void _FARQ *_Vptr = _Ptr;
	::new (_Vptr) _Ty1(_STD forward<_Ty2>(_Val));
	}

template<class _Ty1> inline
	void _Construct(_Ty1 _FARQ *_Ptr)
	{	// construct object at _Ptr with default value
	void _FARQ *_Vptr = _Ptr;

	::new (_Vptr) _Ty1();
	}

		// TEMPLATE FUNCTION _Destroy
template<class _Ty> inline
	void _Destroy(_Ty _FARQ *_Ptr)
	{	// destroy object at _Ptr
	_Ptr->~_Ty();
	}

template<> inline
	void _Destroy(char _FARQ *)
	{	// destroy a char (do nothing)
	}

template<> inline
	void _Destroy(wchar_t _FARQ *)
	{	// destroy a wchar_t (do nothing)
	}

 #ifdef _NATIVE_WCHAR_T_DEFINED
template<> inline
	void _Destroy(unsigned short _FARQ *)
	{	// destroy a unsigned short (do nothing)
	}
 #endif /* _NATIVE_WCHAR_T_DEFINED */

		// TEMPLATE FUNCTION _Destroy_range
template<class _Alloc> inline
	void _Destroy_range(typename _Alloc::pointer _First,
		typename _Alloc::pointer _Last, _Alloc& _Al)
	{	// destroy [_First, _Last)
	_Destroy_range(_First, _Last, _Al, _Ptr_cat(_First, _Last));
	}

template<class _Alloc> inline
	void _Destroy_range(typename _Alloc::pointer _First,
		typename _Alloc::pointer _Last, _Alloc& _Al,
		_Nonscalar_ptr_iterator_tag)
	{	// destroy [_First, _Last), arbitrary type
	for (; _First != _Last; ++_First)
		_Dest_val(_Al, _First);
	}

template<class _Alloc> inline
	void _Destroy_range(typename _Alloc::pointer _First,
		typename _Alloc::pointer _Last, _Alloc& _Al,
		_Scalar_ptr_iterator_tag)
	{	// destroy [_First, _Last), scalar type (do nothing)
	}

		// TEMPLATE FUNCTION addressof
template<class _Ty> inline
	_Ty * addressof(_Ty& _Val)
	{	// return address of _Val
	return ((_Ty *) &(char&)_Val);
	}

		// TEMPLATE CLASS _Allocator_base
template<class _Ty>
	struct _Allocator_base
	{	// base class for generic allocators
	typedef _Ty value_type;
	};

		// TEMPLATE CLASS _Allocator_base<const _Ty>
template<class _Ty>
	struct _Allocator_base<const _Ty>
	{	// base class for generic allocators for const _Ty
	typedef _Ty value_type;
	};

		// TEMPLATE CLASS _ALLOCATOR
template<class _Ty>
	class _ALLOCATOR
		: public _Allocator_base<_Ty>
	{	// generic allocator for objects of class _Ty
public:
	typedef _Allocator_base<_Ty> _Mybase;
	typedef typename _Mybase::value_type value_type;

	typedef value_type _FARQ *pointer;
	typedef value_type _FARQ& reference;
	typedef const value_type _FARQ *const_pointer;
	typedef const value_type _FARQ& const_reference;

	typedef _SIZT size_type;
	typedef _PDFT difference_type;

	template<class _Other>
		struct rebind
		{	// convert this type to _ALLOCATOR<_Other>
		typedef _ALLOCATOR<_Other> other;
		};

	pointer address(reference _Val) const
		{	// return address of mutable _Val
		return ((pointer) &(char&)_Val);
		}

	const_pointer address(const_reference _Val) const
		{	// return address of nonmutable _Val
		return ((const_pointer) &(char&)_Val);
		}

	_ALLOCATOR() _THROW0()
		{	// construct default allocator (do nothing)
		}

	_ALLOCATOR(const _ALLOCATOR<_Ty>&) _THROW0()
		{	// construct by copying (do nothing)
		}

	template<class _Other>
		_ALLOCATOR(const _ALLOCATOR<_Other>&) _THROW0()
		{	// construct from a related allocator (do nothing)
		}

	template<class _Other>
		_ALLOCATOR<_Ty>& operator=(const _ALLOCATOR<_Other>&)
		{	// assign from a related allocator (do nothing)
		return (*this);
		}

	void deallocate(pointer _Ptr, size_type)
		{	// deallocate object at _Ptr, ignore size
		::operator delete(_Ptr);
		}

	pointer allocate(size_type _Count)
		{	// allocate array of _Count elements
		return (_Allocate(_Count, (pointer)0));
		}

	pointer allocate(size_type _Count, const void _FARQ *)
		{	// allocate array of _Count elements, ignore hint
		return (allocate(_Count));
		}

	void construct(pointer _Ptr, const _Ty& _Val)
		{	// construct object at _Ptr with value _Val
		_Construct(_Ptr, _Val);
		}

	void construct(pointer _Ptr, _Ty&& _Val)
		{	// construct object at _Ptr with value _Val
		::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val));
		}

	template<class _Other>
		void construct(pointer _Ptr, _Other&& _Val)
		{	// construct object at _Ptr with value _Val
		::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Other>(_Val));
		}

	void destroy(pointer _Ptr)
		{	// destroy object at _Ptr
		_Destroy(_Ptr);
		}

	_SIZT max_size() const _THROW0()
		{	// estimate maximum array size
		_SIZT _Count = (_SIZT)(-1) / sizeof (_Ty);
		return (0 < _Count ? _Count : 1);
		}
	};

		// CLASS _ALLOCATOR<void>
template<> class _ALLOCATOR<void>
	{	// generic _ALLOCATOR for type void
public:
	typedef void _Ty;
	typedef _Ty _FARQ *pointer;
	typedef const _Ty _FARQ *const_pointer;
	typedef _Ty value_type;

	template<class _Other>
		struct rebind
		{	// convert this type to an _ALLOCATOR<_Other>
		typedef _ALLOCATOR<_Other> other;
		};

	_ALLOCATOR() _THROW0()
		{	// construct default allocator (do nothing)
		}

	_ALLOCATOR(const _ALLOCATOR<_Ty>&) _THROW0()
		{	// construct by copying (do nothing)
		}

	template<class _Other>
		_ALLOCATOR(const _ALLOCATOR<_Other>&) _THROW0()
		{	// construct from related allocator (do nothing)
		}

	template<class _Other>
		_ALLOCATOR<_Ty>& operator=(const _ALLOCATOR<_Other>&)
		{	// assign from a related allocator (do nothing)
		return (*this);
		}
	};

template<class _Ty,
	class _Other> inline
	bool operator==(const allocator<_Ty>&,
		const allocator<_Other>&) _THROW0()
	{	// test for allocator equality
	return (true);
	}

template<class _Ty,
	class _Other> inline
	bool operator!=(const allocator<_Ty>& _Left,
		const allocator<_Other>& _Right) _THROW0()
	{	// test for allocator inequality
	return (!(_Left == _Right));
	}

		// TEMPLATE FUNCTIONS _Cons_val AND _Dest_val
template<class _Alloc,
	class _Ty1,
	class _Ty2>
	void _Cons_val(_Alloc& _Alval, _Ty1 *_Pdest, _Ty2&& _Src)
	{	// construct using allocator
	_Alval.construct(_Pdest, _STD forward<_Ty2>(_Src));
	}

template<class _Alloc,
	class _Ty1>
	void _Dest_val(_Alloc& _Alval, _Ty1 *_Pdest)
	{	// destroy using allocator
	_Alval.destroy(_Pdest);
	}
_STD_END

 #pragma pop_macro("new")

 #pragma warning(pop)
 #pragma pack(pop)

#endif /* RC_INVOKED */
#endif /* _XMEMORY_ */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 */

/*
 * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V5.20:0009 */
