// memory standard header
#ifndef _MEMORY_
#define _MEMORY_
#include <use_ansi.h>
#include <xmemory>

#ifdef  _MSC_VER
/*
 * Currently, all MS C compilers for Win32 platforms default to 8 byte
 * alignment.
 */
#pragma pack(push,8)
#endif  /* _MSC_VER */

		// TEMPLATE OPERATOR new
template<class _TYPE>
	inline void *operator new(size_t _N, ::allocator<_TYPE>& _Al)
	{return (_ALLOCATE_X(char,
		allocator<_TYPE>::rebind<char>::other(), _Al, _N)); }
		// TEMPLATE FUNCTION get_temporary_buffer
template<class _TYPE> inline
	pair<_TYPE _FARQ *, _PDFT>
		get_temporary_buffer(_PDFT _N, _TYPE _FARQ *)
	{_TYPE _FARQ *_P;
	for (_P = 0; 0 < _N; _N /= 2)
		if ((_P = (_TYPE _FARQ *)operator new(
			(_SIZT)_N * sizeof (_TYPE), nothrow)) != 0)
			break;
	return (pair<_TYPE _FARQ *, _PDFT>(_P, _N)); }
		// TEMPLATE FUNCTION return_temporary_buffer
template<class _TYPE> inline
	void return_temporary_buffer(_TYPE *_P)
	{operator delete(_P); }
		// TEMPLATE FUNCTION uninitialized_copy
template<class _II, class _FI> inline
	_FI uninitialized_copy(_II _F, _II _L, _FI _X)
	{for (; _F != _L; ++_X, ++_F)
		_Construct(&*_X, *_F);
	return (_X); }
		// TEMPLATE FUNCTION uninitialized_fill
template<class _FI, class _TYPE> inline
	void uninitialized_fill(_FI _F, _FI _L, const _TYPE& _X)
	{for (; _F != _L; ++_F)
		_Construct(&*_F, _X); }
		// TEMPLATE FUNCTION uninitialized_fill_n
template<class _FI, class _S, class _TYPE> inline
	void uninitialized_fill_n(_FI _F, _S _N, const _TYPE& _X)
	{for (; 0 < _N; --_N, ++_F)
		_Construct(&*_F, _X); }
		// TEMPLATE CLASS raw_storage_iterator
template<class _OI, class _TYPE>
	class raw_storage_iterator
		: public iterator<output_iterator_tag, void, void> {
public:
	typedef _OI iterator_type;
	typedef _TYPE element_type;
	explicit raw_storage_iterator(_OI _X)
		: _Next(_X) {}
	raw_storage_iterator<_OI, _TYPE>& operator*()
		{return (*this); }
	raw_storage_iterator<_OI, _TYPE>& operator=(const _TYPE& _X)
		{_Construct(&*_Next, _X);
		return (*this); }
	raw_storage_iterator<_OI, _TYPE>& operator++()
		{++_Next;
		return (*this); }
	raw_storage_iterator<_OI, _TYPE> operator++(int)
		{raw_storage_iterator<_OI, _TYPE> _Ans = *this;
		++_Next;
		return (_Ans); }
private:
	_OI _Next;
	};
		// TEMPLATE CLASS _Temp_iterator
template<class _TYPE>
	class _Temp_iterator
		: public iterator<output_iterator_tag, void, void> {
	typedef _TYPE _FARQ *_Pty;
public:
	_Temp_iterator(_PDFT _N = 0)
		{pair<_Pty, _PDFT> _Pair =
			get_temporary_buffer(_N, (_Pty)0);
		_Buf._Begin = _Pair.first;
		_Buf._Cur = _Pair.first;
		_Buf._Hiwater = _Pair.first;
		_Buf._Len = _Pair.second;
		_Pb = &_Buf; }
	_Temp_iterator(const _Temp_iterator<_TYPE>& _X)
		{_Buf._Begin = 0;
		_Buf._Cur = 0;
		_Buf._Hiwater = 0;
		_Buf._Len = 0;
		*this = _X; }
	~_Temp_iterator()
		{if (_Buf._Begin != 0)
			{for (_Pty _F = _Buf._Begin;
				_F != _Buf._Hiwater; ++_F)
				_Destroy(&*_F);
			return_temporary_buffer(_Buf._Begin); }}
	_Temp_iterator<_TYPE>& operator=(const _Temp_iterator<_TYPE>& _X)
		{_Pb = _X._Pb;
		return (*this); }
	_Temp_iterator<_TYPE>& operator=(const _TYPE& _V)
		{if (_Pb->_Cur < _Pb->_Hiwater)
			*_Pb->_Cur++ = _V;
		else
			{_Construct(&*_Pb->_Cur, _V);
			_Pb->_Hiwater = ++_Pb->_Cur; }
		return (*this); }
	_Temp_iterator<_TYPE>& operator*()
		{return (*this); }
	_Temp_iterator<_TYPE>& operator++()
		{return (*this); }
	_Temp_iterator<_TYPE>& operator++(int)
		{return (*this); }
	_Temp_iterator<_TYPE>& _Init()
		{_Pb->_Cur = _Pb->_Begin;
		return (*this); }
	_Pty _First() const
		{return (_Pb->_Begin); }
	_Pty _Last() const
		{return (_Pb->_Cur); }
	_PDFT _Maxlen() const
		{return (_Pb->_Len); }
private:
	struct _Bufpar {
		_Pty _Begin;
		_Pty _Cur;
		_Pty _Hiwater;
		_PDFT _Len;
		} _Buf, *_Pb;
	};
		// TEMPLATE CLASS auto_ptr
template<class _TYPE>
	class auto_ptr {
public:
	typedef _TYPE element_type;
	explicit auto_ptr(_TYPE *_P = 0)
		: _Owns(_P != 0), _Ptr(_P) {}
	typedef _TYPE _U;
	auto_ptr(const auto_ptr<_U>& _Y)
		: _Owns(_Y._Owns), _Ptr((_TYPE *)_Y.release()) {}
	auto_ptr<_TYPE>& operator=(const auto_ptr<_U>& _Y)
		{if ((void *)this != (void *)&_Y)
			{if (_Owns)
				delete _Ptr;
			_Owns = _Y._Owns;
			_Ptr = (_TYPE *)_Y.release(); }
		return (*this); }
	~auto_ptr()
		{if (_Owns)
			delete _Ptr; }
	_TYPE& operator*() const
		{return (*get()); }
	_TYPE *operator->() const
		{return (get()); }
	_TYPE *get() const
		{return (_Ptr); }
	_TYPE *release() const
		{((auto_ptr<_TYPE> *)this)->_Owns = false;
		return (_Ptr); }
private:
	bool _Owns;
	_TYPE *_Ptr;
	};

#ifdef  _MSC_VER
#pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* _MEMORY_ */

/*
 * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED. 
 * Consult your license regarding permissions and restrictions.
 */

/*
 * 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.
 */
