549 lines
12 KiB
C++
549 lines
12 KiB
C++
#pragma once
|
|
#ifndef _STLUTIL_H_
|
|
#define _STLUTIL_H_
|
|
|
|
#include <stlxstdd.h>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma pack(push,8)
|
|
#endif /* _MSC_VER */
|
|
|
|
_STD_BEGIN
|
|
|
|
// TEMPLATE STRUCT pair
|
|
template<class _T1, class _T2> struct pair
|
|
{
|
|
typedef _T1 first_type;
|
|
typedef _T2 second_type;
|
|
pair()
|
|
: first(_T1()), second(_T2())
|
|
{
|
|
|
|
}
|
|
pair(const _T1& _V1, const _T2& _V2)
|
|
: first(_V1), second(_V2)
|
|
{
|
|
|
|
}
|
|
_T1 first;
|
|
_T2 second;
|
|
};
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator==(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (_X.first == _Y.first && _X.second == _Y.second);
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator!=(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (!(_X == _Y));
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator<(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (_X.first < _Y.first ||
|
|
!(_Y.first < _X.first) && _X.second < _Y.second);
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator>(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (_Y < _X);
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator<=(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (!(_Y < _X));
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
bool __cdecl operator>=(const pair<_T1, _T2>& _X,
|
|
const pair<_T1, _T2>& _Y)
|
|
{
|
|
return (!(_X < _Y));
|
|
}
|
|
template<class _T1, class _T2> inline
|
|
pair<_T1, _T2> __cdecl make_pair(const _T1& _X, const _T2& _Y)
|
|
{
|
|
return (pair<_T1, _T2>(_X, _Y));
|
|
}
|
|
|
|
|
|
// ITERATOR TAGS (from <iterator>)
|
|
struct input_iterator_tag
|
|
{
|
|
};
|
|
struct output_iterator_tag
|
|
{
|
|
};
|
|
struct forward_iterator_tag
|
|
: public input_iterator_tag
|
|
{
|
|
};
|
|
struct bidirectional_iterator_tag
|
|
: public forward_iterator_tag
|
|
{
|
|
};
|
|
struct random_access_iterator_tag
|
|
: public bidirectional_iterator_tag
|
|
{
|
|
};
|
|
|
|
|
|
// TEMPLATE CLASS iterator (from <iterator>)
|
|
template<class _C, class _Ty, class _D = ptrdiff_t>
|
|
struct iterator
|
|
{
|
|
typedef _C iterator_category;
|
|
typedef _Ty value_type;
|
|
typedef _D distance_type;
|
|
};
|
|
|
|
template<class _Ty, class _D>
|
|
struct _Bidit : public iterator<bidirectional_iterator_tag, _Ty, _D>
|
|
{
|
|
};
|
|
|
|
template<class _Ty, class _D>
|
|
struct _Ranit : public iterator<random_access_iterator_tag, _Ty, _D>
|
|
{
|
|
};
|
|
|
|
// TEMPLATE CLASS iterator_traits (from <iterator>)
|
|
template<class _It>
|
|
struct iterator_traits
|
|
{
|
|
typedef _It::iterator_category iterator_category;
|
|
typedef _It::value_type value_type;
|
|
typedef _It::distance_type distance_type;
|
|
};
|
|
|
|
// TEMPLATE FUNCTION _Iter_cat (from <iterator>)
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(push)
|
|
#endif
|
|
#pragma warning(disable:4700)
|
|
|
|
template<class _C, class _Ty, class _D>
|
|
inline
|
|
_C __cdecl _Iter_cat(const iterator<_C, _Ty, _D>&)
|
|
{
|
|
_C _X;
|
|
return (_X);
|
|
}
|
|
|
|
template<class _Ty>
|
|
inline
|
|
random_access_iterator_tag __cdecl _Iter_cat(const _Ty *)
|
|
{
|
|
random_access_iterator_tag _X;
|
|
return (_X);
|
|
}
|
|
|
|
#if _MSC_VER >= 1200
|
|
#pragma warning(pop)
|
|
#else
|
|
#pragma warning(default:4700)
|
|
#endif
|
|
|
|
// TEMPLATE FUNCTION _Distance
|
|
template<class _II>
|
|
inline
|
|
_CNTSIZ(_II) __cdecl distance(_II _F, _II _L)
|
|
{
|
|
_CNTSIZ(_II) _N = 0;
|
|
_Distance(_F, _L, _N, _Iter_cat(_F));
|
|
return (_N);
|
|
}
|
|
|
|
template<class _II, class _D>
|
|
inline
|
|
void __cdecl _Distance(_II _F, _II _L, _D& _N)
|
|
{
|
|
_Distance(_F, _L, _N, _Iter_cat(_F));
|
|
}
|
|
|
|
template<class _II, class _D>
|
|
inline
|
|
void __cdecl _Distance(_II _F, _II _L, _D& _N, input_iterator_tag)
|
|
{
|
|
for (; _F != _L; ++_F)
|
|
++_N;
|
|
}
|
|
|
|
template<class _II, class _D>
|
|
inline
|
|
void __cdecl _Distance(_II _F, _II _L, _D& _N, forward_iterator_tag)
|
|
{
|
|
for (; _F != _L; ++_F)
|
|
++_N;
|
|
}
|
|
|
|
template<class _II, class _D>
|
|
inline
|
|
void __cdecl _Distance(_II _F, _II _L, _D& _N,
|
|
bidirectional_iterator_tag)
|
|
{
|
|
for (; _F != _L; ++_F)
|
|
++_N;
|
|
}
|
|
|
|
template<class _RI, class _D>
|
|
inline
|
|
void __cdecl _Distance(_RI _F, _RI _L, _D& _N,
|
|
random_access_iterator_tag)
|
|
{
|
|
_N += (_D)(_L - _F);
|
|
}
|
|
|
|
// TEMPLATE CLASS reverse_iterator (from <iterator>)
|
|
template<class _RI, class _Ty, class _Rt = _Ty&, class _Pt = _Ty *,
|
|
class _D = ptrdiff_t>
|
|
class reverse_iterator : public _Ranit<_Ty, _D>
|
|
{
|
|
public:
|
|
typedef reverse_iterator<_RI, _Ty, _Rt, _Pt, _D> _Myt;
|
|
typedef _RI iter_type;
|
|
typedef _Rt reference_type;
|
|
typedef _Pt pointer_type;
|
|
reverse_iterator()
|
|
{
|
|
}
|
|
explicit reverse_iterator(_RI _X)
|
|
: current(_X)
|
|
{
|
|
}
|
|
_RI base() const
|
|
{
|
|
return (current);
|
|
}
|
|
_Rt operator*() const
|
|
{
|
|
return (*(current - 1));
|
|
}
|
|
_Pt operator->() const
|
|
{
|
|
return (&**this);
|
|
}
|
|
_Myt& operator++()
|
|
{
|
|
--current;
|
|
return (*this);
|
|
}
|
|
_Myt operator++(int)
|
|
{
|
|
_Myt _Tmp = *this;
|
|
--current;
|
|
return (_Tmp);
|
|
}
|
|
_Myt& operator--()
|
|
{
|
|
++current;
|
|
return (*this);
|
|
}
|
|
_Myt operator--(int)
|
|
{
|
|
_Myt _Tmp = *this;
|
|
++current;
|
|
return (_Tmp);
|
|
}
|
|
_Myt& operator+=(_D _N)
|
|
{
|
|
current -= _N;
|
|
return (*this);
|
|
}
|
|
_Myt operator+(_D _N) const
|
|
{
|
|
return (_Myt(current - _N));
|
|
}
|
|
_Myt& operator-=(_D _N)
|
|
{
|
|
current += _N;
|
|
return (*this);
|
|
}
|
|
_Myt operator-(_D _N) const
|
|
{
|
|
return (_Myt(current + _N));
|
|
}
|
|
_Rt operator[](_D _N) const
|
|
{
|
|
return (*(*this + _N));
|
|
}
|
|
protected:
|
|
_RI current;
|
|
};
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator==(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (_X.base() == _Y.base());
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator!=(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (!(_X == _Y));
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator<(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (_Y.base() < _X.base());
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator>(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (_Y < _X);
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator<=(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (!(_Y < _X));
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
bool __cdecl operator>=(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (!(_X < _Y));
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
_D __cdecl operator-(
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _X,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (_Y.base() - _X.base());
|
|
}
|
|
|
|
template<class _RI, class _Ty, class _Rt, class _Pt, class _D>
|
|
inline
|
|
reverse_iterator<_RI, _Ty, _Rt, _Pt, _D> __cdecl operator+(_D _N,
|
|
const reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>& _Y)
|
|
{
|
|
return (reverse_iterator<_RI, _Ty, _Rt, _Pt, _D>(
|
|
_Y.base() - _N));
|
|
}
|
|
|
|
/*
|
|
// TEMPLATE CLASS istreambuf_iterator (from <iterator>)
|
|
template<class _E, class _Tr = char_traits<_E> >
|
|
class istreambuf_iterator :
|
|
public iterator<input_iterator_tag, _E, _Tr::off_type>
|
|
{
|
|
public:
|
|
typedef istreambuf_iterator<_E, _Tr> _Myt;
|
|
typedef _E char_type;
|
|
typedef _Tr traits_type;
|
|
typedef _Tr::int_type int_type;
|
|
typedef basic_streambuf<_E, _Tr> streambuf_type;
|
|
typedef basic_istream<_E, _Tr> istream_type;
|
|
istreambuf_iterator(streambuf_type *_Sb = 0) _THROW0()
|
|
: _Sbuf(_Sb), _Got(_Sb == 0)
|
|
{
|
|
|
|
}
|
|
istreambuf_iterator(istream_type& _I) _THROW0()
|
|
: _Sbuf(_I.rdbuf()), _Got(_I.rdbuf() == 0)
|
|
{
|
|
|
|
}
|
|
const _E& operator*() const
|
|
{
|
|
if (!_Got)
|
|
((_Myt *)this)->_Peek();
|
|
return (_Val);
|
|
}
|
|
const _E *operator->() const
|
|
{
|
|
return (&**this);
|
|
}
|
|
_Myt& operator++()
|
|
{
|
|
_Inc();
|
|
return (*this);
|
|
}
|
|
_Myt operator++(int)
|
|
{
|
|
if (!_Got)
|
|
_Peek();
|
|
_Myt _Tmp = *this;
|
|
_Inc();
|
|
return (_Tmp);
|
|
}
|
|
bool equal(const _Myt& _X) const
|
|
{
|
|
if (!_Got)
|
|
((_Myt *)this)->_Peek();
|
|
if (!_X._Got)
|
|
((_Myt *)&_X)->_Peek();
|
|
return (_Sbuf == 0 && _X._Sbuf == 0
|
|
|| _Sbuf != 0 && _X._Sbuf != 0);
|
|
}
|
|
private:
|
|
void _Inc()
|
|
{
|
|
if (_Sbuf == 0
|
|
|| _Tr::eq_int_type(_Tr::eof(), _Sbuf->sbumpc()))
|
|
_Sbuf = 0, _Got = true;
|
|
else
|
|
_Got = false;
|
|
}
|
|
_E _Peek()
|
|
{
|
|
int_type _C;
|
|
if (_Sbuf == 0
|
|
|| _Tr::eq_int_type(_Tr::eof(), _C = _Sbuf->sgetc()))
|
|
_Sbuf = 0;
|
|
else
|
|
_Val = _Tr::to_char_type(_C);
|
|
_Got = true;
|
|
return (_Val);
|
|
}
|
|
streambuf_type *_Sbuf;
|
|
bool _Got;
|
|
_E _Val;
|
|
};
|
|
template<class _E, class _Tr> inline
|
|
bool __cdecl operator==(const istreambuf_iterator<_E, _Tr>& _X,
|
|
const istreambuf_iterator<_E, _Tr>& _Y)
|
|
{
|
|
return (_X.equal(_Y));
|
|
}
|
|
template<class _E, class _Tr> inline
|
|
bool __cdecl operator!=(const istreambuf_iterator<_E, _Tr>& _X,
|
|
const istreambuf_iterator<_E, _Tr>& _Y)
|
|
{
|
|
return (!(_X == _Y));
|
|
}
|
|
|
|
// TEMPLATE CLASS ostreambuf_iterator (from <iterator>)
|
|
template<class _E, class _Tr = char_traits<_E> >
|
|
class ostreambuf_iterator :
|
|
public iterator<output_iterator_tag, void, void>
|
|
{
|
|
typedef ostreambuf_iterator<_E, _Tr> _Myt;
|
|
public:
|
|
typedef _E char_type;
|
|
typedef _Tr traits_type;
|
|
typedef basic_streambuf<_E, _Tr> streambuf_type;
|
|
typedef basic_ostream<_E, _Tr> ostream_type;
|
|
ostreambuf_iterator(streambuf_type *_Sb) _THROW0()
|
|
: _Failed(false), _Sbuf(_Sb)
|
|
{
|
|
|
|
}
|
|
ostreambuf_iterator(ostream_type& _O) _THROW0()
|
|
: _Failed(false), _Sbuf(_O.rdbuf())
|
|
{
|
|
|
|
}
|
|
_Myt& operator=(_E _X)
|
|
{
|
|
if (_Sbuf == 0
|
|
|| _Tr::eq_int_type(_Tr::eof(), _Sbuf->sputc(_X)))
|
|
_Failed = true;
|
|
return (*this);
|
|
}
|
|
_Myt& operator*()
|
|
{
|
|
return (*this);
|
|
}
|
|
_Myt& operator++()
|
|
{
|
|
return (*this);
|
|
}
|
|
_Myt& operator++(int)
|
|
{
|
|
return (*this);
|
|
}
|
|
bool failed() const _THROW0()
|
|
{
|
|
return (_Failed);
|
|
}
|
|
private:
|
|
bool _Failed;
|
|
streambuf_type *_Sbuf;
|
|
};
|
|
*/
|
|
|
|
// TEMPLATE OPERATORS
|
|
namespace rel_ops
|
|
{
|
|
template<class _Ty> inline
|
|
bool __cdecl operator!=(const _Ty& _X, const _Ty& _Y)
|
|
{
|
|
return (!(_X == _Y));
|
|
}
|
|
template<class _Ty> inline
|
|
bool __cdecl operator>(const _Ty& _X, const _Ty& _Y)
|
|
{
|
|
return (_Y < _X);
|
|
}
|
|
template<class _Ty> inline
|
|
bool __cdecl operator<=(const _Ty& _X, const _Ty& _Y)
|
|
{
|
|
return (!(_Y < _X));
|
|
}
|
|
template<class _Ty> inline
|
|
bool __cdecl operator>=(const _Ty& _X, const _Ty& _Y)
|
|
{
|
|
return (!(_X < _Y));
|
|
}
|
|
}
|
|
|
|
_STD_END
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma pack(pop)
|
|
#endif /* _MSC_VER */
|
|
|
|
#endif /* _STLUTIL_H_ */
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|