Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1413 lines
35 KiB

// xutility internal header
#pragma once
#ifndef _XUTILITY_
#define _XUTILITY_
#include <climits>
#include <utility>
#pragma pack(push,8)
#pragma warning(push,3)
#pragma warning(disable:4786)
_STD_BEGIN
// ITERATOR STUFF (from <iterator>)
// ITERATOR TAGS
struct input_iterator_tag
{ // identifying tag for input iterators
};
struct output_iterator_tag
{ // identifying tag for output iterators
};
struct forward_iterator_tag
: public input_iterator_tag
{ // identifying tag for forward iterators
};
struct bidirectional_iterator_tag
: public forward_iterator_tag
{ // identifying tag for bidirectional iterators
};
struct random_access_iterator_tag
: public bidirectional_iterator_tag
{ // identifying tag for random-access iterators
};
struct _Int_iterator_tag
{ // identifying tag for integer types, not an iterator
};
// POINTER ITERATOR TAGS
struct _Nonscalar_ptr_iterator_tag
{ // pointer to unknown type
};
struct _Scalar_ptr_iterator_tag
{ // pointer to scalar type
};
// TEMPLATE CLASS iterator
template<class _Category,
class _Ty,
class _Diff = ptrdiff_t,
class _Pointer = _Ty *,
class _Reference = _Ty&>
struct iterator
{ // base type for all iterator classes
typedef _Category iterator_category;
typedef _Ty value_type;
typedef _Diff difference_type;
typedef _Diff distance_type; // retained
typedef _Pointer pointer;
typedef _Reference reference;
};
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference>
struct _Bidit
: public iterator<bidirectional_iterator_tag, _Ty, _Diff,
_Pointer, _Reference>
{ // base for bidirectional iterators
};
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference>
struct _Ranit
: public iterator<random_access_iterator_tag, _Ty, _Diff,
_Pointer, _Reference>
{ // base for random-access iterators
};
struct _Outit
: public iterator<output_iterator_tag, void, void,
void, void>
{ // base for output iterators
};
// TEMPLATE CLASS iterator_traits
template<class _Iter>
struct iterator_traits
{ // get traits from iterator _Iter
typedef typename _Iter::iterator_category iterator_category;
typedef typename _Iter::value_type value_type;
typedef typename _Iter::difference_type difference_type;
typedef difference_type distance_type; // retained
typedef typename _Iter::pointer pointer;
typedef typename _Iter::reference reference;
};
// TEMPLATE FUNCTION _Iter_cat
template<class _Category,
class _Ty,
class _Diff,
class _Pointer,
class _Reference> inline
_Category _Iter_cat(const iterator<_Category, _Ty, _Diff,
_Pointer, _Reference>&)
{ // return category from iterator argument
_Category _Cat;
return (_Cat);
}
template<class _Ty> inline
random_access_iterator_tag _Iter_cat(const _Ty *)
{ // return category from pointer argument
random_access_iterator_tag _Cat;
return (_Cat);
}
// INTEGER FUNCTION _Iter_cat
inline _Int_iterator_tag _Iter_cat(_Bool)
{ // return category from bool argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(char)
{ // return category from char argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(signed char)
{ // return category from signed char argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(unsigned char)
{ // return category from unsigned char argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(short)
{ // return category from short argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(unsigned short)
{ // return category from unsigned short argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(int)
{ // return category from int argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(unsigned int)
{ // return category from unsigned int argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(long)
{ // return category from long argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(unsigned long)
{ // return category from unsigned long argument
_Int_iterator_tag _Cat;
return (_Cat);
}
#ifdef _LONGLONG
inline _Int_iterator_tag _Iter_cat(_LONGLONG)
{ // return category from long long argument
_Int_iterator_tag _Cat;
return (_Cat);
}
inline _Int_iterator_tag _Iter_cat(_ULONGLONG)
{ // return category from ulong long argument
_Int_iterator_tag _Cat;
return (_Cat);
}
#endif /* _LONGLONG */
// TEMPLATE FUNCTION _Ptr_cat
template<class _T1,
class _T2> inline
_Nonscalar_ptr_iterator_tag _Ptr_cat(const _T1&, _T2&)
{ // return pointer category from arbitrary arguments
_Nonscalar_ptr_iterator_tag _Cat;
return (_Cat);
}
#if _HAS_TEMPLATE_PARTIAL_ORDERING
template<class _Ty> inline
_Scalar_ptr_iterator_tag _Ptr_cat(const _Ty **, const _Ty **)
{ // return pointer category from pointer to pointer arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
template<class _Ty> inline
_Scalar_ptr_iterator_tag _Ptr_cat(const _Ty *const *, const _Ty **)
{ // return pointer category from pointer to pointer arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
#endif /* _HAS_TEMPLATE_PARTIAL_ORDERING */
// INTEGER FUNCTION _Ptr_cat
inline _Scalar_ptr_iterator_tag _Ptr_cat(const _Bool *, _Bool *)
{ // return pointer category from pointer to bool arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const char *, char *)
{ // return pointer category from pointer to char arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const signed char *, signed char *)
{ // return pointer category from pointer to signed char arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned char *,
unsigned char *)
{ // return pointer category from pointer to unsigned char arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const short *, short *)
{ // return pointer category from pointer to short arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned short *,
unsigned short *)
{ // return pointer category from pointer to unsigned short arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const int *, int *)
{ // return pointer category from pointer to int arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned int *, unsigned int *)
{ // return pointer category from pointer to unsigned int arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const long *, long *)
{ // return pointer category from pointer to long arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const unsigned long *,
unsigned long *)
{ // return pointer category from pointer to unsigned long arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const float *, float *)
{ // return pointer category from pointer to float arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const double *, double *)
{ // return pointer category from pointer to double arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const long double *, long double *)
{ // return pointer category from pointer to long double arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
#ifdef _LONGLONG
inline _Scalar_ptr_iterator_tag _Ptr_cat(const _LONGLONG *, _LONGLONG *)
{ // return pointer category from pointer to long long arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
inline _Scalar_ptr_iterator_tag _Ptr_cat(const _ULONGLONG *, _ULONGLONG *)
{ // return pointer category from pointer to ulong long arguments
_Scalar_ptr_iterator_tag _Cat;
return (_Cat);
}
#endif /* _LONGLONG */
// TEMPLATE FUNCTIONS distance and _Distance
template<class _InIt> inline
ptrdiff_t distance(_InIt _First, _InIt _Last)
{ // return distance between iterators
ptrdiff_t _Off = 0;
_Distance2(_First, _Last, _Off, _Iter_cat(_First));
return (_Off);
}
template<class _InIt,
class _Diff> inline
void _Distance(_InIt _First, _InIt _Last, _Diff& _Off)
{ // add to _Off distance between iterators
_Distance2(_First, _Last, _Off, _Iter_cat(_First));
}
template<class _InIt,
class _Diff> inline
void _Distance2(_InIt _First, _InIt _Last, _Diff& _Off,
input_iterator_tag)
{ // add to _Off distance between input iterators
for (; _First != _Last; ++_First)
++_Off;
}
template<class _FwdIt,
class _Diff> inline
void _Distance2(_FwdIt _First, _FwdIt _Last, _Diff& _Off,
forward_iterator_tag)
{ // add to _Off distance between forward iterators (redundant)
for (; _First != _Last; ++_First)
++_Off;
}
template<class _BidIt,
class _Diff> inline
void _Distance2(_BidIt _First, _BidIt _Last, _Diff& _Off,
bidirectional_iterator_tag)
{ // add to _Off distance between bidirectional iterators (redundant)
for (; _First != _Last; ++_First)
++_Off;
}
template<class _RanIt,
class _Diff> inline
void _Distance2(_RanIt _First, _RanIt _Last, _Diff& _Off,
random_access_iterator_tag)
{ // add to _Off distance between random-access iterators
_Off += _Last - _First;
}
// TEMPLATE CLASS _Ptrit
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2>
class _Ptrit
: public _Ranit<_Ty, _Diff, _Pointer, _Reference>
{ // wrap pointer as random-access iterator
public:
typedef _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2> _Myt;
_Ptrit()
{ // construct with uninitialized wrapped pointer
}
_Ptrit(_Pointer _Ptr)
: current(_Ptr)
{ // construct wrapped pointer from _Ptr
}
_Ptrit(const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Iter)
: current(_Iter.base())
{ // const converter or copy constructor
}
_Pointer base() const
{ // return wrapped pointer
return (current);
}
_Reference operator*() const
{ // return designated value
return (*current);
}
_Pointer operator->() const
{ // return pointer to class object
return (&**this);
}
_Myt& operator++()
{ // preincrement
++current;
return (*this);
}
_Myt operator++(int)
{ // postincrement
_Myt _Tmp = *this;
++current;
return (_Tmp);
}
_Myt& operator--()
{ // predecrement
--current;
return (*this);
}
_Myt operator--(int)
{ // postdecrement
_Myt _Tmp = *this;
--current;
return (_Tmp);
}
bool operator==(int _Right) const
{ // test if wrapped pointer == integer (null pointer constant)
return (current == (_Pointer)_Right);
}
bool operator==(const _Myt& _Right) const
{ // test for iterator equality
return (current == _Right.current);
}
bool operator!=(const _Myt& _Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}
_Myt& operator+=(_Diff _Off)
{ // increment by integer
current += _Off;
return (*this);
}
_Myt operator+(_Diff _Off) const
{ // return this + integer
return (_Myt(current + _Off));
}
_Myt& operator-=(_Diff _Off)
{ // decrement by integer
current -= _Off;
return (*this);
}
_Myt operator-(_Diff _Off) const
{ // return this - integer
return (_Myt(current - _Off));
}
_Reference operator[](_Diff _Off) const
{ // subscript
return (*(*this + _Off));
}
bool operator<(const _Myt& _Right) const
{ // test if this < _Right
return (current < _Right.current);
}
bool operator>(const _Myt& _Right) const
{ // test if this > _Right
return (_Right < *this);
}
bool operator<=(const _Myt& _Right) const
{ // test if this <= _Right
return (!(_Right < *this));
}
bool operator>=(const _Myt& _Right) const
{ // test if this >= _Right
return (!(*this < _Right));
}
_Diff operator-(const _Myt& _Right) const
{ // return difference of iterators
return (current - _Right.current);
}
protected:
_Pointer current; // the wrapped pointer
};
// _Ptrit TEMPLATE FUNCTIONS
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
_Ptrit<_Ty, _Diff, _Pointer, _Reference, _Pointer2, _Reference2>
__cdecl operator+(_Diff _Off,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // return iterator + integer
return (_Right + _Off);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator==(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> == _Ptrit<const *>
return (_Right == _Left);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator!=(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> != _Ptrit<const *>
return (_Right != _Left);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator<(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> < _Ptrit<const *>
return (_Right > _Left);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator>(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> > _Ptrit<const *>
return (_Right < _Left);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator<=(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> <= _Ptrit<const *>
return (_Right >= _Left);
}
template<class _Ty,
class _Diff,
class _Pointer,
class _Reference,
class _Pointer2,
class _Reference2> inline
bool __cdecl operator>=(
const _Ptrit<_Ty, _Diff, _Pointer2, _Reference2,
_Pointer2, _Reference2>& _Left,
const _Ptrit<_Ty, _Diff, _Pointer, _Reference,
_Pointer2, _Reference2>& _Right)
{ // test for _Ptrit<non-const *> >= _Ptrit<const *>
return (_Right <= _Left);
}
// TEMPLATE CLASS reverse_iterator
template<class _RanIt>
class reverse_iterator
: public iterator<
typename iterator_traits<_RanIt>::iterator_category,
typename iterator_traits<_RanIt>::value_type,
typename iterator_traits<_RanIt>::difference_type,
typename iterator_traits<_RanIt>::pointer,
typename iterator_traits<_RanIt>::reference>
{ // wrap iterator to run it backwards
public:
typedef reverse_iterator<_RanIt> _Myt;
typedef typename iterator_traits<_RanIt>::difference_type difference_type;
typedef typename iterator_traits<_RanIt>::pointer pointer;
typedef typename iterator_traits<_RanIt>::reference reference;
typedef _RanIt iterator_type;
reverse_iterator()
{ // construct with default wrapped iterator
}
explicit reverse_iterator(_RanIt _Right)
: current(_Right)
{ // construct wrapped iterator from _Right
}
template<class _Other>
reverse_iterator(const reverse_iterator<_Other>& _Right)
: current(_Right.base())
{ // initialize with compatible base
}
_RanIt base() const
{ // return wrapped iterator
return (current);
}
reference operator*() const
{ // return designated value
_RanIt _Tmp = current;
return (*--_Tmp);
}
pointer operator->() const
{ // return pointer to class object
return (&**this);
}
_Myt& operator++()
{ // preincrement
--current;
return (*this);
}
_Myt operator++(int)
{ // postincrement
_Myt _Tmp = *this;
--current;
return (_Tmp);
}
_Myt& operator--()
{ // predecrement
++current;
return (*this);
}
_Myt operator--(int)
{ // postdecrement
_Myt _Tmp = *this;
++current;
return (_Tmp);
}
bool _Equal(const _Myt& _Right) const
{ // test for iterator equality
return (current == _Right.current);
}
// N.B. functions valid for random-access iterators only beyond this point
_Myt& operator+=(difference_type _Off)
{ // increment by integer
current -= _Off;
return (*this);
}
_Myt operator+(difference_type _Off) const
{ // return this + integer
return (_Myt(current - _Off));
}
_Myt& operator-=(difference_type _Off)
{ // decrement by integer
current += _Off;
return (*this);
}
_Myt operator-(difference_type _Off) const
{ // return this - integer
return (_Myt(current + _Off));
}
reference operator[](difference_type _Off) const
{ // subscript
return (*(*this + _Off));
}
bool _Less(const _Myt& _Right) const
{ // test if this < _Right
return (_Right.current < current);
}
difference_type _Minus(const _Myt& _Right) const
{ // return difference of iterators
return (_Right.current - current);
}
protected:
_RanIt current; // the wrapped iterator
};
// reverse_iterator TEMPLATE OPERATORS
template<class _RanIt,
class _Diff> inline
reverse_iterator<_RanIt> __cdecl operator+(_Diff _Off,
const reverse_iterator<_RanIt>& _Right)
{ // return reverse_iterator + integer
return (_Right + _Off);
}
template<class _RanIt> inline
size_t __cdecl operator-(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // return difference of reverse_iterators
return (_Left._Minus(_Right));
}
template<class _RanIt> inline
bool __cdecl operator==(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator equality
return (_Left._Equal(_Right));
}
template<class _RanIt> inline
bool __cdecl operator!=(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator inequality
return (!(_Left == _Right));
}
template<class _RanIt> inline
bool __cdecl operator<(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator < reverse_iterator
return (_Left._Less(_Right));
}
template<class _RanIt> inline
bool __cdecl operator>(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator > reverse_iterator
return (_Right < _Left);
}
template<class _RanIt> inline
bool __cdecl operator<=(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator <= reverse_iterator
return (!(_Right < _Left));
}
template<class _RanIt> inline
bool __cdecl operator>=(const reverse_iterator<_RanIt>& _Left,
const reverse_iterator<_RanIt>& _Right)
{ // test for reverse_iterator >= reverse_iterator
return (!(_Left < _Right));
}
// TEMPLATE CLASS reverse_bidirectional_iterator (retained)
template<class _BidIt,
class _Ty,
class _Reference = _Ty&,
class _Pointer = _Ty *,
class _Diff = ptrdiff_t>
class reverse_bidirectional_iterator
: public _Bidit<_Ty, _Diff, _Pointer, _Reference>
{ // wrap bidirectional iterator to run it backwards
public:
typedef reverse_bidirectional_iterator<_BidIt, _Ty, _Reference,
_Pointer, _Diff> _Myt;
typedef _BidIt iterator_type;
reverse_bidirectional_iterator()
{ // construct with default wrapped iterator
}
explicit reverse_bidirectional_iterator(_BidIt _Right)
: current(_Right)
{ // construct wrapped iterator from _Right
}
_BidIt base() const
{ // return wrapped iterator
return (current);
}
_Reference operator*() const
{ // return designated value
_BidIt _Tmp = current;
return (*--_Tmp);
}
_Pointer operator->() const
{ // return pointer to class object
_Reference _Tmp = **this;
return (&_Tmp);
}
_Myt& operator++()
{ // preincrement
--current;
return (*this);
}
_Myt operator++(int)
{ // postincrement
_Myt _Tmp = *this;
--current;
return (_Tmp);
}
_Myt& operator--()
{ // predecrement
++current;
return (*this);
}
_Myt operator--(int)
{ // postdecrement
_Myt _Tmp = *this;
++current;
return (_Tmp);
}
bool operator==(const _Myt& _Right) const
{ // test for iterator equality
return (current == _Right.current);
}
bool operator!=(const _Myt& _Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}
protected:
_BidIt current; // the wrapped iterator
};
// TEMPLATE CLASS _Revbidit
template<class _BidIt,
class _BidIt2 = _BidIt>
class _Revbidit
: public iterator<
typename iterator_traits<_BidIt>::iterator_category,
typename iterator_traits<_BidIt>::value_type,
typename iterator_traits<_BidIt>::difference_type,
typename iterator_traits<_BidIt>::pointer,
typename iterator_traits<_BidIt>::reference>
{ // wrap bidirectional iterator to run it backwards
public:
typedef _Revbidit<_BidIt, _BidIt2> _Myt;
typedef typename iterator_traits<_BidIt>::difference_type _Diff;
typedef typename iterator_traits<_BidIt>::pointer _Pointer;
typedef typename iterator_traits<_BidIt>::reference _Reference;
typedef _BidIt iterator_type;
_Revbidit()
{ // construct with default wrapped iterator
}
explicit _Revbidit(_BidIt _Right)
: current(_Right)
{ // construct wrapped iterator from _Right
}
_Revbidit(const _Revbidit<_BidIt2>& _Other)
: current (_Other.base())
{ // const converter or copy constructor
}
_BidIt base() const
{ // return wrapped iterator
return (current);
}
_Reference operator*() const
{ // return designated value
_BidIt _Tmp = current;
return (*--_Tmp);
}
_Pointer operator->() const
{ // return pointer to class object
_Reference _Tmp = **this;
return (&_Tmp);
}
_Myt& operator++()
{ // preincrement
--current;
return (*this);
}
_Myt operator++(int)
{ // postincrement
_Myt _Tmp = *this;
--current;
return (_Tmp);
}
_Myt& operator--()
{ // predecrement
++current;
return (*this);
}
_Myt operator--(int)
{ // postdecrement
_Myt _Tmp = *this;
++current;
return (_Tmp);
}
bool operator==(const _Myt& _Right) const
{ // test for iterator equality
return (current == _Right.current);
}
bool operator!=(const _Myt& _Right) const
{ // test for iterator inequality
return (!(*this == _Right));
}
protected:
_BidIt current;
};
// TEMPLATE CLASS istreambuf_iterator
template<class _Elem,
class _Traits>
class istreambuf_iterator
: public iterator<input_iterator_tag,
_Elem, typename _Traits::off_type, _Elem *, _Elem&>
{ // wrap stream buffer as input iterator
public:
typedef istreambuf_iterator<_Elem, _Traits> _Myt;
typedef _Elem char_type;
typedef _Traits traits_type;
typedef basic_streambuf<_Elem, _Traits> streambuf_type;
typedef basic_istream<_Elem, _Traits> istream_type;
typedef typename traits_type::int_type int_type;
istreambuf_iterator(streambuf_type *_Sb = 0) _THROW0()
: _Strbuf(_Sb), _Got(_Sb == 0)
{ // construct from stream buffer _Sb
}
istreambuf_iterator(istream_type& _Istr) _THROW0()
: _Strbuf(_Istr.rdbuf()), _Got(_Istr.rdbuf() == 0)
{ // construct from stream buffer in istream _Istr
}
_Elem operator*() const
{ // return designated value
if (!_Got)
((_Myt *)this)->_Peek();
return (_Val);
}
_Myt& operator++()
{ // preincrement
_Inc();
return (*this);
}
_Myt operator++(int)
{ // postincrement
if (!_Got)
_Peek();
_Myt _Tmp = *this;
_Inc();
return (_Tmp);
}
bool equal(const _Myt& _Right) const
{ // test for equality
if (!_Got)
((_Myt *)this)->_Peek();
if (!_Right._Got)
((_Myt *)&_Right)->_Peek();
return (_Strbuf == 0 && _Right._Strbuf == 0
|| _Strbuf != 0 && _Right._Strbuf != 0);
}
private:
void _Inc()
{ // skip to next input element
if (_Strbuf == 0
|| traits_type::eq_int_type(traits_type::eof(),
_Strbuf->sbumpc()))
_Strbuf = 0, _Got = true;
else
_Got = false;
}
_Elem _Peek()
{ // peek at next input element
int_type _Meta;
if (_Strbuf == 0
|| traits_type::eq_int_type(traits_type::eof(),
_Meta = _Strbuf->sgetc()))
_Strbuf = 0;
else
_Val = traits_type::to_char_type(_Meta);
_Got = true;
return (_Val);
}
streambuf_type *_Strbuf; // the wrapped stream buffer
bool _Got; // true if _Val is valid
_Elem _Val; // next element to deliver
};
// istreambuf_iterator TEMPLATE OPERATORS
template<class _Elem,
class _Traits> inline
bool __cdecl operator==(
const istreambuf_iterator<_Elem, _Traits>& _Left,
const istreambuf_iterator<_Elem, _Traits>& _Right)
{ // test for istreambuf_iterator equality
return (_Left.equal(_Right));
}
template<class _Elem,
class _Traits> inline
bool __cdecl operator!=(
const istreambuf_iterator<_Elem, _Traits>& _Left,
const istreambuf_iterator<_Elem, _Traits>& _Right)
{ // test for istreambuf_iterator inequality
return (!(_Left == _Right));
}
// TEMPLATE CLASS ostreambuf_iterator
template<class _Elem,
class _Traits>
class ostreambuf_iterator
: public _Outit
{ // wrap stream buffer as output iterator
typedef ostreambuf_iterator<_Elem, _Traits> _Myt;
public:
typedef _Elem char_type;
typedef _Traits traits_type;
typedef basic_streambuf<_Elem, _Traits> streambuf_type;
typedef basic_ostream<_Elem, _Traits> ostream_type;
ostreambuf_iterator(streambuf_type *_Sb) _THROW0()
: _Failed(false), _Strbuf(_Sb)
{ // construct from stream buffer _Sb
}
ostreambuf_iterator(ostream_type& _Ostr) _THROW0()
: _Failed(false), _Strbuf(_Ostr.rdbuf())
{ // construct from stream buffer in _Ostr
}
_Myt& operator=(_Elem _Right)
{ // store element and increment
if (_Strbuf == 0
|| traits_type::eq_int_type(_Traits::eof(),
_Strbuf->sputc(_Right)))
_Failed = true;
return (*this);
}
_Myt& operator*()
{ // pretend to get designated element
return (*this);
}
_Myt& operator++()
{ // pretend to preincrement
return (*this);
}
_Myt& operator++(int)
{ // pretend to postincrement
return (*this);
}
bool failed() const _THROW0()
{ // return true if any stores failed
return (_Failed);
}
private:
bool _Failed; // true if any stores have failed
streambuf_type *_Strbuf; // the wrapped stream buffer
};
// ALGORITHM STUFF (from <algorithm>)
// TEMPLATE FUNCTION copy
template<class _InIt,
class _OutIt> inline
_OutIt copy(_InIt _First, _InIt _Last, _OutIt _Dest)
{ // copy [_First, _Last) to [_Dest, ...)
return (_Copy_opt(_First, _Last, _Dest, _Ptr_cat(_First, _Dest)));
}
template<class _InIt,
class _OutIt> inline
_OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
_Nonscalar_ptr_iterator_tag)
{ // copy [_First, _Last) to [_Dest, ...), arbitrary iterators
for (; _First != _Last; ++_Dest, ++_First)
*_Dest = *_First;
return (_Dest);
}
template<class _InIt,
class _OutIt> inline
_OutIt _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
_Scalar_ptr_iterator_tag)
{ // copy [_First, _Last) to [_Dest, ...), pointers to scalars
ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move
return ((_OutIt)::memmove(&*_Dest, &*_First,
_Off * sizeof (*_First)) + _Off);
}
// TEMPLATE FUNCTION copy_backward
template<class _BidIt1,
class _BidIt2> inline
_BidIt2 copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest)
{ // copy [_First, _Last) backwards to [..., _Dest)
return (_Copy_backward_opt(_First, _Last, _Dest,
_Ptr_cat(_First, _Dest)));
}
template<class _BidIt1,
class _BidIt2> inline
_BidIt2 _Copy_backward_opt(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest,
_Nonscalar_ptr_iterator_tag)
{ // copy [_First, _Last) backwards to [..., _Dest), arbitrary iterators
while (_First != _Last)
*--_Dest = *--_Last;
return (_Dest);
}
template<class _InIt,
class _OutIt> inline
_OutIt _Copy_backward_opt(_InIt _First, _InIt _Last, _OutIt _Dest,
_Scalar_ptr_iterator_tag)
{ // copy [_First, _Last) backwards to [..., _Dest), pointers to scalars
ptrdiff_t _Off = _Last - _First; // NB: non-overlapping move
return ((_OutIt)memmove(&*_Dest - _Off, &*_First,
_Off * sizeof (*_First)));
}
// TEMPLATE FUNCTION mismatch
template<class _InIt1,
class _InIt2> inline
pair<_InIt1, _InIt2>
mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch
for (; _First1 != _Last1 && *_First1 == *_First2; )
++_First1, ++_First2;
return (pair<_InIt1, _InIt2>(_First1, _First2));
}
// TEMPLATE FUNCTION mismatch WITH PRED
template<class _InIt1,
class _InIt2,
class _Pr> inline
pair<_InIt1, _InIt2>
mismatch(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred)
{ // return [_First1, _Last1) and [_First2, _Last2) mismatch using _Pred
for (; _First1 != _Last1 && _Pred(*_First1, *_First2); )
++_First1, ++_First2;
return (pair<_InIt1, _InIt2>(_First1, _First2));
}
// TEMPLATE FUNCTION equal
template<class _InIt1,
class _InIt2> inline
bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2)
{ // compare [_First1, _Last1) to [First2, ...)
return (mismatch(_First1, _Last1, _First2).first == _Last1);
}
inline bool equal(const char *_First1,
const char *_Last1, const char *_First2)
{ // compare [_First1, _Last1) to [First2, ...), for chars
return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
}
inline bool equal(const signed char *_First1,
const signed char *_Last1, const signed char *_First2)
{ // compare [_First1, _Last1) to [First2, ...), for signed chars
return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
}
inline bool equal(const unsigned char *_First1,
const unsigned char *_Last1, const unsigned char *_First2)
{ // compare [_First1, _Last1) to [First2, ...), for unsigned chars
return (::memcmp(_First1, _First2, _Last1 - _First1) == 0);
}
// TEMPLATE FUNCTION equal WITH PRED
template<class _InIt1,
class _InIt2,
class _Pr> inline
bool equal(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Pr _Pred)
{ // compare [_First1, _Last1) to [First2, ...) using _Pred
return (mismatch(_First1, _Last1, _First2, _Pred).first == _Last1);
}
// TEMPLATE FUNCTION fill
template<class _FwdIt,
class _Ty> inline
void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
{ // copy _Val through [_First, _Last)
for (; _First != _Last; ++_First)
*_First = _Val;
}
inline void fill(char *_First, char *_Last, int _Val)
{ // copy char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}
inline void fill(signed char *_First, signed char *_Last, int _Val)
{ // copy signed char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}
inline void fill(unsigned char *_First, unsigned char *_Last, int _Val)
{ // copy unsigned char _Val through [_First, _Last)
::memset(_First, _Val, _Last - _First);
}
// TEMPLATE FUNCTION fill_n
template<class _OutIt,
class _Diff,
class _Ty> inline
void fill_n(_OutIt _First, _Diff _Count, const _Ty& _Val)
{ // copy _Val _Count times through [_First, ...)
for (; 0 < _Count; --_Count, ++_First)
*_First = _Val;
}
inline void fill_n(char *_First, size_t _Count, int _Val)
{ // copy char _Val _Count times through [_First, ...)
::memset(_First, _Val, _Count);
}
inline void fill_n(signed char *_First, size_t _Count, int _Val)
{ // copy signed char _Val _Count times through [_First, ...)
::memset(_First, _Val, _Count);
}
inline void fill_n(unsigned char *_First, size_t _Count, int _Val)
{ // copy unsigned char _Val _Count times through [_First, ...)
::memset(_First, _Val, _Count);
}
// TEMPLATE FUNCTION lexicographical_compare
template<class _InIt1,
class _InIt2> inline
bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1,
_InIt2 _First2, _InIt2 _Last2)
{ // order [_First1, _Last1) vs. [First2, Last2)
for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2)
if (*_First1 < *_First2)
return (true);
else if (*_First2 < *_First1)
return (false);
return (_First1 == _Last1 && _First2 != _Last2);
}
inline bool lexicographical_compare(
const unsigned char *_First1, const unsigned char *_Last1,
const unsigned char *_First2, const unsigned char *_Last2)
{ // order [_First1, _Last1) vs. [First2, Last2), for unsigned char
ptrdiff_t _Num1 = _Last1 - _First1;
ptrdiff_t _Num2 = _Last2 - _First2;
int _Ans = ::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2);
return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2);
}
#if CHAR_MAX == UCHAR_MAX
inline bool lexicographical_compare(
const char *_First1, const char *_Last1,
const char *_First2, const char *_Last2)
{ // order [_First1, _Last1) vs. [First2, Last2), for nonnegative char
ptrdiff_t _Num1 = _Last1 - _First1;
ptrdiff_t _Num2 = _Last2 - _First2;
int _Ans = ::memcmp(_First1, _First2, _Num1 < _Num2 ? _Num1 : _Num2);
return (_Ans < 0 || _Ans == 0 && _Num1 < _Num2);
}
#endif
// TEMPLATE FUNCTION lexicographical_compare WITH PRED
template<class _InIt1,
class _InIt2,
class _Pr> inline
bool lexicographical_compare(_InIt1 _First1, _InIt1 _Last1,
_InIt2 _First2, _InIt2 _Last2, _Pr _Pred)
{ // order [_First1, _Last1) vs. [First2, Last2) using _Pred
for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2)
if (_Pred(*_First1, *_First2))
return (true);
else if (_Pred(*_First2, *_First1))
return (false);
return (_First1 == _Last1 && _First2 != _Last2);
}
#ifndef _MAX /* avoid collision with common (nonconforming) macros */
#define _MAX (max)
#define _MIN (min)
#endif
// TEMPLATE FUNCTION max
template<class _Ty> inline
const _Ty& _MAX(const _Ty& _Left, const _Ty& _Right)
{ // return larger of _Left and _Right
return (_Left < _Right ? _Right : _Left);
}
// TEMPLATE FUNCTION max WITH PRED
template<class _Ty,
class _Pr> inline
const _Ty& _MAX(const _Ty& _Left, const _Ty& _Right, _Pr _Pred)
{ // return larger of _Left and _Right using _Pred
return (_Pred(_Left, _Right) ? _Right : _Left);
}
// TEMPLATE FUNCTION min
template<class _Ty> inline
const _Ty& _MIN(const _Ty& _Left, const _Ty& _Right)
{ // return smaller of _Left and _Right
return (_Right < _Left ? _Right : _Left);
}
// TEMPLATE FUNCTION min WITH PRED
template<class _Ty,
class _Pr> inline
const _Ty& _MIN(const _Ty& _Left, const _Ty& _Right, _Pr _Pred)
{ // return smaller of _Left and _Right using _Pred
return (_Pred(_Right, _Left) ? _Right : _Left);
}
#ifndef _cpp_max /* retained from VC++ 6.0 */
#define _cpp_max max /* retained */
#define _cpp_min min /* retained */
#endif
#pragma warning(default:4786)
_STD_END
#pragma warning(pop)
#pragma pack(pop)
#endif /* _XUTILITY_ */
/*
* 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 */