stl_list.h (_List_base<>::_M_get_Node_allocator): Add.

2006-01-03  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&), 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_deque.h (_Deque_base<>::_M_get_map_allocator,
	get_allocator): Tidy.
	* include/bits/stl_vector.h (_Vector_base<>::get_allocator): Tidy.
	* testsuite/23_containers/map/operators/1_neg.cc: Adjust dg-error
	line numbers.
	* testsuite/23_containers/set/operators/1_neg.cc: Likewise.
	
	* testsuite/testsuite_allocator.h (uneq_allocator<>::swap): Fix.

	* testsuite/testsuite_allocator.h (class uneq_allocator): A simple
	non-empty testing allocator which can be endowed of a "personality"
	at construction time.

From-SVN: r109280
This commit is contained in:
Paolo Carlini 2006-01-03 13:19:23 +00:00 committed by Paolo Carlini
parent 1387fef3fb
commit 31905f3498
8 changed files with 200 additions and 33 deletions

View File

@ -1,3 +1,25 @@
2006-01-03 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&), 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_deque.h (_Deque_base<>::_M_get_map_allocator,
get_allocator): Tidy.
* include/bits/stl_vector.h (_Vector_base<>::get_allocator): Tidy.
* testsuite/23_containers/map/operators/1_neg.cc: Adjust dg-error
line numbers.
* testsuite/23_containers/set/operators/1_neg.cc: Likewise.
* testsuite/testsuite_allocator.h (uneq_allocator<>::swap): Fix.
* testsuite/testsuite_allocator.h (class uneq_allocator): A simple
non-empty testing allocator which can be endowed of a "personality"
at construction time.
2006-01-03 Paolo Carlini <pcarlini@suse.de>
* testsuite/27_io/basic_stringstream/str/char/1.cc: Initialize vars.

View File

@ -1,6 +1,7 @@
// Deque implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -369,7 +370,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
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;
@ -416,7 +417,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
_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()

View File

@ -1,6 +1,7 @@
// List implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -322,13 +323,21 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
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)
@ -424,16 +433,11 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
// 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
@ -489,7 +493,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
* 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()); }
/**
@ -803,7 +807,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
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);
}
@ -825,7 +829,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
list __tmp(__first, __last, get_allocator());
list __tmp(__first, __last, _M_get_Node_allocator());
splice(__position, __tmp);
}

View File

@ -1,6 +1,7 @@
// RB tree implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -348,10 +349,18 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
allocator_type
get_allocator() const
_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 allocator_type(_M_get_Node_allocator()); }
protected:
_Rb_tree_node*
_M_get_node()
@ -563,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ }
_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)
{

View File

@ -1,6 +1,7 @@
// Vector implementation -*- C++ -*-
// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -101,7 +102,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
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)
@ -182,11 +183,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
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;

View File

@ -1,6 +1,7 @@
// { dg-do compile }
// Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -41,5 +42,5 @@ void test01()
test &= itr == mapByName.end(); // { dg-error "no" }
}
// { dg-error "candidates are" "" { target *-*-* } 210 }
// { dg-error "candidates are" "" { target *-*-* } 214 }
// { dg-error "candidates are" "" { target *-*-* } 211 }
// { dg-error "candidates are" "" { target *-*-* } 215 }

View File

@ -1,6 +1,7 @@
// { dg-do compile }
// Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -39,5 +40,5 @@ void test01()
test &= itr == setByName.end(); // { dg-error "no" }
}
// { dg-error "candidates are" "" { target *-*-* } 285 }
// { dg-error "candidates are" "" { target *-*-* } 289 }
// { dg-error "candidates are" "" { target *-*-* } 286 }
// { dg-error "candidates are" "" { target *-*-* } 290 }

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
// Testing allocator for the C++ library testsuite.
//
// Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
// Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@ -37,6 +37,8 @@
#include <cstddef>
#include <limits>
#include <tr1/unordered_map>
#include <cassert>
namespace
{
@ -231,6 +233,137 @@ namespace __gnu_test
throw;
}
// A simple allocator which can be constructed endowed of a given
// "personality" (an integer), queried in operator== to simulate the
// behavior of realworld "unequal" allocators (i.e., not exploiting
// the provision in 20.1.5/4, first bullet). A global unordered_map,
// filled at allocation time with (pointer, personality) pairs, is
// then consulted to enforce the requirements in Table 32 about
// deallocation vs allocator equality. Note that this allocator is
// swappable, not assignable, consistently with Option 3 of DR 431
// (see N1599).
struct uneq_allocator_base
{
typedef std::tr1::unordered_map<void*, int> map_type;
// Avoid static initialization troubles and/or bad interactions
// with tests linking testsuite_allocator.o and playing globally
// with operator new/delete.
static map_type&
get_map()
{
static map_type alloc_map;
return alloc_map;
}
};
template<typename Tp>
class uneq_allocator
: private uneq_allocator_base
{
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 rebind
{ typedef uneq_allocator<Tp1> other; };
uneq_allocator() throw()
: personality(0) { }
uneq_allocator(int person) throw()
: personality(person) { }
template<typename Tp1>
uneq_allocator(const uneq_allocator<Tp1>& b) throw()
: personality(b.get_personality()) { }
int get_personality() const { return personality; }
pointer
address(reference x) const { return &x; }
const_pointer
address(const_reference x) const { return &x; }
pointer
allocate(size_type n, const void* = 0)
{
if (__builtin_expect(n > this->max_size(), false))
std::__throw_bad_alloc();
pointer p = static_cast<Tp*>(::operator new(n * sizeof(Tp)));
try
{
get_map().insert(map_type::value_type(reinterpret_cast<void*>(p),
personality));
}
catch(...)
{
::operator delete(p);
__throw_exception_again;
}
return p;
}
void
deallocate(pointer p, size_type)
{
assert( p );
map_type::iterator it = get_map().find(reinterpret_cast<void*>(p));
assert( it != get_map().end() );
// Enforce requirements in Table 32 about deallocation vs
// allocator equality.
assert( it->second == personality );
get_map().erase(it);
::operator delete(p);
}
size_type
max_size() const throw()
{ return size_t(-1) / sizeof(Tp); }
void
construct(pointer p, const Tp& val)
{ ::new(p) Tp(val); }
void
destroy(pointer p) { p->~Tp(); }
private:
// Not assignable...
uneq_allocator&
operator=(const uneq_allocator&);
// ... yet swappable!
friend inline void
swap(uneq_allocator& a, uneq_allocator& b)
{ std::swap(a.personality, b.personality); }
template<typename Tp1>
friend inline bool
operator==(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
{ return a.personality == b.personality; }
template<typename Tp1>
friend inline bool
operator!=(const uneq_allocator& a, const uneq_allocator<Tp1>& b)
{ return !(a == b); }
int personality;
};
template<typename Tp>
class throw_allocator
{