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> 2003-12-22 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/18_support/numeric_limits.cc: Add _GLIBCXX_ASSERT to * 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; } 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> template <class _Alloc>
class _Bvector_base class _Bvector_base
: public _Bvector_alloc_base<_Alloc, : public _Alloc::template rebind<_Bit_type>::other
_Alloc_traits<bool, _Alloc>::_S_instanceless>
{ {
typedef _Bvector_alloc_base<_Alloc, typedef typename _Alloc::template rebind<_Bit_type>::other _Bit_alloc_type;
_Alloc_traits<bool, _Alloc>::_S_instanceless>
_Base;
public: 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(const allocator_type& __a)
~_Bvector_base() { _Base::_M_deallocate(); } : _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 } // namespace __gnu_norm

View File

@ -261,79 +261,14 @@ namespace std
_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
_Rb_tree_node_base& __header); _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, template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = allocator<_Val> > 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: protected:
typedef _Rb_tree_node_base* _Base_ptr; typedef _Rb_tree_node_base* _Base_ptr;
@ -352,18 +287,22 @@ namespace std
typedef size_t size_type; typedef size_t size_type;
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type; typedef _Alloc allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); } allocator_type get_allocator() const {
return *static_cast<const _Node_allocator*>(this);
}
protected: protected:
using _Base::_M_get_node; _Rb_tree_node*
using _Base::_M_put_node; _M_get_node() { return _Node_allocator::allocate(1); }
using _Base::_M_header;
void
_M_put_node(_Rb_tree_node* __p) { _Node_allocator::deallocate(__p, 1); }
_Link_type _Link_type
_M_create_node(const value_type& __x) _M_create_node(const value_type& __x)
{ {
_Link_type __tmp = this->_M_get_node(); _Link_type __tmp = _M_get_node();
try try
{ std::_Construct(&__tmp->_M_value_field, __x); } { std::_Construct(&__tmp->_M_value_field, __x); }
catch(...) catch(...)
@ -391,9 +330,12 @@ namespace std
_M_put_node(__p); _M_put_node(__p);
} }
protected:
_Rb_tree_node_base _M_header;
size_type _M_node_count; // keeps track of size of tree size_type _M_node_count; // keeps track of size of tree
_Compare _M_key_compare; _Compare _M_key_compare;
protected:
_Base_ptr& _Base_ptr&
_M_root() { return this->_M_header._M_parent; } _M_root() { return this->_M_header._M_parent; }
@ -485,20 +427,27 @@ namespace std
public: public:
// allocation/deallocation // allocation/deallocation
_Rb_tree() _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(); } { _M_empty_initialize(); }
_Rb_tree(const _Compare& __comp) _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(); } { _M_empty_initialize(); }
_Rb_tree(const _Compare& __comp, const allocator_type& __a) _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(); } { _M_empty_initialize(); }
_Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x)
: _Base(__x.get_allocator()), _M_node_count(0), : _Node_allocator(__x.get_allocator()),
_M_key_compare(__x._M_key_compare) _M_node_count(0),
_M_key_compare(__x._M_key_compare)
{ {
if (__x._M_root() == 0) if (__x._M_root() == 0)
_M_empty_initialize(); _M_empty_initialize();

View File

@ -60,7 +60,6 @@ namespace __gnu_cxx
{ {
using std::size_t; using std::size_t;
using std::ptrdiff_t; using std::ptrdiff_t;
using std::_Alloc_traits;
using std::_Construct; using std::_Construct;
using std::_Destroy; using std::_Destroy;
using std::allocator; 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> template <class _Tp, class _Alloc>
struct _Slist_base struct _Slist_base
: public _Slist_alloc_base<_Tp, _Alloc, : public _Alloc::template rebind<_Slist_node<_Tp> >::other
_Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{ {
typedef _Slist_alloc_base<_Tp, _Alloc, typedef typename _Alloc::template rebind<_Slist_node<_Tp> >::other _Node_alloc;
_Alloc_traits<_Tp, _Alloc>::_S_instanceless> typedef _Alloc allocator_type;
_Base; allocator_type get_allocator() const {
typedef typename _Base::allocator_type allocator_type; return *static_cast<const _Node_alloc*>(this);
}
_Slist_base(const allocator_type& __a) _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); } ~_Slist_base() { _M_erase_after(&this->_M_head, 0); }
protected: 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_base* _M_erase_after(_Slist_node_base* __pos)
{ {
_Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next); _Slist_node<_Tp>* __next = (_Slist_node<_Tp>*) (__pos->_M_next);