刚开始接触Map的时候,了解到Map采用映射的方式储存数据,为了满足自己的好奇心,自己参考相关书籍,并且调试Linux系统的Map源码,成功完成了Map完整代码的封装。
总体来说Windows系统Map与Linux系统Map采用了相同的实现思路,只是实现细节有点较小的差异。
同样采用相同的数据结构红黑树做为Map内核链表绑定数据的存储路线(代码内部有Window、Linux系统红黑树相关的实现)。
Map主要分为两大模块调用:
1.Map类:
键值数据的管理以及传送给Tree_node对应的红黑树的节点。
2.Tree_node(节点类):
调用适配器完成键值配对,创建、增加红黑树节点以及完成红黑树节点与键值的绑定。
下面贴上代码:(VS2010直接使用)
/*
*
*Map结构(Linux内核)完整实现
*
*李坤昱
*[email protected]
*
*/
#include <map>
struct Test_input_iterator_tag //数据类型,Move函数中做为参数的原型的基类
{ // identifying tag for input iterators
};
struct Test_output_iterator_tag
{ // identifying tag for output iterators
};
struct Test_forward_iterator_tag
: public Test_input_iterator_tag, Test_output_iterator_tag
{ // identifying tag for Test_forward iterators
};
struct Test_bidirectional_iterator_tag
: public Test_forward_iterator_tag
{ // identifying tag for bidirectional iterators
};
struct Test_random_access_iterator_tag
: public Test_bidirectional_iterator_tag
{ // identifying tag for random-access iterators
};
struct Test_Int_iterator_tag
{ // identifying tag for integer types, not an iterator
};
// POINTER ITERATOR TAGS
struct Test_Nonscalar_ptr_iterator_tag
{ // pointer to unknown type
};
struct Test_Scalar_ptr_iterator_tag
{ // pointer to scalar type
};
template<typename _Tp>
class Test_new_allocator//Linux源码中做为内存分配的基类,在本代码中没有实际用途
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct Test_rebind
{ typedef Test_new_allocator<_Tp1> other; };
pointer Test_allocator(int size,const void* = 0)
{
return new (size * sizeof(_Tp));
}
void
deallocate(pointer __p, size_type)
{
::operator delete(__p);
}
};
template<typename _Tp>
class Test_allocator;
/// allocator<void> specialization.
template<>
class Test_allocator<void>
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template<typename _Tp1>
struct Test_rebind
{
typedef Test_allocator<_Tp1> other;
};
};
template<typename _Tp>
class Test_allocator //本例子中,通过这个类创建,删除内存
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
typedef _Tp value_type;
template<typename _Tp1>
struct Test_rebind
{
typedef Test_allocator<_Tp1> other;
};
Test_allocator() throw() { }
Test_allocator(const Test_allocator& __a) throw() { }
template<typename _Tp1>
Test_allocator(const Test_allocator<_Tp1>&) throw() { }
~Test_allocator() throw() { }
pointer
allocate(size_type __n, const void* = 0)
{
//if (__builtin_expect(__n > this->max_size(), false))
// std::__throw_bad_alloc();
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
}
size_type
max_size() const throw()
{ return size_t(-1) / sizeof(_Tp); }
void destroy(pointer _Ptr)
{ // destroy object at _Ptr
_Destroy(_Ptr);
}
template<class _Ty> inline
void _Destroy(_Ty _FARQ *_Ptr)
{ // destroy object at _Ptr
_Ptr->~_Ty();
}
void
deallocate(pointer __p, size_type)
{ ::operator delete(__p); }
void
construct(pointer __p, const _Tp& __val)
{
::new((void *)__p) _Tp(__val);
}
// Inherit everything else.
};
struct Test__false_type { };
template<typename, typename>
struct Test__are_same
{
enum { Test__value = 0 };
typedef Test__false_type __type;
};
template<bool _IsMove, typename _II, typename _OI>
inline _OI
Test__copy_move_a(_II __first, _II __last, _OI __result)
{
typedef typename iterator_traits<_II>::value_type _ValueTypeI;
typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
typedef typename iterator_traits<_II>::iterator_category _Category;
const bool __simple = (__is_pod(_ValueTypeI)
&& __is_pointer<_II>::Test__value
&& __is_pointer<_OI>::Test__value
&& Test__are_same<_ValueTypeI, _ValueTypeO>::Test__value);
return std::__copy_move<_IsMove, __simple,
_Category>::__copy_m(__first, __last, __result);
}
template<typename _Tp>
struct Test__is_char
{
enum { Test__value = 0 };
typedef Test__false_type __type;
};
template<bool _IsMove, typename _II, typename _OI>
inline _OI
Test__copy_move_a2(_II __first, _II __last, _OI __result)
{
return _OI(Test__copy_move_a<_IsMove>
(std::__niter_base<_II>::__b(__first),
std::__niter_base<_II>::__b(__last),
std::__niter_base<_OI>::__b(__result)));
}
template<typename _II, typename _OI>
inline _OI
Test_move(_II __first, _II __last, _OI __result)
{
// concept requirements
// __glibcxx_function_requires(_InputIteratorConcept<_II>)
// __glibcxx_function_requires(_OutputIteratorConcept<_OI,
// typename iterator_traits<_II>::value_type>)
// __glibcxx_requires_valid_range(__first, __last);
return (Test__copy_move_a2<true>
(std::__miter_base<_II>::__b(__first),
std::__miter_base<_II>::__b(__last), __result));
}
template<class _Ty>
struct Test_identity
{ // map _Ty to type unchanged
typedef _Ty type;
const _Ty& operator()(const _Ty& _Left) const
{ // apply Test_identity operator to operand
return (_Left);
}
};
template<class _Ty> inline
_Ty&& Test_forward(typename Test_identity<_Ty>::type& _Arg)//返回_Arg的类型
{ // Test_forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}
template<class _Ty>
struct Test_Remove_reference
{ // remove reference
typedef _Ty _Type;
};
template<class _Ty>
struct Test_Remove_reference<_Ty&>
{ // remove reference
typedef _Ty _Type;
};
template<class _Ty>
struct Test_Remove_reference<_Ty&&>
{ // remove rvalue reference
typedef _Ty _Type;
};
template<class _Ty>
struct remove_reference
: Test_Remove_reference<_Ty>
{ // remove reference
typedef typename Test_Remove_reference<_Ty>::_Type type;
};
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type& //提示无法从int 转换为int&& ,随修改
Test_move(_Tp& __t)
{
return __t;
}
template<class _Ty1,
class _Ty2>
struct Test_Pair_base//适配器的基类
{ // store a Testpair of values
typedef Test_Pair_base<_Ty1, _Ty2> _Myt;
typedef _Ty1 first_type;
typedef _Ty2 second_type;
Test_Pair_base()
: first(_Ty1()), second(_Ty2())
{ // construct from defaults
}
Test_Pair_base(const Test_Pair_base<_Ty1, _Ty2>& _Right)
: first(_Right.first), second(_Right.second)
{ // construct by copying Test_Pair_base
}
Test_Pair_base(const _Ty1& _Val1, const _Ty2& _Val2)
: first(_Val1), second(_Val2)
{ // construct from specified values
}
Test_Pair_base(_Ty1&& _Val1, _Ty2&& _Val2)
: first( Test_move(_Val1)),
second( Test_move(_Val2))
{ // construct from specified values
}
Test_Pair_base(const _Ty1& _Val1, _Ty2&& _Val2)
: first(_Val1), second( Test_move(_Val2))
{ // construct from specified values
}
Test_Pair_base(_Ty1&& _Val1, const _Ty2& _Val2)
: first( Test_move(_Val1)), second(_Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2>
Test_Pair_base(_Other1&& _Val1, _Other2&& _Val2)
: first( Test_forward<_Other1>(_Val1)),
second( Test_forward<_Other2>(_Val2))
{ // construct from moved values
}
_Ty1 first; // the first stored value
_Ty2 second; // the second stored value
};
template<class _Ty1,
class _Ty2>
struct Testpair
: public Test_Pair_base<_Ty1, _Ty2>
{ // store a Testpair of values
typedef Test_Pair_base<_Ty1, _Ty2> _Mybase;
typedef Testpair<_Ty1, _Ty2> _Myt;
typedef _Ty1 first_type;
typedef _Ty2 second_type;
Testpair()
: _Mybase()
{ // construct from defaults
}
Testpair(const _Ty1& _Val1, const _Ty2& _Val2)
: _Mybase(_Val1, _Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2>
Testpair(Testpair<_Other1, _Other2>& _Right)
: _Mybase(_Right.first, _Right.second)
{ // construct from compatible Testpair
}
template<class _Other1,
class _Other2>
Testpair(const Testpair<_Other1, _Other2>& _Right)
: _Mybase(_Right.first, _Right.second)
{ // construct from compatible Testpair
}
void swap(_Myt& _Right)
{ // exchange contents with _Right
if (this != &_Right)
{ // different, worth swapping
_Swap_adl(this->first, _Right.first);
_Swap_adl(this->second, _Right.second);
}
}
_Myt& operator=(const _Myt& _Right)
{ // assign from copied Testpair
this->first = _Right.first;
this->second = _Right.second;
return (*this);
}
Testpair(_Ty1&& _Val1, _Ty2&& _Val2)
: _Mybase( Test_move(_Val1),
Test_move(_Val2))
{ // construct from specified values
}
Testpair(const _Ty1& _Val1, _Ty2&& _Val2)
: _Mybase(_Val1,
Test_move(_Val2))
{ // construct from specified values
}
Testpair(_Ty1&& _Val1, const _Ty2& _Val2)
: _Mybase(Test_move(_Val1),
_Val2)
{ // construct from specified values
}
template<class _Other1,
class _Other2>
Testpair(_Other1&& _Val1, _Other2&& _Val2)
: _Mybase( Test_forward<_Other1>(_Val1),
Test_forward<_Other2>(_Val2))
{ // construct from moved values
}
template<class _Other1,
class _Other2>
Testpair(Testpair<_Other1, _Other2>&& _Right)
: _Mybase( Test_forward<_Other1>(_Right.first),
Test_forward<_Other2>(_Right.second))
{ // construct from moved compatible Testpair
}
Testpair& operator=(Testpair<_Ty1, _Ty2>&& _Right)
{ // assign from moved Testpair
this->first = Test_move(_Right.first);
this->second = Test_move(_Right.second);
return (*this);
}
void swap(_Myt&& _Right)
{ // exchange contents with _Right
if (this != &_Right)
{ // different, worth swapping
this->first = Test_move(_Right.first);
this->second = Test_move(_Right.second);
}
}
};
// Testpair TEMPLATE FUNCTIONS
template<class _Ty1,
class _Ty2> inline
void swap(Testpair<_Ty1, _Ty2>& _Left, Testpair<_Ty1, _Ty2>& _Right)
{ // swap _Left and _Right pairs
_Left.swap(_Right);
}
template<class _Ty1,
class _Ty2> inline
void swap(Testpair<_Ty1, _Ty2>& _Left, Testpair<_Ty1, _Ty2>&& _Right)
{ // swap _Left and _Right pairs
typedef Testpair<_Ty1, _Ty2> _Myt;
_Left.swap( Test_forward<_Myt>(_Right));
}
template<class _Ty1,
class _Ty2> inline
void swap(Testpair<_Ty1, _Ty2>&& _Left, Testpair<_Ty1, _Ty2>& _Right)
{ // swap _Left and _Right pairs
typedef Testpair<_Ty1, _Ty2> _Myt;
_Right.swap( Test_forward<_Myt>(_Left));
}
template<class _Ty1,
class _Ty2> inline
bool operator==(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test for Testpair equality
return (_Left.first == _Right.first && _Left.second == _Right.second);
}
template<class _Ty1,
class _Ty2> inline
bool operator!=(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test for Testpair inequality
return (!(_Left == _Right));
}
template<class _Ty1,
class _Ty2> inline
bool operator<(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test if _Left < _Right for pairs
return (_Left.first < _Right.first ||
!(_Right.first < _Left.first) && _Left.second < _Right.second);
}
template<class _Ty1,
class _Ty2> inline
bool operator>(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test if _Left > _Right for pairs
return (_Right < _Left);
}
template<class _Ty1,
class _Ty2> inline
bool operator<=(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test if _Left <= _Right for pairs
return (!(_Right < _Left));
}
template<class _Ty1,
class _Ty2> inline
bool operator>=(const Testpair<_Ty1, _Ty2>& _Left,
const Testpair<_Ty1, _Ty2>& _Right)
{ // test if _Left >= _Right for pairs
return (!(_Left < _Right));
}
template<class _Type>
struct Test_Unrefwrap
{ // unwrap a reference_wrapper
typedef _Type type;
};
template<class _Ty1,
class _Ty2> inline
Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type>
Test_make_pair(_Ty1&& _Val1, _Ty2&& _Val2)
{ // return Testpair composed from arguments
typedef Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair( Test_forward<_Ty1>(_Val1),
Test_forward<_Ty2>(_Val2)));
}
template<class _Ty1,
class _Ty2> inline
Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type>
Test_make_pair(const _Ty1& _Val1, _Ty2&& _Val2)
{ // return Testpair composed from arguments
typedef Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair((typename Test_Unrefwrap<_Ty1>::type)_Val1,
Test_forward<_Ty2>(_Val2)));
}
template<class _Ty1,
class _Ty2> inline
Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type>
Test_make_pair(_Ty1&& _Val1, const _Ty2& _Val2)
{ // return Testpair composed from arguments
typedef Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair( Test_forward<_Ty1>(_Val1),
(typename Test_Unrefwrap<_Ty2>::type)_Val2));
}
template<class _Ty1,
class _Ty2> inline
Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type>
Test_make_pair(const _Ty1& _Val1, const _Ty2& _Val2)
{ // return Testpair composed from arguments
typedef Testpair<typename Test_Unrefwrap<_Ty1>::type,
typename Test_Unrefwrap<_Ty2>::type> _Mypair;
return (_Mypair((typename Test_Unrefwrap<_Ty1>::type)_Val1,
(typename Test_Unrefwrap<_Ty2>::type)_Val2));
}
#if _HAS_CPP0X
template<class _InIt> inline
_InIt begin(const Testpair<_InIt, _InIt>& _Pair)
{ // return first element of Testpair
return (_Pair.first);
}
template<class _InIt> inline
_InIt end(const Testpair<_InIt, _InIt>& _Pair)
{ // return second element of Testpair
return (_Pair.second);
}
#endif /* _HAS_CPP0X */
// TEMPLATE OPERATORS
// namespace rel_ops
// { // nested namespace to hide relational operators from std
template<class _Ty> inline
bool operator!=(const _Ty& _Left, const _Ty& _Right)
{ // test for inequality, in terms of equality
return (!(_Left == _Right));
}
template<class _Ty> inline
bool operator>(const _Ty& _Left, const _Ty& _Right)
{ // test if _Left > _Right, in terms of operator<
return (_Right < _Left);
}
template<class _Ty> inline
bool operator<=(const _Ty& _Left, const _Ty& _Right)
{ // test if _Left <= _Right, in terms of operator<
return (!(_Right < _Left));
}
template<class _Ty> inline
bool operator>=(const _Ty& _Left, const _Ty& _Right)
{ // test if _Left >= _Right, in terms of operator<
return (!(_Left < _Right));
}
//}
// TUPLE INTERFACE TO tr1::Testpair
template<class _Tuple>
struct tuple_size;
template<size_t _Idx,
class _Tuple>
struct tuple_element;
template<class _Ty1,
class _Ty2>
struct tuple_size<Testpair<_Ty1, _Ty2> >
{ // struct to determine number of elements in Testpair
static const int value = 2;
};
template<int _Idx,
class _Ty>
struct Test_Pair_data;
template<class _Ty1,
class _Ty2>
struct Test_Pair_data<0, Testpair<_Ty1, _Ty2> >
{ // struct to pick out argument type and value at index 0
typedef _Ty1& _Type;
typedef const _Ty1& _CType;
static _Type _Val( Testpair<_Ty1, _Ty2>& _Pr)
{ // return value
return (_Pr.first);
}
static _CType _Val(const Testpair<_Ty1, _Ty2>& _Pr)
{ // return value
return (_Pr.first);
}
};
enum Test_Rb_tree_color { _S_red = false, _S_black = true };
struct Test_Rb_tree_node_base//红黑树的基类,Map的内核结构
{
typedef Test_Rb_tree_node_base* Test_Base_ptr;
typedef const Test_Rb_tree_node_base* Test_Const_Base_ptr;
Test_Rb_tree_color _M_color;
Test_Base_ptr _M_parent;
Test_Base_ptr _M_left;
Test_Base_ptr _M_right;
static Test_Base_ptr
_S_minimum(Test_Base_ptr __x)
{
while (__x->_M_left != 0) __x = __x->_M_left;
return __x;
}
static Test_Const_Base_ptr
_S_minimum(Test_Const_Base_ptr __x)
{
while (__x->_M_left != 0) __x = __x->_M_left;
return __x;
}
static Test_Base_ptr
_S_maximum(Test_Base_ptr __x)
{
while (__x->_M_right != 0) __x = __x->_M_right;
return __x;
}
static Test_Const_Base_ptr
_S_maximum(Test_Const_Base_ptr __x)
{
while (__x->_M_right != 0) __x = __x->_M_right;
return __x;
}
};
template<typename _Val>
struct Test_Rb_tree_node : public Test_Rb_tree_node_base//红黑树数据结构与键值的绑定
{
typedef Test_Rb_tree_node<_Val>* Test_Link_type;
_Val _M_value_field;
// template<typename... _Args>
// Test_Rb_tree_node(_Args&&... __args)
// : Test_Rb_tree_node_base(),
// _M_value_field(std::Test_forward<_Args>(__args)...) { }
};
template<typename _Tp>
struct Test_Rb_tree_iterator//迭代器的功能在这个类中实现
{
typedef _Tp value_type;
typedef _Tp& reference;
typedef _Tp* pointer;
typedef Test_bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
typedef Test_Rb_tree_iterator<_Tp> _Self;
typedef Test_Rb_tree_node_base::Test_Base_ptr Test_Base_ptr;
typedef Test_Rb_tree_node<_Tp>* Test_Link_type;
Test_Rb_tree_iterator()
: _M_node() { }
explicit
Test_Rb_tree_iterator(Test_Link_type __x)
: _M_node(__x) { }
reference
operator*() const
{
return static_cast<Test_Link_type>(_M_node)->_M_value_field;
}
pointer
operator->() const
{
return &static_cast<Test_Link_type>(_M_node)->_M_value_field;
}
_Self&
operator++()
{
_M_node = Test_Rb_tree_increment(_M_node);
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = Test_Rb_tree_increment(_M_node);
return __tmp;
}
_Self&
operator--()
{
_M_node = Test_Rb_tree_decrement(_M_node);
return *this;
}
_Self
operator--(int)
{
_Self __tmp = *this;
_M_node = Test_Rb_tree_decrement(_M_node);
return __tmp;
}
bool
operator==(const _Self& __x) const
{
return _M_node == __x._M_node;
}
bool
operator!=(const _Self& __x) const
{
return _M_node != __x._M_node;
}
Test_Rb_tree_node_base* Test_Rb_tree_increment(Test_Rb_tree_node_base* __x)//
{
if (__x->_M_right != 0)
{
__x = __x->_M_right;
while (__x->_M_left != 0)
__x = __x->_M_left;
}
else
{
Test_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_right)
{
__x = __y;
__y = __y->_M_parent;
}
if (__x->_M_right != __y)
{
__x = __y;
}
}
return __x;
}
Test_Rb_tree_node_base*
Test_Rb_tree_decrement(Test_Rb_tree_node_base* __x)
{
if (__x->_M_color == _S_red && __x->_M_parent->_M_parent == __x)
__x = __x->_M_right;
else if (__x->_M_left != 0)
{
Test_Rb_tree_node_base* __y = __x->_M_left;
while (__y->_M_right != 0)
__y = __y->_M_right;
__x = __y;
}
else
{
Test_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_left)
{
__x = __y;
__y = __y->_M_parent;
}
__x = __y;
}
return __x;
}
Test_Base_ptr _M_node;
};
template<typename _Tp>
struct Test_Rb_tree_const_iterator
{
typedef _Tp value_type;
typedef const _Tp& reference;
typedef const _Tp* pointer;
typedef Test_Rb_tree_iterator<_Tp> iterator;
typedef Test_bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
typedef Test_Rb_tree_const_iterator<_Tp> _Self;
typedef Test_Rb_tree_node_base::Test_Const_Base_ptr Test_Base_ptr;
typedef const Test_Rb_tree_node<_Tp>* Test_Link_type;
Test_Rb_tree_const_iterator()
: _M_node() { }
explicit
Test_Rb_tree_const_iterator(Test_Link_type __x)
: _M_node(__x) { }
Test_Rb_tree_const_iterator(const iterator& __it)
: _M_node(__it._M_node) { }
reference
operator*() const
{
return static_cast<Test_Link_type>(_M_node)->_M_value_field;
}
pointer
operator->() const
{
return &static_cast<Test_Link_type>(_M_node)->_M_value_field;
}
_Self&
operator++()
{
_M_node = Test_Rb_tree_increment(_M_node);
return *this;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = Test_Rb_tree_increment(_M_node);
return __tmp;
}
_Self&
operator--()
{
_M_node = Test_Rb_tree_decrement(_M_node);
return *this;
}
_Self
operator--(int)
{
_Self __tmp = *this;
_M_node = Test_Rb_tree_decrement(_M_node);
return __tmp;
}
bool
operator==(const _Self& __x) const
{
return _M_node == __x._M_node;
}
bool
operator!=(const _Self& __x) const
{
return _M_node != __x._M_node;
}
const Test_Rb_tree_node_base*
Test_Rb_tree_increment(const Test_Rb_tree_node_base* __x)
{
if (__x->_M_right != 0)
{
__x = __x->_M_right;
while (__x->_M_left != 0)
__x = __x->_M_left;
}
else
{
Test_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_right)
{
__x = __y;
__y = __y->_M_parent;
}
if (__x->_M_right != __y)
{
__x = __y;
}
}
return __x;
}
const Test_Rb_tree_node_base*
Test_Rb_tree_decrement(const Test_Rb_tree_node_base* __x)
{
if (__x->_M_color == _S_red && __x->_M_parent->_M_parent == __x)
__x = __x->_M_right;
else if (__x->_M_left != 0)
{
Test_Rb_tree_node_base* __y = __x->_M_left;
while (__y->_M_right != 0)
__y = __y->_M_right;
__x = __y;
}
else
{
Test_Rb_tree_node_base* __y = __x->_M_parent;
while (__x == __y->_M_left)
{
__x = __y;
__y = __y->_M_parent;
}
__x = __y;
}
return __x;
}
void Test_Rb_tree_insert_and_rebalance(const bool __insert_left,
Test_Rb_tree_node_base* __x,
Test_Rb_tree_node_base* __p,
Test_Rb_tree_node_base& __header)
{
if (__insert_left)
{
__x->_M_parent = __p;
__x->_M_parent->_M_parent = __p;
__x->_M_left = 0;
__x->_M_right = 0;
_Rb_tree_rebalance(__x,__header._M_parent);
return ;
}
__x->_M_parent = __p;
__x->_M_left = 0;
__x->_M_right = 0;
_Rb_tree_rebalance(__x,__header._M_parent);
}
Test_Base_ptr _M_node;
};
inline void
_Rb_tree_rotate_left(Test_Rb_tree_node_base* __x, Test_Rb_tree_node_base*& __root)//节点左旋转
{
Test_Rb_tree_node_base* __y = __x->_M_right;
__x->_M_right = __y->_M_left;
if (__y->_M_left !=0)
__y->_M_left->_M_parent = __x;
__y->_M_parent = __x->_M_parent;
if (__x == __root)
__root = __y;
else if (__x == __x->_M_parent->_M_left)
__x->_M_parent->_M_left = __y;
else
__x->_M_parent->_M_right = __y;
__y->_M_left = __x;
__x->_M_parent = __y;
}
inline void
_Rb_tree_rotate_right(Test_Rb_tree_node_base* __x, Test_Rb_tree_node_base*& __root)//节点右旋转
{
Test_Rb_tree_node_base* __y = __x->_M_left;
__x->_M_left = __y->_M_right;
if (__y->_M_right != 0)
__y->_M_right->_M_parent = __x;
__y->_M_parent = __x->_M_parent;
if (__x == __root)
__root = __y;
else if (__x == __x->_M_parent->_M_right)
__x->_M_parent->_M_right = __y;
else
__x->_M_parent->_M_left = __y;
__y->_M_right = __x;
__x->_M_parent = __y;
}
inline void
_Rb_tree_rebalance(Test_Rb_tree_node_base* __x, Test_Rb_tree_node_base*& __root)//Window红黑树数据结构内核
{
__x->_M_color = _S_red;
if (!__x->_M_parent->_M_parent)
{
return;
}
if (!__x->_M_parent->_M_parent->_M_right)
{
__x->_M_parent->_M_parent->_M_right = __x->_M_parent;
}
while (__x != __root && __x->_M_parent->_M_color == _S_red)
{
if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) {
Test_Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right;
if (__y && __y->_M_color == _S_red) {
__x->_M_parent->_M_color = _S_black;
__y->_M_color = _S_black;
__x->_M_parent->_M_parent->_M_color = _S_red;
__x = __x->_M_parent->_M_parent;
}
else {
if (__x == __x->_M_parent->_M_right) {
__x = __x->_M_parent;
_Rb_tree_rotate_left(__x, __root);
}
__x->_M_parent->_M_color = _S_black;
__x->_M_parent->_M_parent->_M_color = _S_red;
_Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root);
}
}
else {
Test_Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left;
if (__y && __y->_M_color == _S_red) {
__x->_M_parent->_M_color = _S_black;
__y->_M_color = _S_black;
__x->_M_parent->_M_parent->_M_color = _S_red;
__x = __x->_M_parent->_M_parent;
}
else {
if (__x == __x->_M_parent->_M_left) {
__x = __x->_M_parent;
_Rb_tree_rotate_right(__x, __root);
}
__x->_M_parent->_M_color = _S_black;
__x->_M_parent->_M_parent->_M_color = _S_red;
_Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root);
}
}
}
__root->_M_color = _S_black;
}
inline Test_Rb_tree_node_base*
Test_Rb_tree_rebalance_for_erase(Test_Rb_tree_node_base* __z,
/*Test_Rb_tree_node_base*& __root*/Test_Rb_tree_node_base& __root,
Test_Rb_tree_node_base*& __leftmost,
Test_Rb_tree_node_base*& __rightmost)
{
Test_Rb_tree_node_base* __y = __z;
Test_Rb_tree_node_base* __x = 0;
Test_Rb_tree_node_base* __x_parent = 0;
Test_Rb_tree_node_base* __root_ = &__root;
if (__y->_M_left == 0) // __z has at most one non-null child. y == z.
__x = __y->_M_right; // __x might be null.
else
if (__y->_M_right == 0) // __z has exactly one non-null child. y == z.
__x = __y->_M_left; // __x is not null.
else { // __z has two non-null children. Set __y to
__y = __y->_M_right; // __z's successor. __x might be null.
while (__y->_M_left != 0)
__y = __y->_M_left;
__x = __y->_M_right;
}
if (__y != __z) { // relink y in place of z. y is z's successor
__z->_M_left->_M_parent = __y;
__y->_M_left = __z->_M_left;
if (__y != __z->_M_right) {
__x_parent = __y->_M_parent;
if (__x) __x->_M_parent = __y->_M_parent;
__y->_M_parent->_M_left = __x; // __y must be a child of _M_left
__y->_M_right = __z->_M_right;
__z->_M_right->_M_parent = __y;
}
else
__x_parent = __y;
if (__root_ == __z)
__root_ = __y;
else if (__z->_M_parent->_M_left == __z)
__z->_M_parent->_M_left = __y;
else
__z->_M_parent->_M_right = __y;
__y->_M_parent = __z->_M_parent;
//swap(__y->_M_color, __z->_M_color);
__y = __z;
// __y now points to node to be actually deleted
}
else { // __y == __z
__x_parent = __y->_M_parent;
if (__x) __x->_M_parent = __y->_M_parent;
if (__root_ == __z)
__root_ = __x;
else
if (__z->_M_parent->_M_left == __z)
__z->_M_parent->_M_left = __x;
else
__z->_M_parent->_M_right = __x;
if (__leftmost == __z)
if (__z->_M_right == 0) // __z->_M_left must be null also
__leftmost = __z->_M_parent;
// makes __leftmost == _M_header if __z == __root
else
__leftmost = Test_Rb_tree_node_base::_S_minimum(__x);
if (__rightmost == __z)
if (__z->_M_left == 0) // __z->_M_right must be null also
__rightmost = __z->_M_parent;
// makes __rightmost == _M_header if __z == __root
else // __x == __z->_M_left
__rightmost = Test_Rb_tree_node_base::_S_maximum(__x);
}
if (__y->_M_color != _S_red) {
while (__x != __root_ && (__x == 0 || __x->_M_color == _S_black))
if (__x == __x_parent->_M_left) {
Test_Rb_tree_node_base* __w = __x_parent->_M_right;
if (__w->_M_color == _S_red) {
__w->_M_color = _S_black;
__x_parent->_M_color = _S_red;
_Rb_tree_rotate_left(__x_parent, __root_);
__w = __x_parent->_M_right;
}
if ((__w->_M_left == 0 ||
__w->_M_left->_M_color == _S_black) &&
(__w->_M_right == 0 ||
__w->_M_right->_M_color == _S_black)) {
__w->_M_color = _S_red;
__x = __x_parent;
__x_parent = __x_parent->_M_parent;
} else {
if (__w->_M_right == 0 ||
__w->_M_right->_M_color == _S_black) {
if (__w->_M_left) __w->_M_left->_M_color = _S_black;
__w->_M_color = _S_red;
_Rb_tree_rotate_right(__w, __root_);
__w = __x_parent->_M_right;
}
__w->_M_color = __x_parent->_M_color;
__x_parent->_M_color = _S_black;
if (__w->_M_right) __w->_M_right->_M_color = _S_black;
_Rb_tree_rotate_left(__x_parent, __root_);
break;
}
} else { // same as above, with _M_right <-> _M_left.
Test_Rb_tree_node_base* __w = __x_parent->_M_left;
if (__w->_M_color == _S_red) {
__w->_M_color = _S_black;
__x_parent->_M_color = _S_red;
_Rb_tree_rotate_right(__x_parent, __root_);
__w = __x_parent->_M_left;
}
if ((__w->_M_right == 0 ||
__w->_M_right->_M_color == _S_black) &&
(__w->_M_left == 0 ||
__w->_M_left->_M_color == _S_black)) {
__w->_M_color = _S_red;
__x = __x_parent;
__x_parent = __x_parent->_M_parent;
} else {
if (__w->_M_left == 0 ||
__w->_M_left->_M_color == _S_black) {
if (__w->_M_right) __w->_M_right->_M_color = _S_black;
__w->_M_color = _S_red;
_Rb_tree_rotate_left(__w, __root_);
__w = __x_parent->_M_left;
}
__w->_M_color = __x_parent->_M_color;
__x_parent->_M_color = _S_black;
if (__w->_M_left) __w->_M_left->_M_color = _S_black;
_Rb_tree_rotate_right(__x_parent, __root_);
break;
}
}
if (__x) __x->_M_color = _S_black;
}
return __y;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = Test_allocator<_Val> >
class Test_Rb_tree//红黑树的创建、增加以及删除节点和迭代器功能 通过此类调用
{
typedef typename _Alloc::template Test_rebind<Test_Rb_tree_node<_Val> >::other
Test_Node_allocator;
protected:
typedef Test_Rb_tree_node_base* Test_Base_ptr;
typedef const Test_Rb_tree_node_base* Test_Const_Base_ptr;
public:
typedef _Key key_type;
typedef _Val value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef Test_Rb_tree_node<_Val>* Test_Link_type;
typedef const Test_Rb_tree_node<_Val>* Test_Const_Link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
Test_Node_allocator&
Test_M_get_Node_allocator()
{
return *static_cast<Test_Node_allocator*>(&this->_M_impl);
}
const Test_Node_allocator&
Test_M_get_Node_allocator() const
{
return *static_cast<const Test_Node_allocator*>(&this->_M_impl);
}
allocator_type
get_allocator() const
{
return allocator_type(Test_M_get_Node_allocator());
}
protected:
Test_Link_type
Test_M_get_node()
{
return _M_impl.Test_Node_allocator::allocate(1);
}
void
Test_M_put_node(Test_Link_type __p)
{
_M_impl.Test_Node_allocator::deallocate(__p, 1);
}
#ifndef __GXX_EXPERIMENTAL_CXX0X__
Test_Link_type
Test_M_create_node(const value_type& __x)
{
Test_Link_type __tmp = Test_M_get_node();
try
{ get_allocator().construct(&__tmp->_M_value_field, __x); }
catch(...)
{
Test_M_put_node(__tmp);
throw;
}
return __tmp;
}
void
Test_M_destroy_node(Test_Link_type __p)
{
get_allocator().destroy(&__p->_M_value_field);
Test_M_put_node(__p);
}
#else
template<typename... _Args>
Test_Link_type
Test_M_create_node(_Args&&... __args)
{
Test_Link_type __tmp = Test_M_get_node();
__try
{
Test_M_get_Node_allocator().construct(__tmp,
std::Test_forward<_Args>(__args)...);
}
__catch(...)
{
Test_M_put_node(__tmp);
__throw_exception_again;
}
return __tmp;
}
void
Test_M_destroy_node(Test_Link_type __p)
{
Test_M_get_Node_allocator().destroy(__p);
Test_M_put_node(__p);
}
#endif
Test_Link_type
Test_M_clone_node(Test_Const_Link_type __x)
{
Test_Link_type __tmp = Test_M_create_node(__x->_M_value_field);
__tmp->_M_color = __x->_M_color;
__tmp->_M_left = 0;
__tmp->_M_right = 0;
return __tmp;
}
protected:
template<typename _Key_compare,
bool _Is_pod_comparator = __is_pod(_Key_compare)>
struct Test_Rb_tree_impl : public Test_Node_allocator
{
_Key_compare _M_key_compare;
Test_Rb_tree_node_base _M_header;
size_type _M_node_count; // Keeps track of size of tree.
Test_Rb_tree_impl()
: Test_Node_allocator(), _M_key_compare(), _M_header(),
_M_node_count(0)
{
Test_M_initialize();
}
Test_Rb_tree_impl(const _Key_compare& __comp, const Test_Node_allocator& __a)
: Test_Node_allocator(__a), _M_key_compare(__comp), _M_header(),
_M_node_count(0)
{
Test_M_initialize();
}
private:
void
Test_M_initialize()
{
this->_M_header._M_color = _S_red;
this->_M_header._M_parent = 0;
this->_M_header._M_left = &this->_M_header;
this->_M_header._M_right = &this->_M_header;
}
};
Test_Rb_tree_impl<_Compare> _M_impl;
protected:
Test_Base_ptr&
Test_M_root()
{
return this->_M_impl._M_header._M_parent;
}
Test_Const_Base_ptr
Test_M_root() const
{
return this->_M_impl._M_header._M_parent;
}
Test_Base_ptr&
_M_leftmost()
{
return this->_M_impl._M_header._M_left;
}
Test_Const_Base_ptr
_M_leftmost() const
{
return this->_M_impl._M_header._M_left;
}
Test_Base_ptr&
_M_rightmost()
{
return this->_M_impl._M_header._M_right;
}
Test_Const_Base_ptr
_M_rightmost() const
{
return this->_M_impl._M_header._M_right;
}
Test_Link_type
_M_begin()
{
return static_cast<Test_Link_type>(this->_M_impl._M_header._M_parent);
}
Test_Const_Link_type
_M_begin() const
{
return static_cast<Test_Const_Link_type>
(this->_M_impl._M_header._M_parent);
}
Test_Link_type
_M_end()
{
return static_cast<Test_Link_type>(&this->_M_impl._M_header);
}
Test_Const_Link_type
_M_end() const
{
return static_cast<Test_Const_Link_type>(&this->_M_impl._M_header);
}
static const_reference
_S_value(Test_Const_Link_type __x)
{
return __x->_M_value_field;
}
static const _Key&
_S_key(Test_Const_Link_type __x)
{
return _KeyOfValue()(_S_value(__x));
}
static Test_Link_type
_S_left(Test_Base_ptr __x)
{
return static_cast<Test_Link_type>(__x->_M_left);
}
static Test_Const_Link_type
_S_left(Test_Const_Base_ptr __x)
{
return static_cast<Test_Const_Link_type>(__x->_M_left);
}
static Test_Link_type
_S_right(Test_Base_ptr __x)
{
return static_cast<Test_Link_type>(__x->_M_right);
}
static Test_Const_Link_type
_S_right(Test_Const_Base_ptr __x)
{
return static_cast<Test_Const_Link_type>(__x->_M_right);
}
static const_reference
_S_value(Test_Const_Base_ptr __x)
{
return static_cast<Test_Const_Link_type>(__x)->_M_value_field;
}
static const _Key&
_S_key(Test_Const_Base_ptr __x)
{
return _KeyOfValue()(_S_value(__x));
}
static Test_Base_ptr
_S_minimum(Test_Base_ptr __x)
{
return Test_Rb_tree_node_base::_S_minimum(__x);
}
static Test_Const_Base_ptr
_S_minimum(Test_Const_Base_ptr __x)
{
return Test_Rb_tree_node_base::_S_minimum(__x);
}
static Test_Base_ptr
_S_maximum(Test_Base_ptr __x)
{
return Test_Rb_tree_node_base::_S_maximum(__x);
}
static Test_Const_Base_ptr
_S_maximum(Test_Const_Base_ptr __x)
{
return Test_Rb_tree_node_base::_S_maximum(__x);
}
public:
typedef Test_Rb_tree_iterator<value_type> iterator;
typedef Test_Rb_tree_const_iterator<value_type> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
private:
iterator
Test_M_insert_(Test_Const_Base_ptr __x, Test_Const_Base_ptr __y,
const value_type& __v);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 233. Insertion hints in associative containers.
iterator
Test_M_insert_lower(Test_Base_ptr __x, Test_Base_ptr __y, const value_type& __v);
iterator
Test_M_insert_equal_lower(const value_type& __x);
Test_Link_type
Test_M_copy(Test_Const_Link_type __x, Test_Link_type __p);
void
Test_M_erase(Test_Link_type __x);
iterator
Test_M_lower_bound(Test_Link_type __x, Test_Link_type __y,
const _Key& __k);
const_iterator
Test_M_lower_bound(Test_Const_Link_type __x, Test_Const_Link_type __y,
const _Key& __k) const;
iterator
Test_M_upper_bound(Test_Link_type __x, Test_Link_type __y,
const _Key& __k);
const_iterator
Test_M_upper_bound(Test_Const_Link_type __x, Test_Const_Link_type __y,
const _Key& __k) const;
public:
// allocation/deallocation
Test_Rb_tree() { }
Test_Rb_tree(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_impl(__comp, __a) { }
Test_Rb_tree(const Test_Rb_tree& __x)
: _M_impl(__x._M_impl._M_key_compare, __x.Test_M_get_Node_allocator())
{
if (__x.Test_M_root() != 0)
{
Test_M_root() = Test_M_copy(__x._M_begin(), _M_end());
_M_leftmost() = _S_minimum(Test_M_root());
_M_rightmost() = _S_maximum(Test_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
}
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
Test_Rb_tree(Test_Rb_tree&& __x);
#endif
~Test_Rb_tree()
{
Test_M_erase(_M_begin());
}
Test_Rb_tree&
operator=(const Test_Rb_tree& __x);
// Accessors.
_Compare
key_comp() const
{
return _M_impl._M_key_compare;
}
iterator
begin()
{
return iterator(static_cast<Test_Link_type>
(this->_M_impl._M_header._M_left));
}
const_iterator
begin() const
{
return const_iterator(static_cast<Test_Const_Link_type>
(this->_M_impl._M_header._M_left));
}
iterator
end()
{
return iterator(static_cast<Test_Link_type>(&this->_M_impl._M_header));
}
const_iterator
end() const
{
return const_iterator(static_cast<Test_Const_Link_type>
(&this->_M_impl._M_header));
}
reverse_iterator
rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator
rbegin() const
{
return const_reverse_iterator(end());
}
reverse_iterator
rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator
rend() const
{
return const_reverse_iterator(begin());
}
bool
empty() const
{
return _M_impl._M_node_count == 0;
}
size_type
size() const
{
return _M_impl._M_node_count;
}
size_type
max_size() const
{
return Test_M_get_Node_allocator().max_size();
}
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
swap(Test_Rb_tree&& __t);
#else
swap(Test_Rb_tree& __t);
#endif
// Insert/erase.
Testpair<iterator, bool>
Test_M_insert_unique(const value_type& __x);
iterator
Test_M_insert_equal(const value_type& __x);
iterator
Test_M_insert_unique_(const_iterator __position, const value_type& __x);
iterator
Test_M_insert_equal_(const_iterator __position, const value_type& __x);
template<typename _InputIterator>
void
Test_M_insert_unique(_InputIterator __first, _InputIterator __last);
template<typename _InputIterator>
void
Test_M_insert_equal(_InputIterator __first, _InputIterator __last);
void
erase(iterator __position);
void
erase(const_iterator __position);
size_type
erase(const key_type& __x);
void
erase(iterator __first, iterator __last);
void
erase(const_iterator __first, const_iterator __last);
void
erase(const key_type* __first, const key_type* __last);
void
clear()
{
Test_M_erase(_M_begin());
_M_leftmost() = _M_end();
Test_M_root() = 0;
_M_rightmost() = _M_end();
_M_impl._M_node_count = 0;
}
// Set operations.
iterator
find(const key_type& __k);
const_iterator
find(const key_type& __k) const;
size_type
count(const key_type& __k) const;
iterator
lower_bound(const key_type& __k)
{
return Test_M_lower_bound(_M_begin(), _M_end(), __k);
}
const_iterator
lower_bound(const key_type& __k) const
{
return Test_M_lower_bound(_M_begin(), _M_end(), __k);
}
iterator
upper_bound(const key_type& __k)
{ return Test_M_upper_bound(_M_begin(), _M_end(), __k); }
const_iterator
upper_bound(const key_type& __k) const
{
return Test_M_upper_bound(_M_begin(), _M_end(), __k);
}
Testpair<iterator, iterator>
equal_range(const key_type& __k);
Testpair<const_iterator, const_iterator>
equal_range(const key_type& __k) const;
// Debugging.
bool
__rb_verify() const;
void Test_Rb_tree_insert_and_rebalance(const bool __insert_left,
Test_Rb_tree_node_base* __x,
Test_Rb_tree_node_base* __p,
Test_Rb_tree_node_base& __header)//Linux红黑树结构内核实现
{
Test_Rb_tree_node_base **rootptrptr = &__header._M_parent;
__x->_M_parent = __p;
__x->_M_left = 0;
__x->_M_right = 0;
__x->_M_color = _S_red;
if(__insert_left){
__p->_M_left = __x;
if(__p == &__header){
__header._M_parent = __x;
__header._M_right = __x;
}else if( __p == __header._M_left )
__header._M_left = __x;
}else{
__p->_M_right = __x;
if(__p == __header._M_right)
__header._M_right = __x;
}
while( __x != *rootptrptr && __x->_M_parent->_M_color==_S_red ){
Test_Rb_tree_node_base* const xpp = __x->_M_parent->_M_parent;
if(__x->_M_parent == xpp->_M_left){
Test_Rb_tree_node_base* const y = xpp->_M_right;
if(y && y->_M_color == _S_red){
__x->_M_parent->_M_color = _S_black;
y->_M_color = _S_black;
xpp->_M_color = _S_red;
__x = xpp;
}else{
if( __x==__x->_M_parent->_M_right){
__x = __x->_M_parent;
_Rb_tree_rotate_left(__x,*rootptrptr);
}
__x->_M_parent->_M_color = _S_black;
xpp->_M_color = _S_red;
_Rb_tree_rotate_right(xpp,*rootptrptr);
}
}else{
Test_Rb_tree_node_base* const y = xpp->_M_left;
if(y && y->_M_color == _S_red){
__x->_M_parent->_M_color = _S_black;
y->_M_color = _S_black;
xpp->_M_color = _S_red;
__x = xpp;
}else{
if(__x == __x->_M_parent->_M_left){
__x = __x->_M_parent;
_Rb_tree_rotate_right(__x,*rootptrptr);
}
__x->_M_parent->_M_color = _S_black;
xpp->_M_color = _S_red;
_Rb_tree_rotate_left(xpp,*rootptrptr);
}
}
}
(*rootptrptr)->_M_color = _S_black;
return ;
}
};
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc/* = Test_allocator<_Val> */>
Testpair<typename Test_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::iterator, bool>
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_unique(const _Val& __v)
{
Test_Link_type __x = _M_begin();
Test_Link_type __y = _M_end();
bool __comp = true;
while (__x != 0)
{
__y = __x;
__comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x));
__x = __comp ? _S_left(__x) : _S_right(__x);
}
iterator __j = iterator(__y);
if (__comp)
{
if (__j == begin())
return Testpair<iterator, bool>(Test_M_insert_(__x, __y, __v), true);
else
--__j;
}
if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v)))
return Testpair<iterator, bool>(Test_M_insert_(__x, __y, __v), true);
return Testpair<iterator, bool>(__j, false);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc/* = Test_allocator<_Val> */>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_equal(const _Val& __v)
{
Test_Link_type __x = _M_begin();
Test_Link_type __y = _M_end();
while (__x != 0)
{
__y = __x;
__x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ?
_S_left(__x) : _S_right(__x);
}
return Test_M_insert_(__x, __y, __v);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_unique_(const_iterator __position, const _Val& __v)
{
// end()
if (__position._M_node == _M_end())
{
if (size() > 0
&& _M_impl._M_key_compare(_S_key(_M_rightmost()),
_KeyOfValue()(__v)))
return Test_M_insert_(0, _M_rightmost(), __v);
else
return Test_M_insert_unique(__v).first;
}
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__position._M_node)))
{
// First, try before...
const_iterator __before = __position;
if (__position._M_node == _M_leftmost()) // begin()
return Test_M_insert_(_M_leftmost(), _M_leftmost(), __v);
else if (_M_impl._M_key_compare(_S_key((--__before)._M_node),
_KeyOfValue()(__v)))
{
if (_S_right(__before._M_node) == 0)
return Test_M_insert_(0, __before._M_node, __v);
else
return Test_M_insert_(__position._M_node,
__position._M_node, __v);
}
else
return Test_M_insert_unique(__v).first;
}
else if (_M_impl._M_key_compare(_S_key(__position._M_node),
_KeyOfValue()(__v)))
{
// ... then try after.
const_iterator __after = __position;
if (__position._M_node == _M_rightmost())
return Test_M_insert_(0, _M_rightmost(), __v);
else if (_M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key((++__after)._M_node)))
{
if (_S_right(__position._M_node) == 0)
return Test_M_insert_(0, __position._M_node, __v);
else
return Test_M_insert_(__after._M_node, __after._M_node, __v);
}
else
return Test_M_insert_unique(__v).first;
}
else
// Equivalent keys.
return iterator(static_cast<Test_Link_type>
(const_cast<Test_Base_ptr>(__position._M_node)));
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc/* = Test_allocator<_Val> */>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_(Test_Const_Base_ptr __x, Test_Const_Base_ptr __p, const _Val& __v)
{
bool __insert_left = (__x != 0 || __p == _M_end()
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__p)));
Test_Link_type __z = Test_M_create_node(__v);
Test_Rb_tree_insert_and_rebalance(__insert_left, __z,
const_cast<Test_Base_ptr>(__p),
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc/* = Test_allocator<_Val> */>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_lower(Test_Base_ptr __x, Test_Base_ptr __p, const _Val& __v)
{
bool __insert_left = (__x != 0 || __p == _M_end()
|| !_M_impl._M_key_compare(_S_key(__p),
_KeyOfValue()(__v)));
Test_Link_type __z = Test_M_create_node(__v);
Test_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header);
++_M_impl._M_node_count;
return iterator(__z);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc/* = Test_allocator<_Val> */>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_insert_equal_lower(const _Val& __v)
{
Test_Link_type __x = _M_begin();
Test_Link_type __y = _M_end();
while (__x != 0)
{
__y = __x;
__x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ?
_S_left(__x) : _S_right(__x);
}
return Test_M_insert_lower(__x, __y, __v);
}
template<typename _Key, typename _Val, typename _KoV,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::Test_Link_type
Test_Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
Test_M_copy(Test_Const_Link_type __x, Test_Link_type __p)
{
// Structural copy. __x and __p must be non-null.
Test_Link_type __top = Test_M_clone_node(__x);
__top->_M_parent = __p;
__try
{
if (__x->_M_right)
__top->_M_right = Test_M_copy(_S_right(__x), __top);
__p = __top;
__x = _S_left(__x);
while (__x != 0)
{
Test_Link_type __y = Test_M_clone_node(__x);
__p->_M_left = __y;
__y->_M_parent = __p;
if (__x->_M_right)
__y->_M_right = Test_M_copy(_S_right(__x), __y);
__p = __y;
__x = _S_left(__x);
}
}
__catch(...)
{
Test_M_erase(__top);
__throw_exception_again;
}
return __top;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_erase(Test_Link_type __x)
{
// Erase without rebalancing.
while (__x != 0)
{
Test_M_erase(_S_right(__x));
Test_Link_type __y = _S_left(__x);
Test_M_destroy_node(__x);
__x = __y;
}
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_lower_bound(Test_Link_type __x, Test_Link_type __y,
const _Key& __k)
{
while (__x != 0)
if (!_M_impl._M_key_compare(_S_key(__x), __k))
__y = __x, __x = _S_left(__x);
else
__x = _S_right(__x);
return iterator(__y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
Test_M_upper_bound(Test_Link_type __x, Test_Link_type __y,
const _Key& __k)
{
while (__x != 0)
if (_M_impl._M_key_compare(__k, _S_key(__x)))
__y = __x, __x = _S_left(__x);
else
__x = _S_right(__x);
return iterator(__y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator==(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return __x.size() == __y.size()
&& std::equal(__x.begin(), __x.end(), __y.begin());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator<(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return std::lexicographical_compare(__x.begin(), __x.end(),
__y.begin(), __y.end());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator!=(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return !(__x == __y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator>(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return __y < __x;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator<=(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return !(__y < __x);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator>=(const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return !(__x < __y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline void
swap(Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
__x.swap(__y);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(iterator __position)
{
Test_Link_type __y =
static_cast<Test_Link_type>(Test_Rb_tree_rebalance_for_erase
(__position._M_node,
this->_M_impl._M_header,this->_M_impl._M_header._M_left,this->_M_impl._M_header._M_right));
Test_M_destroy_node(__y);
--_M_impl._M_node_count;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const_iterator __position)
{
/*Test_Link_type __y =
static_cast<Test_Link_type>(Test_Rb_tree_rebalance_for_erase
(const_cast<_Base_ptr>(__position._M_node),
this->_M_impl._M_header));*/
Test_Link_type __y =
static_cast<Test_Link_type>(Test_Rb_tree_rebalance_for_erase
(const_cast<_Base_ptr>(__position._M_node),
this->_M_impl._M_header,this->_M_impl._M_header->_M_left,this->_M_impl._M_header->_M_right));
Test_M_destroy_node(__y);
--_M_impl._M_node_count;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const _Key& __x)
{
pair<iterator, iterator> __p = equal_range(__x);
const size_type __old_size = size();
erase(__p.first, __p.second);
return __old_size - size();
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(iterator __first, iterator __last)
{
if (__first == begin() && __last == end())
clear();
else
while (__first != __last)
erase(__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const_iterator __first, const_iterator __last)
{
if (__first == begin() && __last == end())
clear();
else
while (__first != __last)
erase(__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
void
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
erase(const _Key* __first, const _Key* __last)
{
while (__first != __last)
erase(*__first++);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
find(const _Key& __k)
{
iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
return (__j == end()
|| _M_impl._M_key_compare(__k,
_S_key(__j._M_node))) ? end() : __j;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::const_iterator
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
find(const _Key& __k) const
{
const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k);
return (__j == end()
|| _M_impl._M_key_compare(__k,
_S_key(__j._M_node))) ? end() : __j;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
typename Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
Test_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
count(const _Key& __k) const
{
pair<const_iterator, const_iterator> __p = equal_range(__k);
const size_type __n = std::distance(__p.first, __p.second);
return __n;
}
unsigned int
_Rb_tree_black_count(const Test_Rb_tree_node_base* __node,
const Test_Rb_tree_node_base* __root);
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
bool
Test_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const
{
if (_M_impl._M_node_count == 0 || begin() == end())
return _M_impl._M_node_count == 0 && begin() == end()
&& this->_M_impl._M_header._M_left == _M_end()
&& this->_M_impl._M_header._M_right == _M_end();
unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root());
for (const_iterator __it = begin(); __it != end(); ++__it)
{
_Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node);
_Const_Link_type __L = _S_left(__x);
_Const_Link_type __R = _S_right(__x);
if (__x->_M_color == _S_red)
if ((__L && __L->_M_color == _S_red)
|| (__R && __R->_M_color == _S_red))
return false;
if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L)))
return false;
if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x)))
return false;
if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len)
return false;
}
if (_M_leftmost() != Test_Rb_tree_node_base::_S_minimum(_M_root()))
return false;
if (_M_rightmost() != Test_Rb_tree_node_base::_S_maximum(_M_root()))
return false;
return true;
}
template<class _Arg,
class _Result>
struct Test_unary_function
{ // base class for unary functions
typedef _Arg argument_type;
typedef _Result result_type;
};
template<typename _Pair>
struct Test_Select1st : public Test_unary_function<_Pair,
typename _Pair::first_type>
{
typename _Pair::first_type&
operator()(_Pair& __x) const
{
return __x.first;
}
const typename _Pair::first_type&
operator()(const _Pair& __x) const
{
return __x.first;
}
};
template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Alloc = Test_allocator<Testpair<const _Key, _Tp> > >
class Testmap//map容器提供接口的类
{
public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef Testpair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
typedef _Alloc allocator_type;
private:
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
{
friend class Testmap<_Key, _Tp, _Compare, _Alloc>;
protected:
_Compare comp;
value_compare(_Compare __c)
: comp(__c) { }
public:
bool operator()(const value_type& __x, const value_type& __y) const
{
return comp(__x.first, __y.first);
}
};
private:
/// This turns a red-black tree into a [multi]map.
typedef typename _Alloc::template Test_rebind<value_type>::other
_Pair_alloc_type;
typedef Test_Rb_tree<key_type, value_type, Test_Select1st<value_type>,
key_compare, _Pair_alloc_type> _Rep_type;
/// The actual tree structure.
_Rep_type Test_M_t;
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
typedef typename _Pair_alloc_type::pointer pointer;
typedef typename _Pair_alloc_type::const_pointer const_pointer;
typedef typename _Pair_alloc_type::reference reference;
typedef typename _Pair_alloc_type::const_reference const_reference;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
typedef typename _Rep_type::reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
// [23.3.1.1] construct/copy/destroy
// (get_allocator() is normally listed in this section, but seems to have
// been accidentally omitted in the printed standard)
/**
* @brief Default constructor creates no elements.
*/
Testmap()
: Test_M_t() { }
/**
* @brief Creates a %map with no elements.
* @param comp A comparison object.
* @param a An Test_allocator object.
*/
explicit
Testmap(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: Test_M_t(__comp, __a) { }
/**
* @brief %Map copy constructor.
* @param x A %map of identical element and Test_allocator types.
*
* The newly-created %map uses a copy of the allocation object
* used by @a x.
*/
Testmap(const Testmap& __x)
: Test_M_t(__x.Test_M_t) { }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief %Map Test_move constructor.
* @param x A %map of identical element and Test_allocator types.
*
* The newly-created %map contains the exact contents of @a x.
* The contents of @a x are a valid, but unspecified %map.
*/
Testmap(Testmap&& __x)
: Test_M_t(std::Test_forward<_Rep_type>(__x.Test_M_t)) { }
Testmap(initializer_list<value_type> __l,
const _Compare& __c = _Compare(),
const allocator_type& __a = allocator_type())
: Test_M_t(__c, __a)
{
Test_M_t.Test_M_insert_unique(__l.begin(), __l.end());
}
#endif
/**
* @brief Builds a %map from a range.
* @param first An input iterator.
* @param last An input iterator.
*
* Create a %map consisting of copies of the elements from [first,last).
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
template<typename _InputIterator>
Testmap(_InputIterator __first, _InputIterator __last)
: Test_M_t()
{
Test_M_t.Test_M_insert_unique(__first, __last);
}
/**
* @brief Builds a %map from a range.
* @param first An input iterator.
* @param last An input iterator.
* @param comp A comparison functor.
* @param a An Test_allocator object.
*
* Create a %map consisting of copies of the elements from [first,last).
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
*/
template<typename _InputIterator>
Testmap(_InputIterator __first, _InputIterator __last,
const _Compare& __comp,
const allocator_type& __a = allocator_type())
: Test_M_t(__comp, __a)
{
Test_M_t.Test_M_insert_unique(__first, __last);
}
Testmap&
operator=(const Testmap& __x)
{
Test_M_t = __x.Test_M_t;
return *this;
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief %Map Test_move assignment operator.
* @param x A %map of identical element and Test_allocator types.
*
* The contents of @a x are moved into this map (without copying).
* @a x is a valid, but unspecified %map.
*/
Testmap&
operator=(Testmap&& __x)
{
// NB: DR 675.
this->clear();
this->swap(__x);
return *this;
}
/**
* @brief %Map list assignment operator.
* @param l An initializer_list.
*
* This function fills a %map with copies of the elements in the
* initializer list @a l.
*
* Note that the assignment completely changes the %map and
* that the resulting %map's size is the same as the number
* of elements assigned. Old data may be lost.
*/
Testmap&
operator=(initializer_list<value_type> __l)
{
this->clear();
this->insert(__l.begin(), __l.end());
return *this;
}
#endif
/// Get a copy of the memory allocation object.
allocator_type
get_allocator() const
{
return Test_M_t.get_allocator();
}
iterator
begin()
{
return Test_M_t.begin();
}
const_iterator
begin() const
{
return Test_M_t.begin();
}
/**
* Returns a read/write iterator that points one past the last
* Testpair in the %map. Iteration is done in ascending order
* according to the keys.
*/
iterator
end()
{
return Test_M_t.end();
}
const_iterator
end() const
{
return Test_M_t.end();
}
reverse_iterator
rbegin()
{
return Test_M_t.rbegin();
}
const_reverse_iterator
rbegin() const
{
return Test_M_t.rbegin();
}
reverse_iterator
rend()
{
return Test_M_t.rend();
}
const_reverse_iterator
rend() const
{
return Test_M_t.rend();
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
const_iterator
cbegin() const
{
return Test_M_t.begin();
}
const_iterator
cend() const
{
return Test_M_t.end();
}
const_reverse_iterator
crbegin() const
{
return Test_M_t.rbegin();
}
const_reverse_iterator
crend() const
{
return Test_M_t.rend();
}
#endif
bool
empty() const
{
return Test_M_t.empty();
}
/** Returns the size of the %map. */
size_type
size() const
{
return Test_M_t.size();
}
/** Returns the maximum size of the %map. */
size_type
max_size() const
{
return Test_M_t.max_size();
}
mapped_type&
operator[](const key_type& __k)
{
// concept requirements
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
__i = insert(__i, value_type(__k, mapped_type()));
return (*__i).second;
}
mapped_type&
at(const key_type& __k)
{
iterator __i = lower_bound(__k);
if (__i == end() || key_comp()(__k, (*__i).first))
__throw_out_of_range(__N("map::at"));
return (*__i).second;
}
const mapped_type&
at(const key_type& __k) const
{
const_iterator __i = lower_bound(__k);
if (__i == end() || key_comp()(__k, (*__i).first))
__throw_out_of_range(__N("map::at"));
return (*__i).second;
}
Testpair<iterator, bool>
insert(const value_type& __x)
{
return Test_M_t.Test_M_insert_unique(__x);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
/**
* @brief Attempts to insert a list of std::pairs into the %map.
* @param list A std::initializer_list<value_type> of pairs to be
* inserted.
*
* Complexity similar to that of the range constructor.
*/
void
insert(std::initializer_list<value_type> __list)
{
insert (__list.begin(), __list.end());
}
#endif
/**
* @brief Attempts to insert a std::Testpair into the %map.
* @param position An iterator that serves as a hint as to where the
* Testpair should be inserted.
* @param x Testpair to be inserted (see std::Test_make_pair for easy creation
* of pairs).
* @return An iterator that points to the element with key of @a x (may
* or may not be the %Testpair passed in).
*
* This function is not concerned about whether the insertion
* took place, and thus does not return a boolean like the
* single-argument insert() does. Note that the first
* parameter is only a hint and can potentially improve the
* performance of the insertion process. A bad hint would
* cause no gains in efficiency.
*
*
* Insertion requires logarithmic time (if the hint is not taken).
*/
iterator
insert(iterator __position, const value_type& __x)
{
return Test_M_t.Test_M_insert_unique_(__position, __x);
}
/**
* @brief Template function that attempts to insert a range of elements.
* @param first Iterator pointing to the start of the range to be
* inserted.
* @param last Iterator pointing to the end of the range.
*
* Complexity similar to that of the range constructor.
*/
template<typename _InputIterator>
void
insert(_InputIterator __first, _InputIterator __last)
{
Test_M_t.Test_M_insert_unique(__first, __last);
}
/**
* @brief Erases an element from a %map.
* @param position An iterator pointing to the element to be erased.
*
* This function erases an element, pointed to by the given
* iterator, from a %map. Note that this function only erases
* the element, and that if the element is itself a pointer,
* the pointed-to memory is not touched in any way. Managing
* the pointer is the user's responsibility.
*/
void
erase(iterator __position)//迭代过程中使用erase函数删除节点,导致迭代器内红黑树基根变为野指针,在下一次迭代增加地址时,判断其节点导致崩溃
{
Test_M_t.erase(__position);
}
/**
* @brief Erases elements according to the provided key.
* @param x Key of element to be erased.
* @return The number of elements erased.
*
* This function erases all the elements located by the given key from
* a %map.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
size_type
erase(const key_type& __x)
{
return Test_M_t.erase(__x);
}
/**
* @brief Erases a [first,last) range of elements from a %map.
* @param first Iterator pointing to the start of the range to be
* erased.
* @param last Iterator pointing to the end of the range to be erased.
*
* This function erases a sequence of elements from a %map.
* Note that this function only erases the element, and that if
* the element is itself a pointer, the pointed-to memory is not touched
* in any way. Managing the pointer is the user's responsibility.
*/
void
erase(iterator __first, iterator __last)
{
Test_M_t.erase(__first, __last);
}
/**
* @brief Swaps data with another %map.
* @param x A %map of the same element and Test_allocator types.
*
* This exchanges the elements between two maps in constant
* time. (It is only swapping a pointer, an integer, and an
* instance of the @c Compare type (which itself is often
* stateless and empty), so it should be quite fast.) Note
* that the global std::swap() function is specialized such
* that std::swap(m1,m2) will feed to this function.
*/
void
#ifdef __GXX_EXPERIMENTAL_CXX0X__
swap(Testmap&& __x)
#else
swap(Testmap& __x)
#endif
{
Test_M_t.swap(__x.Test_M_t);
}
/**
* Erases all elements in a %map. Note that this function only
* erases the elements, and that if the elements themselves are
* pointers, the pointed-to memory is not touched in any way.
* Managing the pointer is the user's responsibility.
*/
void
clear()
{
Test_M_t.clear();
}
// observers
/**
* Returns the key comparison object out of which the %map was
* constructed.
*/
key_compare
key_comp() const
{
return Test_M_t.key_comp();
}
/**
* Returns a value comparison object, built from the key comparison
* object out of which the %map was constructed.
*/
value_compare
value_comp() const
{
return value_compare(Test_M_t.key_comp());
}
// [23.3.1.3] map operations
/**
* @brief Tries to locate an element in a %map.
* @param x Key of (key, value) %Testpair to be located.
* @return Iterator pointing to sought-after element, or end() if not
* found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns an iterator
* pointing to the sought after %Testpair. If unsuccessful it returns the
* past-the-end ( @c end() ) iterator.
*/
iterator
find(const key_type& __x)
{
return Test_M_t.find(__x);
}
/**
* @brief Tries to locate an element in a %map.
* @param x Key of (key, value) %Testpair to be located.
* @return Read-only (constant) iterator pointing to sought-after
* element, or end() if not found.
*
* This function takes a key and tries to locate the element with which
* the key matches. If successful the function returns a constant
* iterator pointing to the sought after %Testpair. If unsuccessful it
* returns the past-the-end ( @c end() ) iterator.
*/
const_iterator
find(const key_type& __x) const
{
return Test_M_t.find(__x);
}
/**
* @brief Finds the number of elements with given key.
* @param x Key of (key, value) pairs to be located.
* @return Number of elements with specified key.
*
* This function only makes sense for multimaps; for map the result will
* either be 0 (not present) or 1 (present).
*/
size_type
count(const key_type& __x) const
{
return Test_M_t.find(__x) == Test_M_t.end() ? 0 : 1;
}
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param x Key of (key, value) Testpair to be located.
* @return Iterator pointing to first element equal to or greater
* than key, or end().
*
* This function returns the first element of a subsequence of elements
* that matches the given key. If unsuccessful it returns an iterator
* pointing to the first element that has a greater value than given key
* or end() if no such element exists.
*/
iterator
lower_bound(const key_type& __x)
{
return Test_M_t.lower_bound(__x);
}
/**
* @brief Finds the beginning of a subsequence matching given key.
* @param x Key of (key, value) Testpair to be located.
* @return Read-only (constant) iterator pointing to first element
* equal to or greater than key, or end().
*
* This function returns the first element of a subsequence of elements
* that matches the given key. If unsuccessful it returns an iterator
* pointing to the first element that has a greater value than given key
* or end() if no such element exists.
*/
const_iterator
lower_bound(const key_type& __x) const
{
return Test_M_t.lower_bound(__x);
}
/**
* @brief Finds the end of a subsequence matching given key.
* @param x Key of (key, value) Testpair to be located.
* @return Iterator pointing to the first element
* greater than key, or end().
*/
iterator
upper_bound(const key_type& __x)
{
return Test_M_t.upper_bound(__x);
}
/**
* @brief Finds the end of a subsequence matching given key.
* @param x Key of (key, value) Testpair to be located.
* @return Read-only (constant) iterator pointing to first iterator
* greater than key, or end().
*/
const_iterator
upper_bound(const key_type& __x) const
{
return Test_M_t.upper_bound(__x);
}
/**
* @brief Finds a subsequence matching given key.
* @param x Key of (key, value) pairs to be located.
* @return Testpair of iterators that possibly points to the subsequence
* matching given key.
*
* This function is equivalent to
* @code
* std::Test_make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*
* This function probably only makes sense for multimaps.
*/
Testpair<iterator, iterator>
equal_range(const key_type& __x)
{
return Test_M_t.equal_range(__x);
}
/**
* @brief Finds a subsequence matching given key.
* @param x Key of (key, value) pairs to be located.
* @return Testpair of read-only (constant) iterators that possibly points
* to the subsequence matching given key.
*
* This function is equivalent to
* @code
* std::Test_make_pair(c.lower_bound(val),
* c.upper_bound(val))
* @endcode
* (but is faster than making the calls separately).
*
* This function probably only makes sense for multimaps.
*/
Testpair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{
return Test_M_t.equal_range(__x);
}
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator==(const Testmap<_K1, _T1, _C1, _A1>&,
const Testmap<_K1, _T1, _C1, _A1>&);
template<typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
operator<(const Testmap<_K1, _T1, _C1, _A1>&,
const Testmap<_K1, _T1, _C1, _A1>&);
};
/**
* @brief Map equality comparison.
* @param x A %map.
* @param y A %map of the same type as @a x.
* @return True iff the size and elements of the maps are equal.
*
* This is an equivalence relation. It is linear in the size of the
* maps. Maps are considered equivalent if their sizes are equal,
* and if corresponding elements compare equal.
*/
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool operator==(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return __x.Test_M_t == __y.Test_M_t;
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool operator<(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return __x.Test_M_t < __y.Test_M_t;
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool operator!=(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return !(__x == __y);
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
operator>(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return __y < __x;
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool operator<=(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return !(__y < __x);
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool operator>=(const Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
const Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
return !(__x < __y);
}
template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void swap(Testmap<_Key, _Tp, _Compare, _Alloc>& __x,
Testmap<_Key, _Tp, _Compare, _Alloc>& __y)
{
__x.swap(__y);
}