windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/swrast/inc/tree.h

954 lines
30 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
template< class Key, class T, class ExtractKey, class CompareKey, class Allocator>
class RBTree
{
public: // Types
typedef RBTree< Key, T, ExtractKey, CompareKey, Allocator> tree_type;
typedef Allocator allocator_type;
typedef Key key_type;
typedef typename allocator_type::value_type value_type;
typedef CompareKey key_compare;
typedef ExtractKey key_extract;
typedef typename allocator_type::pointer pointer;
typedef typename allocator_type::const_pointer const_pointer;
typedef typename allocator_type::reference reference;
typedef typename allocator_type::const_reference const_reference;
typedef typename allocator_type::size_type size_type;
typedef typename allocator_type::difference_type difference_type;
protected: // Types
struct tree_node;
typedef typename Allocator::rebind< tree_node>::other
tree_node_allocator_type;
typedef typename tree_node_allocator_type::pointer tree_node_pointer;
typedef typename tree_node_allocator_type::const_pointer
tree_node_const_pointer;
struct tree_node
{
tree_node_pointer m_pLeft;
tree_node_pointer m_pParent;
tree_node_pointer m_pRight;
value_type m_Value;
bool m_bRed;
tree_node( const tree_node_pointer& pP, const value_type& v, bool bRed)
:m_pLeft( NULL), m_pParent( pP), m_pRight( NULL), m_Value( v),
m_bRed( bRed)
{ }
~tree_node()
{ }
};
template< class TPointer>
struct NextInOrderNode:
public unary_function< TPointer, TPointer>
{
result_type operator()( argument_type Arg, const bool bCouldBeEnd) const
{
if( bCouldBeEnd&& Arg->m_bRed&& Arg->m_pParent->m_pParent== Arg)
Arg= Arg->m_pLeft;
else if( Arg->m_pRight!= NULL)
{
Arg= Arg->m_pRight;
while( Arg->m_pLeft!= NULL)
Arg= Arg->m_pLeft;
}
else
{
TPointer pP;
while( Arg== (pP= Arg->m_pParent)->m_pRight)
Arg= pP;
if( bCouldBeEnd|| Arg->m_pRight!= pP)
Arg= pP;
}
return Arg;
}
};
template< class TPointer>
struct PrevInOrderNode:
public unary_function< TPointer, TPointer>
{
result_type operator()( argument_type Arg, const bool bCouldBeEnd) const
{
if( bCouldBeEnd&& Arg->m_bRed&& Arg->m_pParent->m_pParent== Arg)
Arg= Arg->m_pRight;
else if( Arg->m_pLeft!= NULL)
{
Arg= Arg->m_pLeft;
while( Arg->m_pRight!= NULL)
Arg= Arg->m_pRight;
}
else
{
TPointer pP;
while( Arg== (pP= Arg->m_pParent)->m_pLeft)
Arg= pP;
if( bCouldBeEnd|| Arg->m_pLeft!= pP)
Arg= pP;
}
return Arg;
}
};
public: // Types
class iterator;
class const_iterator;
class reverse_iterator;
class const_reverse_iterator;
friend class iterator;
class iterator
{
public: // Types
typedef bidirectional_iterator_tag iterator_category;
typedef value_type value_type;
typedef difference_type difference_type;
typedef pointer pointer;
typedef reference reference;
friend class const_iterator;
friend class reverse_iterator;
friend class const_reverse_iterator;
friend class RBTree< Key, T, ExtractKey, CompareKey, Allocator>;
protected:
tree_node_pointer m_pNode;
NextInOrderNode< tree_node_pointer> m_fnNext;
PrevInOrderNode< tree_node_pointer> m_fnPrev;
public:
iterator()
{ }
explicit iterator( const tree_node_pointer& pN)
:m_pNode( pN)
{ }
iterator( const iterator& Other)
:m_pNode( Other.m_pNode)
{ }
iterator( const reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
reference operator*() const
{ return m_pNode->m_Value; }
pointer operator->() const
{ return &**this; }
iterator& operator++()
{
// end()++ is not valid.
m_pNode= m_fnNext( m_pNode, false);
return (*this);
}
iterator operator++( int)
{
iterator Temp( *this);
++(*this);
return Temp;
}
iterator& operator--()
{
// end()-- is valid.
m_pNode= m_fnPrev( m_pNode, true);
return (*this);
}
iterator operator--( int)
{
iterator Temp( *this);
--(*this);
return (Temp);
}
bool operator==( const iterator& Other) const
{ return m_pNode== Other.m_pNode; }
bool operator!=( const iterator& Other) const
{ return m_pNode!= Other.m_pNode; }
};
friend class const_iterator;
class const_iterator
{
public: // Types
typedef bidirectional_iterator_tag iterator_category;
typedef value_type value_type;
typedef difference_type difference_type;
typedef const_pointer pointer;
typedef const_reference reference;
friend class const_reverse_iterator;
friend class RBTree< Key, T, ExtractKey, CompareKey, Allocator>;
protected:
tree_node_const_pointer m_pNode;
NextInOrderNode< tree_node_const_pointer> m_fnNext;
PrevInOrderNode< tree_node_const_pointer> m_fnPrev;
public:
const_iterator()
{ }
explicit const_iterator( const tree_node_const_pointer& pN)
:m_pNode( pN)
{ }
const_iterator( const iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_iterator( const const_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_iterator( const reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_iterator( const const_reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
reference operator*() const
{ return m_pNode->m_Value; }
pointer operator->() const
{ return &**this; }
const_iterator& operator++()
{
// end()++ is not valid.
m_pNode= m_fnNext( m_pNode, false);
return (*this);
}
const_iterator operator++( int)
{
iterator Temp( *this);
++(*this);
return Temp;
}
const_iterator& operator--()
{
// end()-- is valid.
m_pNode= m_fnPrev( m_pNode, true);
return (*this);
}
const_iterator operator--( int)
{
iterator Temp( *this);
--(*this);
return (Temp);
}
bool operator==( const const_iterator& Other) const
{ return m_pNode== Other.m_pNode; }
bool operator!=( const const_iterator& Other) const
{ return m_pNode!= Other.m_pNode; }
};
friend class reverse_iterator;
class reverse_iterator
{
public: // Types
typedef bidirectional_iterator_tag iterator_category;
typedef value_type value_type;
typedef difference_type difference_type;
typedef pointer pointer;
typedef reference reference;
friend class iterator;
friend class const_iterator;
friend class const_reverse_iterator;
friend class RBTree< Key, T, ExtractKey, CompareKey, Allocator>;
protected:
tree_node_pointer m_pNode;
PrevInOrderNode< tree_node_pointer> m_fnNext;
NextInOrderNode< tree_node_pointer> m_fnPrev;
public:
reverse_iterator()
{ }
explicit reverse_iterator( const tree_node_pointer& pN)
:m_pNode( pN)
{ }
reverse_iterator( const iterator& Other)
:m_pNode( Other.m_pNode)
{ }
reverse_iterator( const reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
reference operator*() const
{ return m_pNode->m_Value; }
pointer operator->() const
{ return &**this; }
reverse_iterator& operator++()
{
// rend()++ is not valid.
m_pNode= m_fnNext( m_pNode, false);
return (*this);
}
reverse_iterator operator++( int)
{
iterator Temp( *this);
++(*this);
return Temp;
}
reverse_iterator& operator--()
{
// rend()-- is valid.
m_pNode= m_fnPrev( m_pNode, true);
return (*this);
}
reverse_iterator operator--( int)
{
iterator Temp( *this);
--(*this);
return (Temp);
}
bool operator==( const reverse_iterator& Other) const
{ return m_pNode== Other.m_pNode; }
bool operator!=( const reverse_iterator& Other) const
{ return m_pNode!= Other.m_pNode; }
};
friend class const_reverse_iterator;
class const_reverse_iterator
{
public: // Types
typedef bidirectional_iterator_tag iterator_category;
typedef value_type value_type;
typedef difference_type difference_type;
typedef const_pointer pointer;
typedef const_reference reference;
friend class const_iterator;
friend class RBTree< Key, T, ExtractKey, CompareKey, Allocator>;
protected:
tree_node_const_pointer m_pNode;
PrevInOrderNode< tree_node_const_pointer> m_fnNext;
NextInOrderNode< tree_node_const_pointer> m_fnPrev;
public:
const_reverse_iterator()
{ }
explicit const_reverse_iterator( const tree_node_const_pointer& pN)
:m_pNode( pN)
{ }
const_reverse_iterator( const iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_reverse_iterator( const const_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_reverse_iterator( const reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
const_reverse_iterator( const const_reverse_iterator& Other)
:m_pNode( Other.m_pNode)
{ }
reference operator*() const
{ return m_pNode->m_Value; }
pointer operator->() const
{ return &**this; }
const_reverse_iterator& operator++()
{
// rend()++ is not valid.
m_pNode= m_fnNext( m_pNode, false);
return (*this);
}
const_reverse_iterator operator++( int)
{
iterator Temp( *this);
++(*this);
return Temp;
}
const_reverse_iterator& operator--()
{
// rend()-- is valid.
m_pNode= m_fnPrev( m_pNode, true);
return (*this);
}
const_reverse_iterator operator--( int)
{
iterator Temp( *this);
--(*this);
return (Temp);
}
bool operator==( const const_reverse_iterator& Other) const
{ return m_pNode== Other.m_pNode; }
bool operator!=( const const_reverse_iterator& Other) const
{ return m_pNode!= Other.m_pNode; }
};
protected: // Variables
tree_node_pointer m_pHead;
size_type m_uiNodes;
key_compare m_key_compare;
key_extract m_key_extract;
tree_node_allocator_type m_allocator;
protected: // Functions
void BuildHeadNode()
{
m_pHead= m_allocator.allocate( 1);
new (&m_pHead->m_pLeft) tree_node_pointer( m_pHead);
new (&m_pHead->m_pParent) tree_node_pointer( NULL);
new (&m_pHead->m_pRight) tree_node_pointer( m_pHead);
new (&m_pHead->m_bRed) bool( true);
}
void DestroyHeadNode()
{
m_pHead->m_pLeft.~list_node_pointer();
m_pHead->m_pParent.~list_node_pointer();
m_pHead->m_pRight.~list_node_pointer();
m_pHead->m_bRed.~bool();
m_allocator.deallocate( m_pHead, 1);
}
void RotateLeft( tree_node_pointer pX)
{
tree_node_pointer pY( pX->m_pRight);
pX->m_pRight= pY->m_pLeft;
if( pY->m_pLeft!= NULL)
pY->m_pLeft->m_pParent= pX;
pY->m_pParent= pX->m_pParent;
if( pX== m_pHead->m_pParent)
m_pHead->m_pParent= pY;
else if( pX== pX->m_pParent->m_pLeft)
pX->m_pParent->m_pLeft= pY;
else
pX->m_pParent->m_pRight= pY;
pY->m_pLeft= pX;
pX->m_pParent= pY;
}
void RotateRight( tree_node_pointer pX)
{
tree_node_pointer pY( pX->m_pLeft);
pX->m_pLeft= pY->m_pRight;
if( pY->m_pRight!= NULL)
pY->m_pRight->m_pParent= pX;
pY->m_pParent= pX->m_pParent;
if( pX== m_pHead->m_pParent)
m_pHead->m_pParent= pY;
else if( pX== pX->m_pParent->m_pRight)
pX->m_pParent->m_pRight= pY;
else
pX->m_pParent->m_pLeft= pY;
pY->m_pRight= pX;
pX->m_pParent= pY;
}
void RecDelete( tree_node_pointer pX)
{
for( tree_node_pointer pY( pX); pY!= NULL; pX= pY)
{
RecDelete( pY->m_pRight);
pY= pY->m_pLeft;
m_allocator.destroy( pX);
m_allocator.deallocate( pX, 1);
}
}
tree_node_pointer lowerbound( const key_type& k) const
{
tree_node_pointer pX( m_pHead->m_pParent);
tree_node_pointer pY( m_pHead);
while( pX!= NULL)
{
if( m_key_compare( m_key_extract( pX->m_Value), k))
pX= pX->m_pRight;
else
{
pY= pX;
pX= pX->m_pLeft;
}
}
return pY;
}
tree_node_pointer upperbound( const key_type& k) const
{
tree_node_pointer pX( m_pHead->m_pParent);
tree_node_pointer pY( m_pHead);
while( pX!= NULL)
{
if( m_key_compare( k, m_key_extract( pX->m_Value)))
{
pY= pX;
pX= pX->m_pLeft;
}
else
pX= pX->m_pRight;
}
return pY;
}
iterator Insert( tree_node_pointer pX,
tree_node_pointer pY, const value_type& V)
{
tree_node_pointer pZ( m_allocator.allocate( 1));
m_allocator.construct( pZ, tree_node( pY, V, true));
++m_uiNodes;
if( pY== m_pHead|| pX!= NULL||
m_key_compare( m_key_extract( V), m_key_extract( pY->m_Value)))
{
pY->m_pLeft= pZ;
if( pY== m_pHead)
{
m_pHead->m_pParent= pZ;
m_pHead->m_pRight= pZ;
}
else if( pY== m_pHead->m_pLeft)
m_pHead->m_pLeft= pZ;
}
else
{
pY->m_pRight= pZ;
if( pY== m_pHead->m_pRight)
m_pHead->m_pRight= pZ;
}
for( pX= pZ; pX!= m_pHead->m_pParent&& pX->m_pParent->m_bRed; )
{
if( pX->m_pParent== pX->m_pParent->m_pParent->m_pLeft)
{
pY= pX->m_pParent->m_pParent->m_pRight;
if( pY!= NULL&& pY->m_bRed)
{
pX->m_pParent->m_bRed= false;
pY->m_bRed= false;
pX->m_pParent->m_pParent->m_bRed= true;
pX= pX->m_pParent->m_pParent;
}
else
{
if( pX== pX->m_pParent->m_pRight)
{
pX= pX->m_pParent;
RotateLeft( pX);
}
pX->m_pParent->m_bRed= false;
pX->m_pParent->m_pParent->m_bRed= true;
RotateRight( pX->m_pParent->m_pParent);
}
}
else
{
pY= pX->m_pParent->m_pParent->m_pLeft;
if( pY!= NULL&& pY->m_bRed)
{
pX->m_pParent->m_bRed= false;
pY->m_bRed= false;
pX->m_pParent->m_pParent->m_bRed= true;
pX= pX->m_pParent->m_pParent;
}
else
{
if( pX== pX->m_pParent->m_pLeft)
{
pX= pX->m_pParent;
RotateRight( pX);
}
pX->m_pParent->m_bRed= false;
pX->m_pParent->m_pParent->m_bRed= true;
RotateLeft( pX->m_pParent->m_pParent);
}
}
}
m_pHead->m_pParent->m_bRed= false;
return iterator( pZ);
}
public: // Functions
iterator begin()
{ return iterator( m_pHead->m_pLeft); }
const_iterator begin() const
{ return const_iterator( m_pHead->m_pLeft); }
iterator end()
{ return iterator( m_pHead); }
const_iterator end() const
{ return const_iterator( m_pHead); }
reverse_iterator rbegin()
{ return reverse_iterator( m_pHead->m_pRight); }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator( m_pHead->m_pRight); }
reverse_iterator rend()
{ return reverse_iterator( m_pHead); }
const_reverse_iterator rend() const
{ return const_reverse_iterator( m_pHead); }
size_type size() const
{ return m_uiNodes; }
size_type max_size() const
{ return m_allocator.max_size(); }
bool empty() const
{ return 0== size(); }
key_compare key_comp() const
{ return m_key_compare; }
explicit RBTree( const CompareKey& CmpKey= CompareKey(), const ExtractKey&
ExKey= ExtractKey(), const Allocator& A= Allocator()): m_pHead( NULL),
m_uiNodes( 0), m_key_compare( CmpKey), m_key_extract( ExKey),
m_allocator( A)
{
BuildHeadNode();
}
RBTree( const tree_type& Other): m_pHead( NULL), m_uiNodes( 0),
m_key_compare( Other.m_key_compare), m_key_extract( Other.m_key_extract),
m_allocator( Other.m_allocator)
{
BuildHeadNode();
try {
*this= Other;
} catch( ... ) {
clear();
DestroyHeadNode();
throw;
}
}
~RBTree()
{
clear();
DestroyHeadNode();
}
tree_type& operator=( const tree_type& x)
{
if( this!= &x)
{
erase( begin(), end());
m_key_compare= x.m_key_compare;
m_key_extract= x.m_key_extract;
insert_equal( x.begin(), x.end());
}
return (*this);
}
allocator_type get_allocator() const
{ return m_allocator; }
void swap( const tree_type& x)
{
swap( m_key_compare, x.m_key_compare);
swap( m_key_extract, x.m_key_extract);
if( m_allocator== x.m_allocator)
{
swap( m_pHead, x.m_pHead);
swap( m_uiNodes, x.m_uiNodes);
}
else
{
tree_type Temp( *this);
*this= x;
x= Temp;
}
}
friend void swap( tree_type& x, tree_type& y)
{ x.swap( y); }
pair< iterator, bool> insert_unique( const value_type& x)
{
tree_node_pointer pA( m_pHead->m_pParent);
tree_node_pointer pB( m_pHead);
const key_type XKey( m_key_extract( x));
bool bCmp( true);
while( pA!= NULL)
{
pB= pA;
bCmp= m_key_compare( XKey, m_key_extract( pA->m_Value));
pA= (bCmp? pA->m_pLeft: pA->m_pRight);
}
iterator itP( pB);
if( bCmp)
{
if( itP== begin())
return pair< iterator, bool>( Insert( pA, pB, x), true);
else
--itP;
}
if( m_key_compare( m_key_extract( itP.m_pNode->m_Value), XKey))
return pair< iterator, bool>( Insert( pA, pB, x), true);
return pair< iterator, bool>( itP, false);
}
iterator insert_unique( iterator pP, const value_type& x)
{
return insert_unique( x).first;
}
template< class ForwardIterator>
void insert_unique( ForwardIterator f, ForwardIterator l)
{
while( f!= l)
{
insert_unique( *f);
++f;
}
}
iterator insert_equal( const value_type& x)
{
tree_node_pointer pA( m_pHead->m_pParent);
tree_node_pointer pB( m_pHead);
const key_type XKey( m_key_extract( x));
bool bCmp( true);
while( pA!= NULL)
{
pB= pA;
bCmp= m_key_compare( XKey, m_key_extract( pA->m_Value));
pA= (bCmp? pA->m_pLeft: pA->m_pRight);
}
return iterator( Insert( pA, pB, x));
}
iterator insert_equal( iterator pP, const value_type& x)
{
return insert_equal( x);
}
template< class ForwardIterator>
void insert_equal( ForwardIterator f, ForwardIterator l)
{
while( f!= l)
{
insert_equal( *f);
++f;
}
}
iterator erase( iterator itDel)
{
tree_node_pointer pW;
tree_node_pointer pX;
tree_node_pointer pY( itDel.m_pNode);
tree_node_pointer pZ( pY);
++itDel;
if( pY->m_pLeft== NULL)
pX= pY->m_pRight;
else if( pY->m_pRight== NULL)
pX= pY->m_pLeft;
else
{
pY= pY->m_pRight;
while( pY->m_pLeft!= NULL)
pY= pY->m_pLeft;
pX= pY->m_pRight;
}
tree_node_pointer pXParent( pY);
if( pY!= pZ)
{
pZ->m_pLeft->m_pParent= pY;
pY->m_pLeft= pZ->m_pLeft;
if( pY== pZ->m_pRight)
(pX!= NULL? pX->m_pParent= pXParent= pY: pXParent= pY);
else
{
(pX!= NULL? pX->m_pParent= pXParent= pY->m_pParent: pXParent= pY->m_pParent);
pY->m_pParent->m_pLeft= pX;
pY->m_pRight= pZ->m_pRight;
pZ->m_pRight->m_pParent= pY;
}
if( m_pHead->m_pParent== pZ)
m_pHead->m_pParent= pY;
else if( pZ->m_pParent->m_pLeft== pZ)
pZ->m_pParent->m_pLeft= pY;
else
pZ->m_pParent->m_pRight= pY;
pY->m_pParent= pZ->m_pParent;
const bool bTmp( pY->m_bRed);
pY->m_bRed= pZ->m_bRed;
pZ->m_bRed= bTmp;
pY= pZ;
}
else
{
(pX!= NULL? pX->m_pParent= pXParent= pY->m_pParent: pXParent= pY->m_pParent);
if( m_pHead->m_pParent== pZ)
m_pHead->m_pParent= pX;
else if( pZ->m_pParent->m_pLeft== pZ)
pZ->m_pParent->m_pLeft= pX;
else
pZ->m_pParent->m_pRight= pX;
if( m_pHead->m_pLeft== pZ)
{
if( pZ->m_pRight== NULL)
m_pHead->m_pLeft= pZ->m_pParent;
else
{
m_pHead->m_pLeft= pX;
while( m_pHead->m_pLeft->m_pLeft!= NULL)
m_pHead->m_pLeft= m_pHead->m_pLeft->m_pLeft;
}
}
if( m_pHead->m_pRight== pZ)
{
if( pZ->m_pLeft== NULL)
m_pHead->m_pRight= pZ->m_pParent;
else
{
m_pHead->m_pRight= pX;
while( m_pHead->m_pRight->m_pRight!= NULL)
m_pHead->m_pRight= m_pHead->m_pRight->m_pRight;
}
}
}
if( !pY->m_bRed)
{
while( pX!= m_pHead->m_pParent&& (pX== NULL|| !pX->m_bRed))
{
if( pX== pXParent->m_pLeft)
{
pW= pXParent->m_pRight;
if( pW->m_bRed)
{
pW->m_bRed= false;
pXParent->m_bRed= true;
RotateLeft( pXParent);
pW= pXParent->m_pRight;
}
if( (pW->m_pLeft== NULL|| !pW->m_pLeft->m_bRed)&&
(pW->m_pRight== NULL|| !pW->m_pRight->m_bRed) )
{
pW->m_bRed= true;
pX= pXParent;
pXParent= pXParent->m_pParent;
}
else
{
if( pW->m_pRight== NULL|| !pW->m_pRight->m_bRed)
{
pW->m_pLeft->m_bRed= false;
pW->m_bRed= true;
RotateRight( pW);
pW= pXParent->m_pRight;
}
pW->m_bRed= pXParent->m_bRed;
pXParent->m_bRed= false;
pW->m_pRight->m_bRed= false;
RotateLeft( pXParent);
break;
}
}
else
{
pW= pXParent->m_pLeft;
if( pW->m_bRed)
{
pW->m_bRed= false;
pXParent->m_bRed= true;
RotateRight( pXParent);
pW= pXParent->m_pLeft;
}
if( (pW->m_pLeft== NULL|| !pW->m_pLeft->m_bRed)&&
(pW->m_pRight== NULL|| !pW->m_pRight->m_bRed) )
{
pW->m_bRed= true;
pX= pXParent;
pXParent= pXParent->m_pParent;
}
else
{
if( pW->m_pLeft== NULL|| !pW->m_pLeft->m_bRed)
{
pW->m_pRight->m_bRed= false;
pW->m_bRed= true;
RotateLeft( pW);
pW= pXParent->m_pLeft;
}
pW->m_bRed= pXParent->m_bRed;
pXParent->m_bRed= false;
pW->m_pLeft->m_bRed= false;
RotateRight( pXParent);
break;
}
}
}
if( pX!= NULL)
pX->m_bRed= false;
}
m_allocator.destroy( pY);
m_allocator.deallocate( pY, 1);
--m_uiNodes;
return itDel;
}
iterator erase( iterator f, iterator l)
{
if( 0== size()|| f!= begin() || l!= end())
{
while( f!= l)
f= erase( f);
return f;
}
clear();
return begin();
}
size_type erase( const key_type& k)
{
const pair< iterator, iterator> EqRng( equal_range( k));
size_type n( 0);
iterator itCur( EqRng.first);
while( itCur!= EqRng.second)
{
++itCur;
++n;
}
erase( EqRng.first, EqRng.second);
return n;
}
void clear()
{
RecDelete( m_pHead->m_pParent);
m_uiNodes= 0;
m_pHead->m_pParent= NULL;
m_pHead->m_pRight= m_pHead->m_pLeft= m_pHead;
}
iterator find( const key_type& k)
{
iterator itLB( lower_bound( k));
return( itLB== end()|| m_key_compare( k, m_key_extract(
itLB.m_pNode->m_Value))? end(): itLB);
}
const_iterator find( const key_type& k) const
{
const_iterator itLB( lower_bound( k));
return( itLB== end()|| m_key_compare( k, m_key_extract(
itLB.m_pNode->m_Value))? end(): itLB);
}
size_type count( const key_type& k) const
{
const pair< const_iterator, const_iterator> EqRng( equal_range( k));
size_type n( 0);
const_iterator itCur( EqRng.first);
while( itCur!= EqRng.second)
{
++itCur;
++n;
}
return n;
}
iterator lower_bound( const key_type& k)
{ return iterator( lowerbound( k)); }
const_iterator lower_bound( const key_type& k) const
{ return const_iterator( lowerbound( k)); }
iterator upper_bound( const key_type& k)
{ return iterator( upperbound( k)); }
const_iterator upper_bound( const key_type& k) const
{ return const_iterator( upperbound( k)); }
pair< iterator, iterator> equal_range( const key_type& k)
{ return pair< iterator, iterator>( lower_bound( k), upper_bound( k)); }
pair< const_iterator, const_iterator> equal_range( const key_type& k) const
{ return pair< const_iterator, const_iterator>( lower_bound( k), upper_bound( k)); }
#if 0
pair< bool, int> InValid( tree_node_pointer pNode, tree_node_pointer pParent, bool bParentRed)
{
pair< bool, int> RightRet( false, 1);
if( pNode->m_pRight!= NULL)
RightRet= InValid( pNode->m_pRight, pNode, pNode->m_bRed);
pair< bool, int> LeftRet( false, 1);
if( pNode->m_pLeft!= NULL)
LeftRet= InValid( pNode->m_pLeft, pNode, pNode->m_bRed);
return pair< bool, int>( pNode->m_pParent!= pParent|| RightRet.first|| LeftRet.first||
RightRet.second!= LeftRet.second|| (bParentRed&& pNode->m_bRed),
RightRet.second+ (pNode->m_bRed? 0: 1));
}
bool valid()
{
if( m_pHead->m_pParent!= NULL)
{
bool bInvalid( InValid( m_pHead->m_pParent, m_pHead, m_pHead->m_bRed).first);
tree_node_pointer pChk= m_pHead->m_pParent;
while( pChk->m_pLeft!= NULL)
pChk= pChk->m_pLeft;
bInvalid|= (pChk!= m_pHead->m_pLeft);
pChk= m_pHead->m_pParent;
while( pChk->m_pRight!= NULL)
pChk= pChk->m_pRight;
bInvalid|= (pChk!= m_pHead->m_pRight);
return !bInvalid;
}
else
return true;
}
#endif
};