+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.
// 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
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;
_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()
// 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
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)
// 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
* 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()); }
/**
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);
}
insert(iterator __position, _InputIterator __first,
_InputIterator __last)
{
- list __tmp(__first, __last, get_allocator());
+ list __tmp(__first, __last, _M_get_Node_allocator());
splice(__position, __tmp);
}
// 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
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()
{ }
_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)
{
// 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
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)
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;
// { 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
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 }
// { 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
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 }
// -*- 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
#include <cstddef>
#include <limits>
+#include <tr1/unordered_map>
+#include <cassert>
namespace
{
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
{