* include/bits/demangle.h: Fix allocator type correctness,
authoraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Dec 2003 18:35:38 +0000 (18:35 +0000)
committeraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Dec 2003 18:35:38 +0000 (18:35 +0000)
i.e. make sure that when we instantiate a container with a value
type and an allocator, the allocator's value type matches the
container's.
* include/bits/stl_deque.h (_Deque_alloc_base): Eliminate.
(_Deque_base): inherit directly from the deque's allocator.  Use
rebinding instead of _Alloc_traits.  Pick up data members from
_Deque_alloc_base.
* include/bits/stl_list.h (_List_alloc_base): Eliminate.
(_List_base): Inherit directly from the list's allocator.  Use
rebinding instead of _Alloc_traits.  Pick up data members from
_List_alloc_base.
* include/bits/stl_vector.h (_Vector_alloc_base): Eliminate
(_Vector_base): Inherit directly from the vector's allocator.  Use
rebinding instead of _Alloc_traits.  Pick up data members from
_Vector_alloc_base.
* include/ext/hashtable.h: Fix allocator type correctness (the
vector of buckets must be passed an allocator for objects of
type _Node*).  Use rebinding instead of _Alloc_traits.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74787 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/demangle.h
libstdc++-v3/include/bits/stl_deque.h
libstdc++-v3/include/bits/stl_list.h
libstdc++-v3/include/bits/stl_vector.h
libstdc++-v3/include/ext/hashtable.h

index e86b749..3d9f85e 100644 (file)
@@ -1,3 +1,25 @@
+2003-12-18  Matt Austern  <austern@apple.com>
+
+       * include/bits/demangle.h: Fix allocator type correctness,
+       i.e. make sure that when we instantiate a container with a value
+       type and an allocator, the allocator's value type matches the
+       container's.
+       * include/bits/stl_deque.h (_Deque_alloc_base): Eliminate.
+       (_Deque_base): inherit directly from the deque's allocator.  Use
+       rebinding instead of _Alloc_traits.  Pick up data members from 
+       _Deque_alloc_base.
+       * include/bits/stl_list.h (_List_alloc_base): Eliminate.
+       (_List_base): Inherit directly from the list's allocator.  Use
+       rebinding instead of _Alloc_traits.  Pick up data members from 
+       _List_alloc_base.
+       * include/bits/stl_vector.h (_Vector_alloc_base): Eliminate
+       (_Vector_base): Inherit directly from the vector's allocator.  Use
+       rebinding instead of _Alloc_traits.  Pick up data members from 
+       _Vector_alloc_base.
+       * include/ext/hashtable.h: Fix allocator type correctness (the
+       vector of buckets must be passed an allocator for objects of
+       type _Node*).  Use rebinding instead of _Alloc_traits.
+       
 2003-12-17  Paolo Carlini  <pcarlini@suse.de>
 
        * include/bits/locale_facets.tcc (time_get::_M_extract_via_format):
index 751e58c..82e2d06 100644 (file)
@@ -113,7 +113,9 @@ namespace __gnu_cxx
     template<typename Allocator>
       class qualifier
       {
-       typedef std::basic_string<char, std::char_traits<char>, Allocator>
+       typedef typename Allocator::template rebind<char>::other
+               char_Allocator;
+       typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
            string_type;
 
       private:
@@ -206,17 +208,22 @@ namespace __gnu_cxx
     template<typename Allocator>
       class qualifier_list
       {
-       typedef std::basic_string<char, std::char_traits<char>, Allocator>
+       typedef typename Allocator::template rebind<char>::other
+         char_Allocator;
+       typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
          string_type;
 
       private:
        mutable bool M_printing_suppressed;
-       std::vector<qualifier<Allocator>, Allocator> M_qualifier_starts;
+       typedef qualifier<Allocator> qual;
+        typedef typename Allocator::template rebind<qual>::other qual_Allocator;
+       typedef std::vector<qual, qual_Allocator> qual_vector;
+       qual_vector M_qualifier_starts;
        session<Allocator>& M_demangler;
 
        void decode_KVrA(string_type& prefix, string_type& postfix, int cvq,
-          typename std::vector<qualifier<Allocator>, Allocator>::
-             const_reverse_iterator const& iter_array) const;
+                        typename qual_vector::
+                          const_reverse_iterator const& iter_array) const;
 
       public:
        qualifier_list(session<Allocator>& demangler_obj)
@@ -270,7 +277,7 @@ namespace __gnu_cxx
 #if _GLIBCXX_DEMANGLER_CWDEBUG
        friend std::ostream& operator<<(std::ostream& os, qualifier_list const& list)
        {
-         typename std::vector<qualifier<Allocator>, Allocator>::const_iterator
+         typename qual_vector::const_iterator
              iter = list.M_qualifier_starts.begin();
          if (iter != list.M_qualifier_starts.end())
          {
@@ -344,7 +351,9 @@ namespace __gnu_cxx
       class session
       {
        friend class qualifier_list<Allocator>;
-       typedef std::basic_string<char, std::char_traits<char>, Allocator>
+       typedef typename Allocator::template rebind<char>::other
+           char_Allocator;
+       typedef std::basic_string<char, std::char_traits<char>, char_Allocator>
            string_type;
 
       private:
@@ -361,9 +370,13 @@ namespace __gnu_cxx
        bool M_name_is_conversion_operator;
        bool M_template_args_need_space;
        string_type M_function_name;
-       std::vector<int, Allocator> M_template_arg_pos;
+        typedef typename Allocator::template rebind<int>::other
+                int_Allocator;
+        typedef typename Allocator::template rebind<substitution_st>::other
+                subst_Allocator;
+       std::vector<int, int_Allocator> M_template_arg_pos;
        int M_template_arg_pos_offset;
-       std::vector<substitution_st, Allocator> M_substitutions_pos;
+       std::vector<substitution_st, subst_Allocator> M_substitutions_pos;
        implementation_details const& M_implementation_details;
 #if _GLIBCXX_DEMANGLER_CWDEBUG
        bool M_inside_add_substitution;
@@ -1690,8 +1703,7 @@ namespace __gnu_cxx
       void
       qualifier_list<Allocator>::decode_KVrA(
           string_type& prefix, string_type& postfix, int cvq,
-          typename std::vector<qualifier<Allocator>, Allocator>::
-             const_reverse_iterator const& iter_array) const
+          typename qual_vector::const_reverse_iterator const& iter_array) const
        {
          _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_KVrA");
          if ((cvq & cvq_K))
@@ -1703,7 +1715,7 @@ namespace __gnu_cxx
          if ((cvq & cvq_A))
          {
            int n = cvq >> 5;
-           for (typename std::vector<qualifier<Allocator>, Allocator>::
+           for (typename qual_vector::
                const_reverse_iterator iter = iter_array;
                iter != M_qualifier_starts.rend(); ++iter)
            {
@@ -1744,9 +1756,8 @@ namespace __gnu_cxx
       {
        _GLIBCXX_DEMANGLER_DOUT_ENTERING3("decode_qualifiers");
        int cvq = 0;
-       typename std::vector<qualifier<Allocator>, Allocator>::
-           const_reverse_iterator iter_array;
-       for(typename std::vector<qualifier<Allocator>, Allocator>::
+       typename qual_vector::const_reverse_iterator iter_array;
+       for(typename qual_vector::
            const_reverse_iterator iter = M_qualifier_starts.rbegin();
            iter != M_qualifier_starts.rend(); ++iter)
        {
@@ -2676,8 +2687,8 @@ namespace __gnu_cxx
   template<typename Allocator>
     struct demangle
     {
-      typedef Allocator allocator_type;
-      typedef std::basic_string<char, std::char_traits<char>, Allocator> 
+      typedef typename Allocator::template rebind<char>::other char_Allocator;
+      typedef std::basic_string<char, std::char_traits<char>, char_Allocator> 
          string_type;
       static string_type symbol(char const* in,
                                 demangler::implementation_details const& id);
@@ -2690,7 +2701,7 @@ namespace __gnu_cxx
   // Demangle `input' which should be a mangled function name as for
   // instance returned by nm(1).
   template<typename Allocator>
-    std::basic_string<char, std::char_traits<char>, Allocator>
+    typename demangle<Allocator>::string_type
     demangle<Allocator>::symbol(char const* input,
                                 demangler::implementation_details const& id)
     {
@@ -2741,7 +2752,7 @@ namespace __gnu_cxx
   // Demangle `input' which must be a zero terminated mangled type
   // name as for instance returned by std::type_info::name().
   template<typename Allocator>
-    std::basic_string<char, std::char_traits<char>, Allocator> 
+    typename demangle<Allocator>::string_type
     demangle<Allocator>::type(char const* input,
                               demangler::implementation_details const& id)
     {
index 2498bb6..64a24b1 100644 (file)
@@ -332,139 +332,70 @@ namespace __gnu_norm
     return __x + __n;
   }
   
-  
-  /// @if maint Primary default version.  @endif
   /**
    *  @if maint
-   *  Deque base class.  It has two purposes.  First, its constructor
-   *  and destructor allocate (but don't initialize) storage.  This makes
-   *  %exception safety easier.  Second, the base class encapsulates all of
-   *  the differences between SGI-style allocators and standard-conforming
-   *  allocators.  (See allocator.h for more on this topic.)  There are two
-   *  versions:  this ordinary one, and the space-saving specialization for
-   *  instanceless allocators.
+   *  Deque base class.  This class provides the unified face for %deque's
+   *  allocation.  This class's constructor and destructor allocate and
+   *  deallocate (but do not initialize) storage.  This makes %exception
+   *  safety easier.
+   *
+   *  Nothing in this class ever constructs or destroys an actual Tp element.
+   *  (Deque handles that itself.)  Only/All memory management is performed
+   *  here.
    *  @endif
   */
-  template<typename _Tp, typename _Alloc, bool __is_static>
-    class _Deque_alloc_base
-  {
-  public:
-    typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
-    allocator_type get_allocator() const { return _M_node_allocator; }
-  
-    _Deque_alloc_base(const allocator_type& __a)
-      : _M_node_allocator(__a), _M_map_allocator(__a),
-        _M_map(0), _M_map_size(0)
-    {}
-    
-  protected:
-    typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
-            _Map_allocator_type;
-  
-    _Tp*
-    _M_allocate_node()
-    {
-      return _M_node_allocator.allocate(__deque_buf_size(sizeof(_Tp)));
-    }
-  
-    void
-    _M_deallocate_node(_Tp* __p)
-    {
-      _M_node_allocator.deallocate(__p, __deque_buf_size(sizeof(_Tp)));
-    }
-  
-    _Tp**
-    _M_allocate_map(size_t __n) 
-      { return _M_map_allocator.allocate(__n); }
-  
-    void
-    _M_deallocate_map(_Tp** __p, size_t __n) 
-      { _M_map_allocator.deallocate(__p, __n); }
-  
-    allocator_type       _M_node_allocator;
-    _Map_allocator_type  _M_map_allocator;
-    _Tp**                _M_map;
-    size_t               _M_map_size;
-  };
-  
-  /// @if maint Specialization for instanceless allocators.  @endif
   template<typename _Tp, typename _Alloc>
-    class _Deque_alloc_base<_Tp, _Alloc, true>
+    class _Deque_base
+    : public _Alloc
   {
   public:
-    typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
-    allocator_type get_allocator() const { return allocator_type(); }
+    typedef _Alloc                                     allocator_type;
+    allocator_type get_allocator() const
+      { return *static_cast<const _Alloc*>(this); }
+
+    typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
+    typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
   
-    _Deque_alloc_base(const allocator_type&)
-      : _M_map(0), _M_map_size(0)
-    {}
-    
+    _Deque_base(const allocator_type& __a, size_t __num_elements)
+      : _Alloc(__a), _M_start(), _M_finish()
+      { _M_initialize_map(__num_elements); }
+    _Deque_base(const allocator_type& __a) 
+      : _Alloc(__a), _M_start(), _M_finish() {}
+    ~_Deque_base();    
+
   protected:
-    typedef typename _Alloc_traits<_Tp,_Alloc>::_Alloc_type  _Node_alloc_type;
-    typedef typename _Alloc_traits<_Tp*,_Alloc>::_Alloc_type _Map_alloc_type;
-  
+    typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
+    _Map_alloc_type _M_get_map_allocator() const
+      { return _Map_alloc_type(this->get_allocator()); }
+
     _Tp*
     _M_allocate_node()
     {
-      return _Node_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
+      return _Alloc::allocate(__deque_buf_size(sizeof(_Tp)));
     }
   
     void
     _M_deallocate_node(_Tp* __p)
     {
-      _Node_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+      _Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
     }
   
     _Tp**
     _M_allocate_map(size_t __n) 
-      { return _Map_alloc_type::allocate(__n); }
+      { return _M_get_map_allocator().allocate(__n); }
   
     void
     _M_deallocate_map(_Tp** __p, size_t __n) 
-      { _Map_alloc_type::deallocate(__p, __n); }
-  
-    _Tp**   _M_map;
-    size_t  _M_map_size;
-  };
-  
-  
-  /**
-   *  @if maint
-   *  Deque base class.  Using _Alloc_traits in the instantiation of the parent
-   *  class provides the compile-time dispatching mentioned in the parent's
-   *  docs.  This class provides the unified face for %deque's allocation.
-   *
-   *  Nothing in this class ever constructs or destroys an actual Tp element.
-   *  (Deque handles that itself.)  Only/All memory management is performed
-   *  here.
-   *  @endif
-  */
-  template<typename _Tp, typename _Alloc>
-    class _Deque_base
-    : public _Deque_alloc_base<_Tp,_Alloc,
-                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-  {
-  public:
-    typedef _Deque_alloc_base<_Tp,_Alloc,
-                               _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-            _Base;
-    typedef typename _Base::allocator_type             allocator_type;
-    typedef _Deque_iterator<_Tp,_Tp&,_Tp*>             iterator;
-    typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
-  
-    _Deque_base(const allocator_type& __a, size_t __num_elements)
-      : _Base(__a), _M_start(), _M_finish()
-      { _M_initialize_map(__num_elements); }
-    _Deque_base(const allocator_type& __a) 
-      : _Base(__a), _M_start(), _M_finish() {}
-    ~_Deque_base();    
-  
+      { _M_get_map_allocator().deallocate(__p, __n); }
+
   protected:
     void _M_initialize_map(size_t);
     void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
     void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
     enum { _S_initial_map_size = 8 };
   
+    _Tp** _M_map;
+    size_t _M_map_size;
     iterator _M_start;
     iterator _M_finish;
   };
@@ -670,9 +601,7 @@ namespace __gnu_norm
     using _Base::_M_deallocate_map;
   
     /** @if maint
-     *  A total of four data members accumulated down the heirarchy.  If the
-     *  _Alloc type requires separate instances, then two of them will also be
-     *  included in each deque.
+     *  A total of four data members accumulated down the heirarchy.
      *  @endif
     */
     using _Base::_M_map;
index 4524e9e..8fd2f71 100644 (file)
@@ -202,36 +202,16 @@ namespace __gnu_norm
     }
   };
   
-  
-  /// @if maint Primary default version.  @endif
   /**
    *  @if maint
-   *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
+   *  See bits/stl_deque.h's _Deque_base for an explanation.
    *  @endif
   */
-  template<typename _Tp, typename _Allocator, bool _IsStatic>
-    class _List_alloc_base
+  template <typename _Tp, typename _Alloc>
+    class _List_base
+    : public _Alloc::template rebind<_List_node<_Tp> >::other
   {
-  public:
-    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-            allocator_type;
-  
-    allocator_type
-    get_allocator() const { return _M_node_allocator; }
-  
-    _List_alloc_base(const allocator_type& __a)
-    : _M_node_allocator(__a)
-    { }
-  
   protected:
-    _List_node<_Tp>*
-    _M_get_node()
-    { return _M_node_allocator.allocate(1); }
-  
-    void
-    _M_put_node(_List_node<_Tp>* __p)
-    { _M_node_allocator.deallocate(__p, 1); }
-  
     // NOTA BENE
     // The stored instance is not actually of "allocator_type"'s type.
     // Instead we rebind the type to Allocator<List_node<Tp>>, which
@@ -240,69 +220,29 @@ namespace __gnu_norm
     // larger), and specializations on Tp may go unused because
     // List_node<Tp> is being bound instead.
     //
-    // We put this to the test in get_allocator above; if the two
-    // types are actually different, there had better be a conversion
-    // between them.
-    //
-    // None of the predefined allocators shipped with the library (as
-    // of 3.1) use this instantiation anyhow; they're all
-    // instanceless.
-    typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
-             _M_node_allocator;
-  
-    _List_node_base _M_node;
-  };
-  
-  /// @if maint Specialization for instanceless allocators.  @endif
-  template<typename _Tp, typename _Allocator>
-    class _List_alloc_base<_Tp, _Allocator, true>
-  {
-  public:
-    typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-            allocator_type;
-  
-    allocator_type
-    get_allocator() const { return allocator_type(); }
-  
-    _List_alloc_base(const allocator_type&)
-    { }
-  
-  protected:
-    // See comment in primary template class about why this is safe for the
-    // standard predefined classes.
-    typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
-            _Alloc_type;
-  
+    // We put this to the test in the constructors and in get_allocator,
+    // where we use conversions between allocator_type and 
+    // _Node_Alloc_type. The conversion is required by table 32 in [20.1.5].
+    typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
+      _Node_Alloc_type;
+
     _List_node<_Tp>*
     _M_get_node()
-    { return _Alloc_type::allocate(1); }
-  
+    { return _Node_Alloc_type::allocate(1); }
+
     void
     _M_put_node(_List_node<_Tp>* __p)
-    { _Alloc_type::deallocate(__p, 1); }
-  
+    { _Node_Alloc_type::deallocate(__p, 1); }
+
     _List_node_base _M_node;
-  };
-  
-  
-  /**
-   *  @if maint
-   *  See bits/stl_deque.h's _Deque_base for an explanation.
-   *  @endif
-  */
-  template <typename _Tp, typename _Alloc>
-    class _List_base
-    : public _List_alloc_base<_Tp, _Alloc,
-                              _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-  {
   public:
-    typedef _List_alloc_base<_Tp, _Alloc,
-                             _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-            _Base;
-    typedef typename _Base::allocator_type allocator_type;
-  
+    typedef _Alloc allocator_type;
+    allocator_type get_allocator() const
+
+    { return allocator_type(*static_cast<const _Node_Alloc_type*>(this)); }
+
     _List_base(const allocator_type& __a)
-    : _Base(__a)
+    : _Node_Alloc_type(__a)
     {
       this->_M_node._M_next = &this->_M_node;
       this->_M_node._M_prev = &this->_M_node;
index 94d6a4a..de9c1a3 100644 (file)
 
 namespace __gnu_norm
 {
-  /// @if maint Primary default version.  @endif
-  /**
-   *  @if maint
-   *  See bits/stl_deque.h's _Deque_alloc_base for an explanation.
-   *  @endif
-  */
-  template<typename _Tp, typename _Allocator, bool _IsStatic>
-    class _Vector_alloc_base
-    {
-    public:
-      typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-      allocator_type;
-
-      allocator_type
-      get_allocator() const { return _M_data_allocator; }
-  
-      _Vector_alloc_base(const allocator_type& __a)
-      : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
-      { }
-  
-    protected:
-      allocator_type _M_data_allocator;
-      _Tp*           _M_start;
-      _Tp*           _M_finish;
-      _Tp*           _M_end_of_storage;
-  
-      _Tp*
-      _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); }
-  
-      void
-      _M_deallocate(_Tp* __p, size_t __n)
-      { if (__p) _M_data_allocator.deallocate(__p, __n); }
-    };
-  
-  /// @if maint Specialization for instanceless allocators.  @endif
-  template<typename _Tp, typename _Allocator>
-    class _Vector_alloc_base<_Tp, _Allocator, true>
-    {
-    public:
-      typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
-             allocator_type;
-  
-      allocator_type
-      get_allocator() const { return allocator_type(); }
-      
-      _Vector_alloc_base(const allocator_type&)
-      : _M_start(0), _M_finish(0), _M_end_of_storage(0)
-      { }
-  
-    protected:
-      _Tp* _M_start;
-      _Tp* _M_finish;
-      _Tp* _M_end_of_storage;
-  
-      typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
-      
-      _Tp*
-      _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); }
-  
-      void
-      _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);}
-    };
-  
-  
   /**
    *  @if maint
    *  See bits/stl_deque.h's _Deque_base for an explanation.
@@ -138,20 +74,19 @@ namespace __gnu_norm
   */
   template<typename _Tp, typename _Alloc>
     struct _Vector_base
-    : public _Vector_alloc_base<_Tp, _Alloc,
-                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
+    : public _Alloc
     {
     public:
-      typedef _Vector_alloc_base<_Tp, _Alloc,
-                                _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
-         _Base;
-      typedef typename _Base::allocator_type allocator_type;
+      typedef _Alloc allocator_type;
+
+      allocator_type
+      get_allocator() const { return *static_cast<const _Alloc*>(this); }
 
       _Vector_base(const allocator_type& __a)
-      : _Base(__a) { }
+      : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) { }
       
       _Vector_base(size_t __n, const allocator_type& __a)
-      : _Base(__a)
+      : _Alloc(__a)
       {
        this->_M_start = this->_M_allocate(__n);
        this->_M_finish = this->_M_start;
@@ -161,6 +96,18 @@ namespace __gnu_norm
       ~_Vector_base() 
       { _M_deallocate(this->_M_start,
                      this->_M_end_of_storage - this->_M_start); }
+
+    public:
+      _Tp*           _M_start;
+      _Tp*           _M_finish;
+      _Tp*           _M_end_of_storage;
+  
+      _Tp*
+      _M_allocate(size_t __n) { return _Alloc::allocate(__n); }
+  
+      void
+      _M_deallocate(_Tp* __p, size_t __n)
+      { if (__p) _Alloc::deallocate(__p, __n); }
     };
   
   
@@ -209,8 +156,7 @@ namespace __gnu_norm
     protected:
       /** @if maint
        *  These two functions and three data members are all from the
-       *  top-most base class, which varies depending on the type of
-       *  %allocator.  They should be pretty self-explanatory, as
+       *  base class.  They should be pretty self-explanatory, as
        *  %vector uses a simple contiguous allocation scheme.  @endif
        */
       using _Base::_M_allocate;
@@ -347,8 +293,7 @@ namespace __gnu_norm
        }
   
       /// Get a copy of the memory allocation object.
-      allocator_type
-      get_allocator() const { return _Base::get_allocator(); }
+      using _Base::get_allocator;
       
       // iterators
       /**
index 4e5ea09..54540c4 100644 (file)
@@ -77,7 +77,6 @@ using std::size_t;
 using std::ptrdiff_t;
 using std::forward_iterator_tag;
 using std::input_iterator_tag;
-using std::_Alloc_traits;
 using std::_Construct;
 using std::_Destroy;
 using std::distance;
@@ -242,10 +241,14 @@ private:
   typedef _Hashtable_node<_Val> _Node;
 
 public:
-  typedef typename _Alloc_traits<_Val,_Alloc>::allocator_type allocator_type;
+  typedef _Alloc allocator_type;
   allocator_type get_allocator() const { return _M_node_allocator; }
 private:
-  typename _Alloc_traits<_Node, _Alloc>::allocator_type _M_node_allocator;
+  typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc;
+  typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc;
+  typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type;
+
+  _Node_Alloc _M_node_allocator;
   _Node* _M_get_node() { return _M_node_allocator.allocate(1); }
   void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); }
 
@@ -253,7 +256,7 @@ private:
   hasher                _M_hash;
   key_equal             _M_equals;
   _ExtractKey           _M_get_key;
-  vector<_Node*,_Alloc> _M_buckets;
+  _Vector_type          _M_buckets;
   size_type             _M_num_elements;
 
 public:
@@ -876,8 +879,7 @@ void hashtable<_Val,_Key,_HF,_Ex,_Eq,_All>
   if (__num_elements_hint > __old_n) {
     const size_type __n = _M_next_size(__num_elements_hint);
     if (__n > __old_n) {
-      vector<_Node*, _All> __tmp(__n, (_Node*)(0),
-                                 _M_buckets.get_allocator());
+      _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator());
       try {
         for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) {
           _Node* __first = _M_buckets[__bucket];