Here is an other attempt. This time I am storing the node using allocator pointer just in the singly linked list of nodes. Buckets are still __node_base* so that the custom pointer is not manipulated too much. Moreover iterators are also using node raw pointers. As advised I introduced new types in case of custom pointers. But I am also using those in gnu versioned namespace so that I could more easily test this new code with all existing test cases. Note that as we are at introducing a new abi I am also changing node memory layout in this case. I think it is better to put the hash code cache before the node value rather than after. It will be closer to the begining of the node and so accessible without mem page fault. To be clear the node mem layout is: - next node pointer - node value_type - hash code (optional) The new node mem layout is: - next node pointer - hash code (optional) - node value_type Here is the git log in case you validate it.     libstdc++: Store allocator::pointer in hashtable implementation     Use allocator pointer type in _Hashtable implementation.             * include/bits/hashtable_policy.h             (_ReuseOrAllocNode<>::__node_type): Remove.             (_ReuseOrAllocNode<>::__node_pointer): New.             (_ReuseOrAllocNode(__node_pointer, __hashtable_alloc&)): Adapt to use             latter. (_ReuseOrAllocNode<>::operator()(_Arg&&)): Return latter.             (_AllocNode<>::__node_type): Remove.             (_AllocNode<>::__node_pointer): New. (_AllocNode<>::operator()<>(_Arg&&)): Return latter.             (_Hash_node_cust_ptr_base<>): New.             (_Hash_node_cache_value): New.             (_Hash_node<>::__node_base): New.             (_Hash_node<>::__node_ptr): New.             (_Hash_node<>::__node_type): New.             (_Hash_node<>::__node_value_cache_type): New.             (_Hash_node<>::_M_next_ptr()): New.             (_Hash_cust_ptr_node): New.             (_Hashtable_iterator_base): New.             (_Node_iterator_base<>): Inherits from latter.             (_Hashtable_iterator):             New.             (_Hashtable_const_iterator):             New.             (_Insert_base<>::__alloc_ptr): New.             (_Insert_base<>::__node_type): New. Define conditionally to _Hash_node<>             or _Hash_cust_ptr_node<> depending on __alloc_ptr being a raw pointer.             (_Insert_base<>::__node_alloc_type): New.             (_Insert_base<>::__hashtable_alloc): Remove.             (_Insert_base<>::iterator): Define conditionally to _Node_iterator<>             or _Hashtable_iterator<> depending on __alloc_ptr being a raw pointer.             (_Insert_base<>::const_iterator): Define conditionally to             _Node_const_iterator<> or _Hashtable_const_iterator<> depending on             __alloc_ptr being a raw pointer.             (_Hashtable_local_iter_base<>): New.             (_Hash_code_base<>::_M_bucket_index(const _Hash_node_cache_value<>&,             size_t)): New.             (_Hashtable_local_iter_base<>): New.             (_Hashtable_local_iterator<>): New.             (_Hashtable_const_local_iterator<>): New.             (_Hashtable_base<>::_M_equals(const _Key&, __hash_code,             const _Hash_node_cache_value<>&): New.             (_Hashtable_base<>::_M_node_equals(const _Hash_node_cache_value<>&,             const _Hash_node_cache_value<>&)): New.             (_Hashtable_alloc<>::__value_alloc_traits): Remove.             (_Hashtable_alloc<>::__node_base_ptr): Remove.             * include/bits/hashtable.h (_Hashtable<>): Adapt.             * testsuite/23_containers/unordered_map/allocator/ext_ptr.cc: New test.             * testsuite/23_containers/unordered_multimap/allocator/ext_ptr.cc:             New test.             * testsuite/23_containers/unordered_multiset/allocator/ext_ptr.cc:             New test.             * testsuite/23_containers/unordered_set/allocator/ext_ptr.cc: Adapt. Tested under Linux x86_64 normal and version namespace modes. François On 20/10/20 1:04 pm, Jonathan Wakely wrote: > On 28/09/20 22:37 +0200, François Dumont via Libstdc++ wrote: >> Following recent changes on _Hashtable I rebase the patch and >> completely review it. >> >> I managed to integrate the allocator custom pointer type without >> touching to _Hashtable base types like _Hash_code_base or >> _Hashtable_base. However I cannot see how to use the custom pointer >> type without impacting the node types like _Hash_node_base which now >> takes a template parameter, the custom pointer type. >> >> On an abi point of view node types are different however the data >> structure is the same. The only difference is that the >> _Hash_node_base _M_nxt is now a _Hash_node<> custom pointer rather >> than a simple _Hash_node_base*. >> >> Even if this patch can't go in because of the abi breaking change I >> am going to adapt some of the code simplifications for master. >> Especially the _Hash_code_base and _Local_iterator_base simplifications. >> >> Let me know if you can think of a way to integrate the custom pointer >> without impacting abi. Unless impacting node types and associated >> iterator types is fine even if I already noticed that pretty printer >> tests are broken with those changes. > > The approach I used for the other containers (which was never > completed and committed) is something like: > > struct _Node_base > { >   _Node_base* _M_next; > }; > > template > struct _Fancy_node_base > { >   _Ptr _M_next; > }; > > template >   using node_base = conditional_t::value, >                                   _Node_base, > _Fancy_node_base<_Ptr>>; > > This way all existing code that has allocators with non-fancy pointers > continues to use the same type. Code using fancy pointers (which > doesn't currently work properly anyway) changes to use the new types > that depend on the pointer type. >