This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch, v7] Prepare for DR 431 everywhere
- From: Paolo Carlini <pcarlini at suse dot de>
- To: libstdc++ <libstdc++ at gcc dot gnu dot org>
- Date: Fri, 16 Dec 2005 18:01:59 +0100
- Subject: [Patch, v7] Prepare for DR 431 everywhere
Hi,
the below is all the infrastructure I need to implement very simply
Option 3 for all the containers (+ string): just matter of begin able to
access the allocator by reference.
As hoped at the outset, I'm now sure that we can do that without
breaking binary compatibility: after completing the work next week we
can test it for a while in the branch and then merge it to mainline.
Also took the occasion to fix a very-very stupid bug in the
uneq_allocator testing class, which showed up while prototyping Option 3
for vector.
Tested x86-linux.
///////////////
2005-12-16 Paolo Carlini <pcarlini@suse.de>
* include/bits/stl_list.h (_List_base<>::_M_get_Node_allocator): Add.
(_M_get_Tp_allocator, get_allocator): Tidy.
(list<>::list(const list&), list(__gnu_cxx::__rvalref<_List>),
insert(iterator, size_type, const value_type&), insert(iterator,
_InputIterator, _InputIterator)): Use _M_get_Node_allocator.
* include/bits/stl_tree.h (_Rb_tree<>::_M_get_Node_allocator()): Add.
(_Rb_tree(const _Rb_tree<>&): Use it.
* include/bits/stl_map.h (map(__gnu_cxx::__rvalref<>)): Same.
* include/bits/stl_multimap.h (multimap(__gnu_cxx::__rvalref<>): Same.
* include/bits/stl_set.h (set(__gnu_cxx::__rvalref<>): Same.
* include/bits/stl_multiset.h (multiset(__gnu_cxx::__rvalref<>): Same.
* include/bits/stl_deque.h (_Deque_base<>::_M_get_map_allocator,
get_allocator): Tidy.
* include/bits/stl_vector.h (_Vector_base<>::get_allocator): Tidy.
* testsuite/testsuite_allocator.h (uneq_allocator<>::swap): Fix.
Index: include/bits/stl_list.h
===================================================================
--- include/bits/stl_list.h (revision 108607)
+++ include/bits/stl_list.h (working copy)
@@ -323,13 +323,21 @@
public:
typedef _Alloc allocator_type;
+ _Node_alloc_type&
+ _M_get_Node_allocator()
+ { return *static_cast<_Node_alloc_type*>(&this->_M_impl); }
+
+ const _Node_alloc_type&
+ _M_get_Node_allocator() const
+ { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); }
+
_Tp_alloc_type
_M_get_Tp_allocator() const
- { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); }
+ { return _Tp_alloc_type(_M_get_Node_allocator()); }
allocator_type
get_allocator() const
- { return _M_get_Tp_allocator(); }
+ { return allocator_type(_M_get_Node_allocator()); }
_List_base(const allocator_type& __a)
: _M_impl(__a)
@@ -425,16 +433,11 @@
// iterator types.
typedef _List_node<_Tp> _Node;
- /** @if maint
- * One data member plus two memory-handling functions. If the
- * _Alloc type requires separate instances, then one of those
- * will also be included, accumulated from the topmost parent.
- * @endif
- */
using _Base::_M_impl;
using _Base::_M_put_node;
using _Base::_M_get_node;
using _Base::_M_get_Tp_allocator;
+ using _Base::_M_get_Node_allocator;
/**
* @if maint
@@ -490,7 +493,7 @@
* by @a x.
*/
list(const list& __x)
- : _Base(__x.get_allocator())
+ : _Base(__x._M_get_Node_allocator())
{ _M_initialize_dispatch(__x.begin(), __x.end(), __false_type()); }
/**
@@ -505,7 +508,7 @@
*/
template<typename _List>
list(__gnu_cxx::__rvalref<_List> __x)
- : _Base(__x.__ref.get_allocator())
+ : _Base(__x.__ref._M_get_Node_allocator())
{ this->swap(__x.__ref); }
/**
@@ -836,7 +839,7 @@
void
insert(iterator __position, size_type __n, const value_type& __x)
{
- list __tmp(__n, __x, get_allocator());
+ list __tmp(__n, __x, _M_get_Node_allocator());
splice(__position, __tmp);
}
@@ -858,7 +861,7 @@
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
- list __tmp(__first, __last, get_allocator());
+ list __tmp(__first, __last, _M_get_Node_allocator());
splice(__position, __tmp);
}
Index: include/bits/stl_map.h
===================================================================
--- include/bits/stl_map.h (revision 108409)
+++ include/bits/stl_map.h (working copy)
@@ -181,7 +181,8 @@
*/
template<typename _Map>
map(__gnu_cxx::__rvalref<_Map> __x)
- : _M_t(__x.__ref._M_t.key_comp(), __x.__ref.get_allocator())
+ : _M_t(__x.__ref._M_t.key_comp(),
+ __x.__ref._M_t._M_get_Node_allocator())
{ this->swap(__x.__ref); }
/**
Index: include/bits/stl_set.h
===================================================================
--- include/bits/stl_set.h (revision 108409)
+++ include/bits/stl_set.h (working copy)
@@ -187,7 +187,7 @@
* The newly-created %set uses a copy of the allocation object used
* by @a x.
*/
- set(const set<_Key,_Compare,_Alloc>& __x)
+ set(const set<_Key, _Compare, _Alloc>& __x)
: _M_t(__x._M_t) { }
/**
@@ -202,8 +202,9 @@
*/
template<typename _Set>
set(__gnu_cxx::__rvalref<_Set> __x)
- : _M_t(__x.__ref._M_t.key_comp() , __x.__ref.get_allocator())
- { this->swap(__x.__ref); }
+ : _M_t(__x.__ref._M_t.key_comp(),
+ __x.__ref._M_t._M_get_Node_allocator())
+ { this->swap(__x.__ref); }
/**
* @brief Set assignment operator.
Index: include/bits/stl_multimap.h
===================================================================
--- include/bits/stl_multimap.h (revision 108409)
+++ include/bits/stl_multimap.h (working copy)
@@ -194,7 +194,8 @@
*/
template<typename _Multimap>
multimap(__gnu_cxx::__rvalref<_Multimap> __x)
- : _M_t(__x.__ref._M_t.key_comp(), __x.__ref.get_allocator())
+ : _M_t(__x.__ref._M_t.key_comp(),
+ __x.__ref._M_t._M_get_Node_allocator())
{ this->swap(__x.__ref); }
/**
Index: include/bits/stl_vector.h
===================================================================
--- include/bits/stl_vector.h (revision 108409)
+++ include/bits/stl_vector.h (working copy)
@@ -102,7 +102,7 @@
allocator_type
get_allocator() const
- { return _M_get_Tp_allocator(); }
+ { return allocator_type(_M_get_Tp_allocator()); }
_Vector_base(const allocator_type& __a)
: _M_impl(__a)
@@ -183,11 +183,6 @@
typedef _Alloc allocator_type;
protected:
- /** @if maint
- * These two functions and three data members are all from the
- * base class. They should be pretty self-explanatory, as
- * %vector uses a simple contiguous allocation scheme. @endif
- */
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_impl;
Index: include/bits/stl_deque.h
===================================================================
--- include/bits/stl_deque.h (revision 108409)
+++ include/bits/stl_deque.h (working copy)
@@ -360,7 +360,7 @@
allocator_type
get_allocator() const
- { return _M_get_Tp_allocator(); }
+ { return allocator_type(_M_get_Tp_allocator()); }
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
@@ -407,7 +407,7 @@
_Map_alloc_type
_M_get_map_allocator() const
- { return _M_get_Tp_allocator(); }
+ { return _Map_alloc_type(_M_get_Tp_allocator()); }
_Tp*
_M_allocate_node()
Index: include/bits/stl_multiset.h
===================================================================
--- include/bits/stl_multiset.h (revision 108409)
+++ include/bits/stl_multiset.h (working copy)
@@ -179,7 +179,7 @@
* The newly-created %multiset uses a copy of the allocation object used
* by @a x.
*/
- multiset(const multiset<_Key,_Compare,_Alloc>& __x)
+ multiset(const multiset<_Key, _Compare, _Alloc>& __x)
: _M_t(__x._M_t) { }
/**
@@ -194,8 +194,9 @@
*/
template<typename _Multiset>
multiset(__gnu_cxx::__rvalref<_Multiset> __x)
- : _M_t(__x.__ref._M_t.key_comp(), __x.__ref.get_allocator())
- { this->swap(__x.__ref); }
+ : _M_t(__x.__ref._M_t.key_comp(),
+ __x.__ref._M_t._M_get_Node_allocator())
+ { this->swap(__x.__ref); }
/**
* @brief %Multiset assignment operator.
@@ -205,7 +206,7 @@
* the allocator object is not copied.
*/
multiset<_Key,_Compare,_Alloc>&
- operator=(const multiset<_Key,_Compare,_Alloc>& __x)
+ operator=(const multiset<_Key, _Compare, _Alloc>& __x)
{
_M_t = __x._M_t;
return *this;
Index: include/bits/stl_tree.h
===================================================================
--- include/bits/stl_tree.h (revision 108409)
+++ include/bits/stl_tree.h (working copy)
@@ -348,9 +348,17 @@
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
+ _Node_allocator&
+ _M_get_Node_allocator()
+ { return *static_cast<_Node_allocator*>(&this->_M_impl); }
+
+ const _Node_allocator&
+ _M_get_Node_allocator() const
+ { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
+
allocator_type
get_allocator() const
- { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
+ { return allocator_type(_M_get_Node_allocator()); }
protected:
_Rb_tree_node*
@@ -570,7 +578,7 @@
{ }
_Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x)
- : _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare())
+ : _M_impl(__x._M_get_Node_allocator(), __x._M_impl._M_key_compare())
{
if (__x._M_root() != 0)
{
Index: testsuite/testsuite_allocator.h
===================================================================
--- testsuite/testsuite_allocator.h (revision 108607)
+++ testsuite/testsuite_allocator.h (working copy)
@@ -345,10 +345,9 @@
operator=(const uneq_allocator&);
// ... yet swappable!
- template<typename Tp1>
- friend inline void
- swap(uneq_allocator& a, uneq_allocator<Tp1>& b)
- { std::swap(a.personality, b.personality); }
+ friend inline void
+ swap(uneq_allocator& a, uneq_allocator& b)
+ { std::swap(a.personality, b.personality); }
template<typename Tp1>
friend inline bool