You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
503 lines
13 KiB
503 lines
13 KiB
// memory standard header
|
|
#pragma once
|
|
#ifndef _MEMORY_
|
|
#define _MEMORY_
|
|
#include <iterator>
|
|
#include <xmemory>
|
|
|
|
#pragma pack(push,8)
|
|
#pragma warning(push,3)
|
|
_STD_BEGIN
|
|
|
|
// TEMPLATE FUNCTION get_temporary_buffer
|
|
template<class _Ty> inline
|
|
pair<_Ty _FARQ *, _PDFT>
|
|
get_temporary_buffer(_PDFT _Count)
|
|
{ // get raw temporary buffer of up to _Count elements
|
|
_Ty _FARQ *_Pbuf;
|
|
|
|
for (_Pbuf = 0; 0 < _Count; _Count /= 2)
|
|
if ((_Pbuf = (_Ty _FARQ *)operator new(
|
|
(_SIZT)_Count * sizeof (_Ty), nothrow)) != 0)
|
|
break;
|
|
|
|
return (pair<_Ty _FARQ *, _PDFT>(_Pbuf, _Count));
|
|
}
|
|
|
|
// TEMPLATE FUNCTION return_temporary_buffer
|
|
template<class _Ty> inline
|
|
void return_temporary_buffer(_Ty *_Pbuf)
|
|
{ // delete raw temporary buffer
|
|
operator delete(_Pbuf);
|
|
}
|
|
|
|
// TEMPLATE FUNCTION uninitialized_copy
|
|
template<class _InIt,
|
|
class _FwdIt> inline
|
|
_FwdIt uninitialized_copy(_InIt _First, _InIt _Last, _FwdIt _Dest)
|
|
{ // copy [_First, _Last) to raw _Dest
|
|
return (_Uninit_copy(_First, _Last, _Dest,
|
|
_Ptr_cat(_First, _Dest)));
|
|
}
|
|
|
|
template<class _InIt,
|
|
class _FwdIt> inline
|
|
_FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest,
|
|
_Nonscalar_ptr_iterator_tag)
|
|
{ // copy [_First, _Last) to raw _Dest, arbitrary type
|
|
_FwdIt _Next = _Dest;
|
|
|
|
_TRY_BEGIN
|
|
for (; _First != _Last; ++_Dest, ++_First)
|
|
_Construct(&*_Dest, *_First);
|
|
_CATCH_ALL
|
|
for (; _Next != _Dest; ++_Next)
|
|
_Destroy(&*_Next);
|
|
_RERAISE;
|
|
_CATCH_END
|
|
return (_Dest);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Ty *_Uninit_copy(const _Ty *_First, const _Ty *_Last, _Ty *_Dest,
|
|
_Scalar_ptr_iterator_tag)
|
|
{ // copy [_First, _Last) to raw _Dest, scalar type
|
|
size_t _Count = (size_t)(_Last - _First);
|
|
return ((_Ty *)memmove(&*_Dest, &*_First,
|
|
_Count * sizeof (*_First)) + _Count); // NB: non-overlapping move
|
|
}
|
|
|
|
// TEMPLATE FUNCTION _Uninitialized_copy WITH ALLOCATOR
|
|
template<class _InIt,
|
|
class _FwdIt,
|
|
class _Alloc> inline
|
|
_FwdIt _Uninitialized_copy(_InIt _First, _InIt _Last, _FwdIt _Dest,
|
|
_Alloc& _Al)
|
|
{ // copy [_First, _Last) to raw _Dest, using _Al
|
|
return (_Uninit_copy(_First, _Last, _Dest, _Al,
|
|
_Ptr_cat(_First, _Dest)));
|
|
}
|
|
|
|
template<class _InIt,
|
|
class _FwdIt,
|
|
class _Alloc> inline
|
|
_FwdIt _Uninit_copy(_InIt _First, _InIt _Last, _FwdIt _Dest,
|
|
_Alloc& _Al, _Nonscalar_ptr_iterator_tag)
|
|
{ // copy [_First, _Last) to raw _Dest, using _Al, arbitrary type
|
|
_FwdIt _Next = _Dest;
|
|
|
|
_TRY_BEGIN
|
|
for (; _First != _Last; ++_Dest, ++_First)
|
|
_Al.construct(_Dest, *_First);
|
|
_CATCH_ALL
|
|
for (; _Next != _Dest; ++_Next)
|
|
_Al.destroy(_Next);
|
|
_RERAISE;
|
|
_CATCH_END
|
|
return (_Dest);
|
|
}
|
|
|
|
template<class _Ty> inline
|
|
_Ty *_Uninit_copy(const _Ty *_First, const _Ty *_Last, _Ty *_Dest,
|
|
allocator<_Ty>&, _Scalar_ptr_iterator_tag)
|
|
{ // copy [_First, _Last) to raw _Dest, scalar type
|
|
size_t _Count = (size_t)(_Last - _First);
|
|
return ((_Ty *)memmove(&*_Dest, &*_First,
|
|
_Count * sizeof (*_First)) + _Count); // NB: non-overlapping move
|
|
}
|
|
|
|
// TEMPLATE FUNCTION uninitialized_fill
|
|
template<class _FwdIt,
|
|
class _Tval> inline
|
|
void uninitialized_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val)
|
|
{ // copy _Val throughout raw [_First, _Last)
|
|
_Uninit_fill(_First, _Last, _Val, _Ptr_cat(_First, _First));
|
|
}
|
|
|
|
template<class _FwdIt,
|
|
class _Tval> inline
|
|
void _Uninit_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val,
|
|
_Nonscalar_ptr_iterator_tag)
|
|
{ // copy _Val throughout raw [_First, _Last), arbitrary type
|
|
_FwdIt _Next = _First;
|
|
|
|
_TRY_BEGIN
|
|
for (; _First != _Last; ++_First)
|
|
_Construct(&*_First, _Val);
|
|
_CATCH_ALL
|
|
for (; _Next != _First; ++_Next)
|
|
_Destroy(&*_Next);
|
|
_RERAISE;
|
|
_CATCH_END
|
|
}
|
|
|
|
template<class _Ty,
|
|
class _Tval> inline
|
|
void _Uninit_fill(_Ty *_First, _Ty *_Last, const _Tval& _Val,
|
|
_Scalar_ptr_iterator_tag)
|
|
{ // copy _Val throughout raw [_First, _Last), scalar type
|
|
std::fill(_First, _Last, _Val);
|
|
}
|
|
|
|
// TEMPLATE FUNCTION uninitialized_fill_n
|
|
template<class _FwdIt,
|
|
class _Diff,
|
|
class _Tval> inline
|
|
void uninitialized_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val)
|
|
{ // copy _Count *_Val to raw _First
|
|
_Uninit_fill_n(_First, _Count, _Val, _Ptr_cat(_First, _First));
|
|
}
|
|
|
|
template<class _FwdIt,
|
|
class _Diff,
|
|
class _Tval> inline
|
|
void _Uninit_fill_n(_FwdIt _First, _Diff _Count, const _Tval& _Val,
|
|
_Nonscalar_ptr_iterator_tag)
|
|
{ // copy _Count *_Val to raw _First, arbitrary type
|
|
_FwdIt _Next = _First;
|
|
|
|
_TRY_BEGIN
|
|
for (; 0 < _Count; --_Count, ++_First)
|
|
_Construct(&*_First, _Val);
|
|
_CATCH_ALL
|
|
for (; _Next != _First; ++_Next)
|
|
_Destroy(&*_Next);
|
|
_RERAISE;
|
|
_CATCH_END
|
|
}
|
|
|
|
template<class _Ty,
|
|
class _Diff,
|
|
class _Tval> inline
|
|
void _Uninit_fill_n(_Ty *_First, _Diff _Count, const _Tval& _Val,
|
|
_Scalar_ptr_iterator_tag)
|
|
{ // copy _Count *_Val to raw _First, scalar type
|
|
std::fill_n(_First, _Count, _Val);
|
|
}
|
|
|
|
// TEMPLATE FUNCTION _Uninitialized_fill_n WITH ALLOCATOR
|
|
template<class _FwdIt,
|
|
class _Diff,
|
|
class _Tval,
|
|
class _Alloc> inline
|
|
void _Uninitialized_fill_n(_FwdIt _First, _Diff _Count,
|
|
const _Tval& _Val, _Alloc& _Al)
|
|
{ // copy _Count *_Val to raw _First, using _Al
|
|
_Uninit_fill_n(_First, _Count, _Val, _Al,
|
|
_Ptr_cat(_First, _First));
|
|
}
|
|
|
|
template<class _FwdIt,
|
|
class _Diff,
|
|
class _Tval,
|
|
class _Alloc> inline
|
|
void _Uninit_fill_n(_FwdIt _First, _Diff _Count,
|
|
const _Tval& _Val, _Alloc& _Al, _Nonscalar_ptr_iterator_tag)
|
|
{ // copy _Count *_Val to raw _First, using _Al, arbitrary type
|
|
_FwdIt _Next = _First;
|
|
|
|
_TRY_BEGIN
|
|
for (; 0 < _Count; --_Count, ++_First)
|
|
_Al.construct(_First, _Val);
|
|
_CATCH_ALL
|
|
for (; _Next != _First; ++_Next)
|
|
_Al.destroy(_Next);
|
|
_RERAISE;
|
|
_CATCH_END
|
|
}
|
|
|
|
template<class _Ty,
|
|
class _Diff,
|
|
class _Tval> inline
|
|
void _Uninit_fill_n(_Ty *_First, _Diff _Count,
|
|
const _Tval& _Val, allocator<_Ty>&, _Scalar_ptr_iterator_tag)
|
|
{ // copy _Count *_Val to raw _First, using _Al, scalar type
|
|
fill_n(_First, _Count, _Val);
|
|
}
|
|
|
|
// TEMPLATE CLASS raw_storage_iterator
|
|
template<class _FwdIt,
|
|
class _Ty>
|
|
class raw_storage_iterator
|
|
: public _Outit
|
|
{ // wrap stores to raw buffer as output iterator
|
|
public:
|
|
typedef _FwdIt iterator_type; // retained
|
|
typedef _FwdIt iter_type; // retained
|
|
typedef _Ty element_type; // retained
|
|
|
|
explicit raw_storage_iterator(_FwdIt _First)
|
|
: _Next(_First)
|
|
{ // construct with iterator
|
|
}
|
|
|
|
raw_storage_iterator<_FwdIt, _Ty>& operator*()
|
|
{ // pretend to return designated value
|
|
return (*this);
|
|
}
|
|
|
|
raw_storage_iterator<_FwdIt, _Ty>& operator=(const _Ty& _Val)
|
|
{ // construct value designated by stored iterator
|
|
_Construct(&*_Next, _Val);
|
|
return (*this);
|
|
}
|
|
|
|
raw_storage_iterator<_FwdIt, _Ty>& operator++()
|
|
{ // preincrement
|
|
++_Next;
|
|
return (*this);
|
|
}
|
|
|
|
raw_storage_iterator<_FwdIt, _Ty> operator++(int)
|
|
{ // postincrement
|
|
raw_storage_iterator<_FwdIt, _Ty> _Ans = *this;
|
|
++_Next;
|
|
return (_Ans);
|
|
}
|
|
|
|
private:
|
|
_FwdIt _Next; // the stored iterator
|
|
};
|
|
|
|
// TEMPLATE CLASS _Temp_iterator
|
|
template<class _Ty>
|
|
class _Temp_iterator
|
|
: public _Outit
|
|
{ // wrap stores to temporary buffer as output iterator
|
|
public:
|
|
typedef _Ty _FARQ *_Pty;
|
|
|
|
_Temp_iterator(_PDFT _Count = 0)
|
|
{ // construct from desired temporary buffer size
|
|
pair<_Pty, _PDFT> _Pair =
|
|
std::get_temporary_buffer<_Ty>(_Count);
|
|
_Buf._Begin = _Pair.first;
|
|
_Buf._Current = _Pair.first;
|
|
_Buf._Hiwater = _Pair.first;
|
|
_Buf._Size = _Pair.second;
|
|
_Pbuf = &_Buf;
|
|
}
|
|
|
|
_Temp_iterator(const _Temp_iterator<_Ty>& _Right)
|
|
{ // construct from _Right (share active buffer)
|
|
_Buf._Begin = 0; // clear stored buffer, to be tidy
|
|
_Buf._Current = 0;
|
|
_Buf._Hiwater = 0;
|
|
_Buf._Size = 0;
|
|
*this = _Right;
|
|
}
|
|
|
|
~_Temp_iterator()
|
|
{ // destroy the object
|
|
if (_Buf._Begin != 0)
|
|
{ // destroy any constructed elements in buffer
|
|
for (_Pty _Next = _Buf._Begin;
|
|
_Next != _Buf._Hiwater; ++_Next)
|
|
_Destroy(&*_Next);
|
|
std::return_temporary_buffer(_Buf._Begin);
|
|
}
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& operator=(const _Temp_iterator<_Ty>& _Right)
|
|
{ // assign _Right (share active buffer)
|
|
_Pbuf = _Right._Pbuf;
|
|
return (*this);
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& operator=(const _Ty& _Val)
|
|
{ // assign or construct value into active buffer, and increment
|
|
if (_Pbuf->_Current < _Pbuf->_Hiwater)
|
|
*_Pbuf->_Current++ = _Val; // below high water mark, assign
|
|
else
|
|
{ // above high water mark, construct
|
|
_Construct(&*_Pbuf->_Current, _Val);
|
|
_Pbuf->_Hiwater = ++_Pbuf->_Current;
|
|
}
|
|
return (*this);
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& operator*()
|
|
{ // pretend to return designated value
|
|
return (*this);
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& operator++()
|
|
{ // pretend to preincrement
|
|
return (*this);
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& operator++(int)
|
|
{ // pretend to postincrement
|
|
return (*this);
|
|
}
|
|
|
|
_Temp_iterator<_Ty>& _Init()
|
|
{ // set pointer at beginning of buffer
|
|
_Pbuf->_Current = _Pbuf->_Begin;
|
|
return (*this);
|
|
}
|
|
|
|
_Pty _First() const
|
|
{ // return pointer to beginning of buffer
|
|
return (_Pbuf->_Begin);
|
|
}
|
|
|
|
_Pty _Last() const
|
|
{ // return pointer past end of buffer contents
|
|
return (_Pbuf->_Current);
|
|
}
|
|
|
|
_PDFT _Maxlen() const
|
|
{ // return size of buffer
|
|
return (_Pbuf->_Size);
|
|
}
|
|
|
|
private:
|
|
struct _Bufpar
|
|
{ // control information for a temporary buffer
|
|
_Pty _Begin; // pointer to beginning of buffer
|
|
_Pty _Current; // pointer to next available element
|
|
_Pty _Hiwater; // pointer to first unconstructed element
|
|
_PDFT _Size; // length of buffer
|
|
};
|
|
_Bufpar _Buf; // buffer control stored in iterator
|
|
_Bufpar *_Pbuf; // pointer to active buffer control
|
|
};
|
|
|
|
// TEMPLATE CLASS auto_ptr
|
|
template<class _Ty>
|
|
class auto_ptr;
|
|
|
|
template<class _Ty>
|
|
struct auto_ptr_ref
|
|
{ // proxy reference for auto_ptr copying
|
|
auto_ptr_ref(auto_ptr<_Ty>& _Right)
|
|
: _Ref(_Right)
|
|
{ // construct from compatible auto_ptr
|
|
}
|
|
|
|
auto_ptr<_Ty>& _Ref; // reference to constructor argument
|
|
};
|
|
|
|
template<class _Ty>
|
|
class auto_ptr
|
|
{ // wrap an object pointer to ensure destruction
|
|
public:
|
|
typedef _Ty element_type;
|
|
|
|
explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
|
|
: _Myptr(_Ptr)
|
|
{ // construct from object pointer
|
|
}
|
|
|
|
auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()
|
|
: _Myptr(_Right.release())
|
|
{ // construct by assuming pointer from _Right auto_ptr
|
|
}
|
|
|
|
auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
|
|
: _Myptr(_Right._Ref.release())
|
|
{ // construct by assuming pointer from _Right auto_ptr_ref
|
|
}
|
|
|
|
template<class _Other>
|
|
operator auto_ptr<_Other>() _THROW0()
|
|
{ // convert to compatible auto_ptr
|
|
return (auto_ptr<_Other>(*this));
|
|
}
|
|
|
|
template<class _Other>
|
|
operator auto_ptr_ref<_Other>() _THROW0()
|
|
{ // convert to compatible auto_ptr_ref
|
|
return (auto_ptr_ref<_Other>(*this));
|
|
}
|
|
|
|
template<class _Other>
|
|
auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) _THROW0()
|
|
{ // assign compatible _Right (assume pointer)
|
|
reset(_Right.release());
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other>
|
|
auto_ptr(auto_ptr<_Other>& _Right) _THROW0()
|
|
: _Myptr(_Right.release())
|
|
{ // construct by assuming pointer from _Right
|
|
}
|
|
|
|
auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0()
|
|
{ // assign compatible _Right (assume pointer)
|
|
reset(_Right.release());
|
|
return (*this);
|
|
}
|
|
|
|
auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty>& _Right) throw ()
|
|
{ // assign compatible _Right._Ref (assume pointer)
|
|
reset(_Right._Ref.release());
|
|
return (*this);
|
|
}
|
|
|
|
~auto_ptr()
|
|
{ // destroy the object
|
|
delete _Myptr;
|
|
}
|
|
|
|
_Ty& operator*() const _THROW0()
|
|
{ // return designated value
|
|
return (*get());
|
|
}
|
|
|
|
_Ty *operator->() const _THROW0()
|
|
{ // return pointer to class object
|
|
return (get());
|
|
}
|
|
|
|
_Ty *get() const _THROW0()
|
|
{ // return wrapped pointer
|
|
return (_Myptr);
|
|
}
|
|
|
|
_Ty *release() _THROW0()
|
|
{ // return wrapped pointer and give up ownership
|
|
_Ty *_Tmp = _Myptr;
|
|
_Myptr = 0;
|
|
return (_Tmp);
|
|
}
|
|
|
|
void reset(_Ty* _Ptr = 0)
|
|
{ // destroy designated object and store new pointer
|
|
if (_Ptr != _Myptr)
|
|
delete _Myptr;
|
|
_Myptr = _Ptr;
|
|
}
|
|
|
|
private:
|
|
_Ty *_Myptr; // the wrapped object pointer
|
|
};
|
|
_STD_END
|
|
#pragma warning(pop)
|
|
#pragma pack(pop)
|
|
|
|
#endif /* _MEMORY_ */
|
|
|
|
/*
|
|
* Copyright (c) 1992-2001 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.
|
|
V3.10:0009 */
|