protected:
typedef _Rb_tree_node_base* _Base_ptr;
typedef const _Rb_tree_node_base* _Const_Base_ptr;
+ typedef _Rb_tree_node<_Val>* _Link_type;
+ typedef const _Rb_tree_node<_Val>* _Const_Link_type;
+
+ private:
+ // Functor recycling a pool of nodes and using allocation once the pool is
+ // empty.
+ struct _Reuse_or_alloc_node
+ {
+ _Reuse_or_alloc_node(const _Rb_tree_node_base& __header,
+ _Rb_tree& __t)
+ : _M_root(__header._M_parent), _M_nodes(__header._M_right), _M_t(__t)
+ {
+ if (_M_root)
+ _M_root->_M_parent = 0;
+ else
+ _M_nodes = 0;
+ }
+
+#if __cplusplus >= 201103L
+ _Reuse_or_alloc_node(const _Reuse_or_alloc_node&) = delete;
+#endif
+
+ ~_Reuse_or_alloc_node()
+ { _M_t._M_erase(static_cast<_Link_type>(_M_root)); }
+
+ template<typename _Arg>
+ _Link_type
+#if __cplusplus < 201103L
+ operator()(const _Arg& __arg)
+#else
+ operator()(_Arg&& __arg)
+#endif
+ {
+ _Link_type __node = static_cast<_Link_type>(_M_extract());
+ if (__node)
+ {
+ _M_t._M_destroy_node(__node);
+ _M_t._M_construct_node(__node, _GLIBCXX_FORWARD(_Arg, __arg));
+ return __node;
+ }
+
+ return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg));
+ }
+
+ private:
+ _Base_ptr
+ _M_extract()
+ {
+ if (!_M_nodes)
+ return _M_nodes;
+
+ _Base_ptr __node = _M_nodes;
+ _M_nodes = _M_nodes->_M_parent;
+ if (_M_nodes)
+ {
+ if (_M_nodes->_M_right == __node)
+ {
+ _M_nodes->_M_right = 0;
+
+ if (_M_nodes->_M_left)
+ {
+ _M_nodes = _M_nodes->_M_left;
+
+ while (_M_nodes->_M_right)
+ _M_nodes = _M_nodes->_M_right;
+ }
+ }
+ else // __node is on the left.
+ _M_nodes->_M_left = 0;
+ }
+ else
+ _M_root = 0;
+
+ return __node;
+ }
+
+ _Base_ptr _M_root;
+ _Base_ptr _M_nodes;
+ _Rb_tree& _M_t;
+ };
+
+ // Functor similar to the previous one but without any pool of node to
+ // recycle.
+ struct _Alloc_node
+ {
+ _Alloc_node(_Rb_tree& __t)
+ : _M_t(__t) { }
+
+ template<typename _Arg>
+ _Link_type
+#if __cplusplus < 201103L
+ operator()(const _Arg& __arg) const
+#else
+ operator()(_Arg&& __arg) const
+#endif
+ { return _M_t._M_create_node(_GLIBCXX_FORWARD(_Arg, __arg)); }
+
+ private:
+ _Rb_tree& _M_t;
+ };
public:
typedef _Key key_type;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
- typedef _Rb_tree_node<_Val>* _Link_type;
- typedef const _Rb_tree_node<_Val>* _Const_Link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
{ _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
#if __cplusplus < 201103L
- _Link_type
- _M_create_node(const value_type& __x)
+ void
+ _M_construct_node(_Link_type __node, const value_type& __x)
{
- _Link_type __tmp = _M_get_node();
__try
- { get_allocator().construct(__tmp->_M_valptr(), __x); }
+ { get_allocator().construct(__node->_M_valptr(), __x); }
__catch(...)
{
- _M_put_node(__tmp);
+ _M_put_node(__node);
__throw_exception_again;
}
+ }
+
+ _Link_type
+ _M_create_node(const value_type& __x)
+ {
+ _Link_type __tmp = _M_get_node();
+ _M_construct_node(__tmp, __x);
return __tmp;
}
void
_M_destroy_node(_Link_type __p)
- {
- get_allocator().destroy(__p->_M_valptr());
- _M_put_node(__p);
- }
+ { get_allocator().destroy(__p->_M_valptr()); }
#else
template<typename... _Args>
- _Link_type
- _M_create_node(_Args&&... __args)
+ void
+ _M_construct_node(_Link_type __node, _Args&&... __args)
{
- _Link_type __tmp = _M_get_node();
__try
{
- ::new(__tmp) _Rb_tree_node<_Val>;
+ ::new(__node) _Rb_tree_node<_Val>;
_Alloc_traits::construct(_M_get_Node_allocator(),
- __tmp->_M_valptr(),
+ __node->_M_valptr(),
std::forward<_Args>(__args)...);
}
__catch(...)
{
- _M_put_node(__tmp);
+ __node->~_Rb_tree_node<_Val>();
+ _M_put_node(__node);
__throw_exception_again;
}
+ }
+
+ template<typename... _Args>
+ _Link_type
+ _M_create_node(_Args&&... __args)
+ {
+ _Link_type __tmp = _M_get_node();
+ _M_construct_node(__tmp, std::forward<_Args>(__args)...);
return __tmp;
}
{
_Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
__p->~_Rb_tree_node<_Val>();
- _M_put_node(__p);
}
#endif
- _Link_type
- _M_clone_node(_Const_Link_type __x)
+ void
+ _M_drop_node(_Link_type __p) _GLIBCXX_NOEXCEPT
{
- _Link_type __tmp = _M_create_node(*__x->_M_valptr());
- __tmp->_M_color = __x->_M_color;
- __tmp->_M_left = 0;
- __tmp->_M_right = 0;
- return __tmp;
+ _M_destroy_node(__p);
+ _M_put_node(__p);
}
+ template<typename _NodeGen>
+ _Link_type
+ _M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
+ {
+ _Link_type __tmp = __node_gen(*__x->_M_valptr());
+ __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)>
+ // Unused _Is_pod_comparator is kept as it is part of mangled name.
+ template<typename _Key_compare,
+ bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
struct _Rb_tree_impl : public _Node_allocator
{
_Key_compare _M_key_compare;
{ _M_initialize(); }
#endif
+ void
+ _M_reset()
+ {
+ this->_M_header._M_parent = 0;
+ this->_M_header._M_left = &this->_M_header;
+ this->_M_header._M_right = &this->_M_header;
+ this->_M_node_count = 0;
+ }
+
private:
void
_M_initialize()
const key_type& __k);
#if __cplusplus >= 201103L
- template<typename _Arg>
+ template<typename _Arg, typename _NodeGen>
iterator
- _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v);
+ _M_insert_(_Base_ptr __x, _Base_ptr __y, _Arg&& __v, _NodeGen&);
iterator
_M_insert_node(_Base_ptr __x, _Base_ptr __y, _Link_type __z);
iterator
_M_insert_equal_lower_node(_Link_type __z);
#else
- iterator
- _M_insert_(_Base_ptr __x, _Base_ptr __y,
- const value_type& __v);
+ template<typename _NodeGen>
+ iterator
+ _M_insert_(_Base_ptr __x, _Base_ptr __y,
+ const value_type& __v, _NodeGen&);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 233. Insertion hints in associative containers.
_M_insert_equal_lower(const value_type& __x);
#endif
+ template<typename _NodeGen>
+ _Link_type
+ _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen&);
+
_Link_type
- _M_copy(_Const_Link_type __x, _Link_type __p);
+ _M_copy(_Const_Link_type __x, _Link_type __p)
+ {
+ _Alloc_node __an(*this);
+ return _M_copy(__x, __p, __an);
+ }
void
_M_erase(_Link_type __x);
_Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
: _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
{
- if (__x._M_root() != 0)
+ if (__x._M_root() != nullptr)
{
_M_root() = _M_copy(__x._M_begin(), _M_end());
_M_leftmost() = _S_minimum(_M_root());
iterator
_M_insert_equal(_Arg&& __x);
- template<typename _Arg>
+ template<typename _Arg, typename _NodeGen>
iterator
- _M_insert_unique_(const_iterator __position, _Arg&& __x);
+ _M_insert_unique_(const_iterator __pos, _Arg&& __x, _NodeGen&);
template<typename _Arg>
- iterator
- _M_insert_equal_(const_iterator __position, _Arg&& __x);
+ iterator
+ _M_insert_unique_(const_iterator __pos, _Arg&& __x)
+ {
+ _Alloc_node __an(*this);
+ return _M_insert_unique_(__pos, std::forward<_Arg>(__x), __an);
+ }
+
+ template<typename _Arg, typename _NodeGen>
+ iterator
+ _M_insert_equal_(const_iterator __pos, _Arg&& __x, _NodeGen&);
+
+ template<typename _Arg>
+ iterator
+ _M_insert_equal_(const_iterator __pos, _Arg&& __x)
+ {
+ _Alloc_node __an(*this);
+ return _M_insert_equal_(__pos, std::forward<_Arg>(__x), __an);
+ }
template<typename... _Args>
pair<iterator, bool>
iterator
_M_insert_equal(const value_type& __x);
+ template<typename _NodeGen>
+ iterator
+ _M_insert_unique_(const_iterator __pos, const value_type& __x,
+ _NodeGen&);
+
iterator
- _M_insert_unique_(const_iterator __position, const value_type& __x);
+ _M_insert_unique_(const_iterator __pos, const value_type& __x)
+ {
+ _Alloc_node __an(*this);
+ return _M_insert_unique_(__pos, __x, __an);
+ }
+ template<typename _NodeGen>
+ iterator
+ _M_insert_equal_(const_iterator __pos, const value_type& __x,
+ _NodeGen&);
iterator
- _M_insert_equal_(const_iterator __position, const value_type& __x);
+ _M_insert_equal_(const_iterator __pos, const value_type& __x)
+ {
+ _Alloc_node __an(*this);
+ return _M_insert_equal_(__pos, __x, __an);
+ }
#endif
template<typename _InputIterator>
clear() _GLIBCXX_NOEXCEPT
{
_M_erase(_M_begin());
- _M_leftmost() = _M_end();
- _M_root() = 0;
- _M_rightmost() = _M_end();
- _M_impl._M_node_count = 0;
+ _M_impl._M_reset();
}
// Set operations.
__rb_verify() const;
#if __cplusplus >= 201103L
- bool
- _M_move_assign(_Rb_tree&);
+ _Rb_tree&
+ operator=(_Rb_tree&&) noexcept(_Alloc_traits::_S_nothrow_move());
+
+ template<typename _Iterator>
+ void
+ _M_assign_unique(_Iterator, _Iterator);
+
+ template<typename _Iterator>
+ void
+ _M_assign_equal(_Iterator, _Iterator);
private:
// Move elements from container with equal allocator.
: _M_impl(__x._M_impl._M_key_compare, std::move(__a))
{
using __eq = integral_constant<bool, _Alloc_traits::_S_always_equal()>;
- if (__x._M_root() != 0)
+ if (__x._M_root() != nullptr)
_M_move_data(__x, __eq());
}
_M_move_data(__x, std::true_type());
else
{
- _M_root() = _M_copy(__x._M_begin(), _M_end());
+ _Alloc_node __an(*this);
+ auto __lbd =
+ [&__an](const value_type& __cval)
+ {
+ auto& __val = const_cast<value_type&>(__cval);
+ return __an(std::move_if_noexcept(__val));
+ };
+ _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
_M_leftmost() = _S_minimum(_M_root());
_M_rightmost() = _S_maximum(_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
- bool
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
- _M_move_assign(_Rb_tree& __x)
+ operator=(_Rb_tree&& __x)
+ noexcept(_Alloc_traits::_S_nothrow_move())
{
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (_Alloc_traits::_S_propagate_on_move_assign()
|| _M_get_Node_allocator() == __x._M_get_Node_allocator())
{
clear();
- if (__x._M_root() != 0)
+ if (__x._M_root() != nullptr)
_M_move_data(__x, std::true_type());
std::__alloc_on_move(_M_get_Node_allocator(),
__x._M_get_Node_allocator());
- return true;
+ return *this;
+ }
+
+ // Try to move each node reusing existing nodes and copying __x nodes
+ // structure.
+ _Reuse_or_alloc_node __roan(_M_impl._M_header, *this);
+ _M_impl._M_reset();
+ if (__x._M_root() != nullptr)
+ {
+ auto __lbd =
+ [&__roan](const value_type& __cval)
+ {
+ auto& __val = const_cast<value_type&>(__cval);
+ return __roan(std::move_if_noexcept(__val));
+ };
+ _M_root() = _M_copy(__x._M_begin(), _M_end(), __lbd);
+ _M_leftmost() = _S_minimum(_M_root());
+ _M_rightmost() = _S_maximum(_M_root());
+ _M_impl._M_node_count = __x._M_impl._M_node_count;
+ __x.clear();
}
- return false;
+ return *this;
}
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ template<typename _Iterator>
+ void
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_assign_unique(_Iterator __first, _Iterator __last)
+ {
+ _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
+ _M_impl._M_reset();
+ for (; __first != __last; ++__first)
+ _M_insert_unique_(end(), *__first, __roan);
+ }
+
+ template<typename _Key, typename _Val, typename _KeyOfValue,
+ typename _Compare, typename _Alloc>
+ template<typename _Iterator>
+ void
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_assign_equal(_Iterator __first, _Iterator __last)
+ {
+ _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
+ _M_impl._M_reset();
+ for (; __first != __last; ++__first)
+ _M_insert_equal_(end(), *__first, __roan);
+ }
#endif
template<typename _Key, typename _Val, typename _KeyOfValue,
if (this != &__x)
{
// Note that _Key may be a constant type.
- clear();
#if __cplusplus >= 201103L
if (_Alloc_traits::_S_propagate_on_copy_assign())
{
if (!_Alloc_traits::_S_always_equal()
&& __this_alloc != __that_alloc)
{
+ // Replacement allocator cannot free existing storage, we need
+ // to erase nodes first.
+ clear();
std::__alloc_on_copy(__this_alloc, __that_alloc);
}
}
#endif
+
+ _Reuse_or_alloc_node __roan(this->_M_impl._M_header, *this);
+ _M_impl._M_reset();
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
{
- _M_root() = _M_copy(__x._M_begin(), _M_end());
+ _M_root() = _M_copy(__x._M_begin(), _M_end(), __roan);
_M_leftmost() = _S_minimum(_M_root());
_M_rightmost() = _S_maximum(_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
}
}
+
return *this;
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
#if __cplusplus >= 201103L
- template<typename _Arg>
+ template<typename _Arg, typename _NodeGen>
+#else
+ template<typename _NodeGen>
#endif
- typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_insert_(_Base_ptr __x, _Base_ptr __p,
#if __cplusplus >= 201103L
- _M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v)
+ _Arg&& __v,
#else
- _M_insert_(_Base_ptr __x, _Base_ptr __p, const _Val& __v)
+ const _Val& __v,
#endif
- {
- bool __insert_left = (__x != 0 || __p == _M_end()
- || _M_impl._M_key_compare(_KeyOfValue()(__v),
- _S_key(__p)));
+ _NodeGen& __node_gen)
+ {
+ bool __insert_left = (__x != 0 || __p == _M_end()
+ || _M_impl._M_key_compare(_KeyOfValue()(__v),
+ _S_key(__p)));
- _Link_type __z = _M_create_node(_GLIBCXX_FORWARD(_Arg, __v));
+ _Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v));
- _Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
- this->_M_impl._M_header);
- ++_M_impl._M_node_count;
- return iterator(__z);
- }
+ _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>
}
template<typename _Key, typename _Val, typename _KoV,
- typename _Compare, typename _Alloc>
- typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
- _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
- _M_copy(_Const_Link_type __x, _Link_type __p)
- {
- // Structural copy. __x and __p must be non-null.
- _Link_type __top = _M_clone_node(__x);
- __top->_M_parent = __p;
-
- __try
- {
- if (__x->_M_right)
- __top->_M_right = _M_copy(_S_right(__x), __top);
- __p = __top;
- __x = _S_left(__x);
+ typename _Compare, typename _Alloc>
+ template<typename _NodeGen>
+ typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type
+ _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::
+ _M_copy(_Const_Link_type __x, _Link_type __p, _NodeGen& __node_gen)
+ {
+ // Structural copy. __x and __p must be non-null.
+ _Link_type __top = _M_clone_node(__x, __node_gen);
+ __top->_M_parent = __p;
- while (__x != 0)
- {
- _Link_type __y = _M_clone_node(__x);
- __p->_M_left = __y;
- __y->_M_parent = __p;
- if (__x->_M_right)
- __y->_M_right = _M_copy(_S_right(__x), __y);
- __p = __y;
- __x = _S_left(__x);
- }
- }
- __catch(...)
- {
- _M_erase(__top);
- __throw_exception_again;
- }
- return __top;
- }
+ __try
+ {
+ if (__x->_M_right)
+ __top->_M_right = _M_copy(_S_right(__x), __top, __node_gen);
+ __p = __top;
+ __x = _S_left(__x);
+
+ while (__x != 0)
+ {
+ _Link_type __y = _M_clone_node(__x, __node_gen);
+ __p->_M_left = __y;
+ __y->_M_parent = __p;
+ if (__x->_M_right)
+ __y->_M_right = _M_copy(_S_right(__x), __y, __node_gen);
+ __p = __y;
+ __x = _S_left(__x);
+ }
+ }
+ __catch(...)
+ {
+ _M_erase(__top);
+ __throw_exception_again;
+ }
+ return __top;
+ }
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
{
_M_erase(_S_right(__x));
_Link_type __y = _S_left(__x);
- _M_destroy_node(__x);
+ _M_drop_node(__x);
__x = __y;
}
}
_M_leftmost() = __t._M_leftmost();
_M_rightmost() = __t._M_rightmost();
_M_root()->_M_parent = _M_end();
+ _M_impl._M_node_count = __t._M_impl._M_node_count;
- __t._M_root() = 0;
- __t._M_leftmost() = __t._M_end();
- __t._M_rightmost() = __t._M_end();
+ __t._M_impl._M_reset();
}
}
else if (__t._M_root() == 0)
__t._M_leftmost() = _M_leftmost();
__t._M_rightmost() = _M_rightmost();
__t._M_root()->_M_parent = __t._M_end();
+ __t._M_impl._M_node_count = _M_impl._M_node_count;
- _M_root() = 0;
- _M_leftmost() = _M_end();
- _M_rightmost() = _M_end();
+ _M_impl._M_reset();
}
else
{
_M_root()->_M_parent = _M_end();
__t._M_root()->_M_parent = __t._M_end();
+ std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
}
// No need to swap header's color as it does not change.
- std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count);
std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare);
_Alloc_traits::_S_on_swap(_M_get_Node_allocator(),
= _M_get_insert_unique_pos(_KeyOfValue()(__v));
if (__res.second)
- return _Res(_M_insert_(__res.first, __res.second,
- _GLIBCXX_FORWARD(_Arg, __v)),
- true);
+ {
+ _Alloc_node __an(*this);
+ return _Res(_M_insert_(__res.first, __res.second,
+ _GLIBCXX_FORWARD(_Arg, __v), __an),
+ true);
+ }
return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
}
{
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_equal_pos(_KeyOfValue()(__v));
- return _M_insert_(__res.first, __res.second, _GLIBCXX_FORWARD(_Arg, __v));
+ _Alloc_node __an(*this);
+ return _M_insert_(__res.first, __res.second,
+ _GLIBCXX_FORWARD(_Arg, __v), __an);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
#if __cplusplus >= 201103L
- template<typename _Arg>
+ template<typename _Arg, typename _NodeGen>
+#else
+ template<typename _NodeGen>
#endif
- typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_insert_unique_(const_iterator __position,
#if __cplusplus >= 201103L
- _M_insert_unique_(const_iterator __position, _Arg&& __v)
+ _Arg&& __v,
#else
- _M_insert_unique_(const_iterator __position, const _Val& __v)
+ const _Val& __v,
#endif
+ _NodeGen& __node_gen)
{
pair<_Base_ptr, _Base_ptr> __res
= _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
if (__res.second)
return _M_insert_(__res.first, __res.second,
- _GLIBCXX_FORWARD(_Arg, __v));
+ _GLIBCXX_FORWARD(_Arg, __v),
+ __node_gen);
return iterator(static_cast<_Link_type>(__res.first));
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
#if __cplusplus >= 201103L
- template<typename _Arg>
+ template<typename _Arg, typename _NodeGen>
+#else
+ template<typename _NodeGen>
#endif
- typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
- _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
+ _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
+ _M_insert_equal_(const_iterator __position,
#if __cplusplus >= 201103L
- _M_insert_equal_(const_iterator __position, _Arg&& __v)
+ _Arg&& __v,
#else
- _M_insert_equal_(const_iterator __position, const _Val& __v)
+ const _Val& __v,
#endif
- {
- pair<_Base_ptr, _Base_ptr> __res
- = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
+ _NodeGen& __node_gen)
+ {
+ pair<_Base_ptr, _Base_ptr> __res
+ = _M_get_insert_hint_equal_pos(__position, _KeyOfValue()(__v));
- if (__res.second)
- return _M_insert_(__res.first, __res.second,
- _GLIBCXX_FORWARD(_Arg, __v));
+ if (__res.second)
+ return _M_insert_(__res.first, __res.second,
+ _GLIBCXX_FORWARD(_Arg, __v),
+ __node_gen);
- return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
- }
+ return _M_insert_equal_lower(_GLIBCXX_FORWARD(_Arg, __v));
+ }
#if __cplusplus >= 201103L
template<typename _Key, typename _Val, typename _KeyOfValue,
if (__res.second)
return _Res(_M_insert_node(__res.first, __res.second, __z), true);
- _M_destroy_node(__z);
+ _M_drop_node(__z);
return _Res(iterator(static_cast<_Link_type>(__res.first)), false);
}
__catch(...)
{
- _M_destroy_node(__z);
+ _M_drop_node(__z);
__throw_exception_again;
}
}
}
__catch(...)
{
- _M_destroy_node(__z);
+ _M_drop_node(__z);
__throw_exception_again;
}
}
if (__res.second)
return _M_insert_node(__res.first, __res.second, __z);
- _M_destroy_node(__z);
+ _M_drop_node(__z);
return iterator(static_cast<_Link_type>(__res.first));
}
__catch(...)
{
- _M_destroy_node(__z);
+ _M_drop_node(__z);
__throw_exception_again;
}
}
}
__catch(...)
{
- _M_destroy_node(__z);
+ _M_drop_node(__z);
__throw_exception_again;
}
}
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
_M_insert_unique(_II __first, _II __last)
{
+ _Alloc_node __an(*this);
for (; __first != __last; ++__first)
- _M_insert_unique_(end(), *__first);
+ _M_insert_unique_(end(), *__first, __an);
}
template<typename _Key, typename _Val, typename _KoV,
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
_M_insert_equal(_II __first, _II __last)
{
+ _Alloc_node __an(*this);
for (; __first != __last; ++__first)
- _M_insert_equal_(end(), *__first);
+ _M_insert_equal_(end(), *__first, __an);
}
template<typename _Key, typename _Val, typename _KeyOfValue,
static_cast<_Link_type>(_Rb_tree_rebalance_for_erase
(const_cast<_Base_ptr>(__position._M_node),
this->_M_impl._M_header));
- _M_destroy_node(__y);
+ _M_drop_node(__y);
--_M_impl._M_node_count;
}