Boost logo

Boost :

Subject: Re: [boost] [context] implementation comments
From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2011-03-07 07:56:27


On 07.03.2011 12:19, Oliver Kowalke wrote:
>>> then Scott Meyers is completely wrong?
>> I don't know. What did he say?
> 'Effective STL' - page 52:
> '... final curiosity of STL allocatos, that most of the standard containers never make a single call to the allocators ... true for all the standard associative containers....'
Effective STL is old, and many of the caveats Scott mentions in Item 10
no longer apply to implementations that conform to the C++0x draft. For
example, implementations are no longer allowed to assume that
allocator<T>::pointer is T*. They are no longer allowed to assume that
any two instances of allocator<T> compare equal, or otherwise assume
that allocator state is irrelevant (and thus not keep a copy).
Besides, your quote is incomplete. The full relevant quote is "that most
of the standard containers never make a single call to the allocators
*with which they were instantiated*" (emphasis mine), which just means
that a std::list<int, allocator<int>> doesn't ever call
allocator<int>::allocate. Instead, it calls
allocator<_ListNode<int>>::allocate. But the correct C++0x form for such
an allocation looks roughly like this:

template <typename _T, typename _Alloc = std::allocator<_T>>
class list
{
     typedef typename _Alloc::template rebind<_ListNode<T>>::other
_NodeAlloc;
     typedef typename _NodeAlloc::pointer _NodePtr;
     _Alloc _M_alloc;

     _NodePtr __alloc_node() {
         // Create an allocator for this allocation. Not 100% sure that
the base allocator is passed, but pretty sure.
         _NodeAlloc __node_alloc(_M_alloc);
         _NodePtr mem = __node_alloc.allocate(1);
         new (mem) _ListNode<T>();
         return mem;
     }
};

It actually may look a bit different, since I haven't fully understood
the scoped allocator model yet. But that's the gist of it. The memory
comes from the allocator template you pass. It's just the concrete
instantiation that may be different.
Now, there may still be various implementations around that don't
actually implement this correctly. But the standard in C++0x is quite clear.

Sebastian


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk