]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
stl_list.h (_List_base<>::_M_get_Node_allocator): Add.
authorPaolo Carlini <pcarlini@suse.de>
Tue, 3 Jan 2006 13:19:23 +0000 (13:19 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Tue, 3 Jan 2006 13:19:23 +0000 (13:19 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/bits/stl_tree.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc
libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc
libstdc++-v3/testsuite/testsuite_allocator.h

index 4db8a1328185dad90e7050d24c6d3626f87cb075..7a775d4f68b35aaf3b14cdb17e5c00c60882e78b 100644 (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.
index 2eb77673e28a53d604487c4c95980ea81dcb26af..d9bbb007b060ab7480c85a23c70369e2225741af 100644 (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()
index 03b70a39fb03e6574d91f8b9359427d534fc98be..1761bf5c133fb4ce16de033aba18f272cfde4bc1 100644 (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);
        }
 
index ad0e68df9c1625c393e6ff76943e7acded69ddad..c2acf87e3500c10eb2a70aea38decec33ea81a02 100644 (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)
          {
index c4107fa6e778ddf1c093ad2d73cbd40950dfdb62..43f69de450e2eb76000b6f47adf041748ad6dd11 100644 (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;
index 405f8e4caa7dad1c10c43499c3ba5e118ab61f01..54e741425dec6066125716366c83a28edf28a0ed 100644 (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 }
index a0286b0566d98294a1a814ebb7780555acf9809f..48f6ae68f69f7c2d1b086bb5fc472b07b5e2dc71 100644 (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 }
index 170c4db45c9cb49f877084509c7e26bb1bb9071f..0ea1215e3b4c6a150b758ff798cde358d8da62c1 100644 (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
     {