stl_bvector.h (_Bvector_alloc_base): Eliminate.

* include/bits/stl_bvector.h (_Bvector_alloc_base): Eliminate.
        (_Bvector_base): Inherit directly from word allocator.
        * include/bits/stl_tree.h (_Rb_tree_alloc_base): Eliminate.
        (_Rb_tree_base): Eliminate.
        (_Rb_tree): Inherit directly from node allocator.
        * include/ext/slist (_Alist_alloc_base): Eliminate.
        (_Slist_base): Inherit direcly from node allocator.

From-SVN: r74955
This commit is contained in:
Matt Austern 2003-12-23 00:09:26 +00:00 committed by Matt Austern
parent 7813d14ccc
commit 34c878297e
4 changed files with 74 additions and 206 deletions

View File

@ -1,3 +1,13 @@
2003-12-22 Matt Austern <austern@apple.com>
* include/bits/stl_bvector.h (_Bvector_alloc_base): Eliminate.
(_Bvector_base): Inherit directly from word allocator.
* include/bits/stl_tree.h (_Rb_tree_alloc_base): Eliminate.
(_Rb_tree_base): Eliminate.
(_Rb_tree): Inherit directly from node allocator.
* include/ext/slist (_Alist_alloc_base): Eliminate.
(_Slist_base): Inherit direcly from node allocator.
2003-12-22 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/18_support/numeric_limits.cc: Add _GLIBCXX_ASSERT to

View File

@ -261,77 +261,33 @@ inline _Bit_const_iterator
operator+(ptrdiff_t __n, const _Bit_const_iterator& __x) { return __x + __n; }
// Bit-vector base class, which encapsulates the difference between
// old SGI-style allocators and standard-conforming allocators.
// Base class for ordinary allocators.
template <class _Allocator, bool __is_static>
class _Bvector_alloc_base {
public:
typedef typename _Alloc_traits<bool, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_data_allocator; }
_Bvector_alloc_base(const allocator_type& __a)
: _M_data_allocator(__a), _M_start(), _M_finish(), _M_end_of_storage(0) {}
protected:
_Bit_type * _M_bit_alloc(size_t __n)
{ return _M_data_allocator.allocate((__n + _S_word_bit - 1)/_S_word_bit); }
void _M_deallocate() {
if (_M_start._M_p)
_M_data_allocator.deallocate(_M_start._M_p,
_M_end_of_storage - _M_start._M_p);
}
typename _Alloc_traits<_Bit_type, _Allocator>::allocator_type
_M_data_allocator;
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
_Bit_type * _M_end_of_storage;
};
// Specialization for instanceless allocators.
template <class _Allocator>
class _Bvector_alloc_base<_Allocator, true> {
public:
typedef typename _Alloc_traits<bool, _Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Bvector_alloc_base(const allocator_type&)
: _M_start(), _M_finish(), _M_end_of_storage(0) {}
protected:
typedef typename _Alloc_traits<_Bit_type, _Allocator>::_Alloc_type
_Alloc_type;
_Bit_type * _M_bit_alloc(size_t __n)
{ return _Alloc_type::allocate((__n + _S_word_bit - 1)/_S_word_bit); }
void _M_deallocate() {
if (_M_start._M_p)
_Alloc_type::deallocate(_M_start._M_p,
_M_end_of_storage - _M_start._M_p);
}
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
_Bit_type * _M_end_of_storage;
};
template <class _Alloc>
class _Bvector_base
: public _Bvector_alloc_base<_Alloc,
_Alloc_traits<bool, _Alloc>::_S_instanceless>
: public _Alloc::template rebind<_Bit_type>::other
{
typedef _Bvector_alloc_base<_Alloc,
_Alloc_traits<bool, _Alloc>::_S_instanceless>
_Base;
typedef typename _Alloc::template rebind<_Bit_type>::other _Bit_alloc_type;
public:
typedef typename _Base::allocator_type allocator_type;
typedef _Alloc allocator_type;
allocator_type get_allocator() const {
return *static_cast<const _Bit_alloc_type*>(this);
}
_Bvector_base(const allocator_type& __a) : _Base(__a) {}
~_Bvector_base() { _Base::_M_deallocate(); }
_Bvector_base(const allocator_type& __a)
: _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage(0) { }
~_Bvector_base() { this->_M_deallocate(); }
protected:
_Bit_type* _M_bit_alloc(size_t __n) {
return _Bit_alloc_type::allocate((__n + _S_word_bit - 1)/_S_word_bit);
}
void _M_deallocate() {
if (_M_start._M_p)
_Bit_alloc_type::deallocate(_M_start._M_p, _M_end_of_storage - _M_start._M_p);
}
_Bit_iterator _M_start;
_Bit_iterator _M_finish;
_Bit_type * _M_end_of_storage;
};
} // namespace __gnu_norm

View File

@ -261,79 +261,14 @@ namespace std
_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
_Rb_tree_node_base& __header);
// Base class to encapsulate the differences between old SGI-style
// allocators and standard-conforming allocators. In order to avoid
// having an empty base class, we arbitrarily move one of rb_tree's
// data members into the base class.
// _Base for general standard-conforming allocators.
template<typename _Tp, typename _Alloc, bool _S_instanceless>
class _Rb_tree_alloc_base
{
public:
typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
allocator_type
get_allocator() const { return _M_node_allocator; }
_Rb_tree_alloc_base(const allocator_type& __a)
: _M_node_allocator(__a) {}
protected:
typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type
_M_node_allocator;
_Rb_tree_node_base _M_header;
_Rb_tree_node<_Tp>*
_M_get_node() { return _M_node_allocator.allocate(1); }
void
_M_put_node(_Rb_tree_node<_Tp>* __p)
{ _M_node_allocator.deallocate(__p, 1); }
};
// Specialization for instanceless allocators.
template<typename _Tp, typename _Alloc>
class _Rb_tree_alloc_base<_Tp, _Alloc, true>
{
public:
typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Rb_tree_alloc_base(const allocator_type&) {}
protected:
_Rb_tree_node_base _M_header;
typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type
_Alloc_type;
_Rb_tree_node<_Tp>*
_M_get_node() { return _Alloc_type::allocate(1); }
void
_M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
};
template<typename _Tp, typename _Alloc>
struct _Rb_tree_base : public _Rb_tree_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{
typedef _Rb_tree_alloc_base<_Tp,
_Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base;
typedef typename _Base::allocator_type allocator_type;
_Rb_tree_base(const allocator_type& __a)
: _Base(__a) {}
};
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = allocator<_Val> >
class _Rb_tree : protected _Rb_tree_base<_Val, _Alloc>
class _Rb_tree
: protected _Alloc::template rebind<_Rb_tree_node<_Val> >::other
{
typedef _Rb_tree_base<_Val, _Alloc> _Base;
typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other
_Node_allocator;
protected:
typedef _Rb_tree_node_base* _Base_ptr;
@ -352,18 +287,22 @@ namespace std
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); }
typedef _Alloc allocator_type;
allocator_type get_allocator() const {
return *static_cast<const _Node_allocator*>(this);
}
protected:
using _Base::_M_get_node;
using _Base::_M_put_node;
using _Base::_M_header;
_Rb_tree_node*
_M_get_node() { return _Node_allocator::allocate(1); }
void
_M_put_node(_Rb_tree_node* __p) { _Node_allocator::deallocate(__p, 1); }
_Link_type
_M_create_node(const value_type& __x)
{
_Link_type __tmp = this->_M_get_node();
_Link_type __tmp = _M_get_node();
try
{ std::_Construct(&__tmp->_M_value_field, __x); }
catch(...)
@ -391,9 +330,12 @@ namespace std
_M_put_node(__p);
}
protected:
_Rb_tree_node_base _M_header;
size_type _M_node_count; // keeps track of size of tree
_Compare _M_key_compare;
protected:
_Base_ptr&
_M_root() { return this->_M_header._M_parent; }
@ -485,20 +427,27 @@ namespace std
public:
// allocation/deallocation
_Rb_tree()
: _Base(allocator_type()), _M_node_count(0), _M_key_compare()
: _Node_allocator(allocator_type()),
_M_node_count(0),
_M_key_compare()
{ _M_empty_initialize(); }
_Rb_tree(const _Compare& __comp)
: _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp)
: _Node_allocator(allocator_type()),
_M_node_count(0),
_M_key_compare(__comp)
{ _M_empty_initialize(); }
_Rb_tree(const _Compare& __comp, const allocator_type& __a)
: _Base(__a), _M_node_count(0), _M_key_compare(__comp)
: _Node_allocator(__a),
_M_node_count(0),
_M_key_compare(__comp)
{ _M_empty_initialize(); }
_Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
: _Base(__x.get_allocator()), _M_node_count(0),
_M_key_compare(__x._M_key_compare)
: _Node_allocator(__x.get_allocator()),
_M_node_count(0),
_M_key_compare(__x._M_key_compare)
{
if (__x._M_root() == 0)
_M_empty_initialize();

View File

@ -60,7 +60,6 @@ namespace __gnu_cxx
{
using std::size_t;
using std::ptrdiff_t;
using std::_Alloc_traits;
using std::_Construct;
using std::_Destroy;
using std::allocator;
@ -201,73 +200,27 @@ struct _Slist_iterator : public _Slist_iterator_base
}
};
// Base class that encapsulates details of allocators. Three cases:
// an ordinary standard-conforming allocator, a standard-conforming
// allocator with no non-static data, and an SGI-style allocator.
// This complexity is necessary only because we're worrying about backward
// compatibility and because we want to avoid wasting storage on an
// allocator instance if it isn't necessary.
// Base for general standard-conforming allocators.
template <class _Tp, class _Allocator, bool _IsStatic>
class _Slist_alloc_base {
public:
typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return _M_node_allocator; }
_Slist_alloc_base(const allocator_type& __a) : _M_node_allocator(__a) {}
protected:
_Slist_node<_Tp>* _M_get_node()
{ return _M_node_allocator.allocate(1); }
void _M_put_node(_Slist_node<_Tp>* __p)
{ _M_node_allocator.deallocate(__p, 1); }
protected:
typename _Alloc_traits<_Slist_node<_Tp>,_Allocator>::allocator_type
_M_node_allocator;
_Slist_node_base _M_head;
};
// Specialization for instanceless allocators.
template <class _Tp, class _Allocator>
class _Slist_alloc_base<_Tp,_Allocator, true> {
public:
typedef typename _Alloc_traits<_Tp,_Allocator>::allocator_type
allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_Slist_alloc_base(const allocator_type&) {}
protected:
typedef typename _Alloc_traits<_Slist_node<_Tp>, _Allocator>::_Alloc_type
_Alloc_type;
_Slist_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
void _M_put_node(_Slist_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
protected:
_Slist_node_base _M_head;
};
template <class _Tp, class _Alloc>
struct _Slist_base
: public _Slist_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
: public _Alloc::template rebind<_Slist_node<_Tp> >::other
{
typedef _Slist_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
_Base;
typedef typename _Base::allocator_type allocator_type;
typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc;
typedef _Alloc allocator_type;
allocator_type get_allocator() const {
return *static_cast<const _Node_alloc*>(this);
}
_Slist_base(const allocator_type& __a)
: _Base(__a) { this->_M_head._M_next = 0; }
: _Node_alloc(__a) { this->_M_head._M_next = 0; }
~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
protected:
_Slist_node_base _M_head;
_Slist_node<_Tp>* _M_get_node() { return _Node_alloc::allocate(1); }
void _M_put_node(_Slist_node<_Tp>* __p) { _Node_alloc::deallocate(__p, 1); }
protected:
_Slist_node_base* _M_erase_after(_Slist_node_base* __pos)
{
_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);