I am currently writting a smart pointer which is reasonnably stable and I
decided supporting allocators for completion because of its increase in
efficiency when the same pool used by containers is shared. I was told the
new standards are being finalized and I am hoping minor but important
changes could be applied before anything else.
To give a quick overview on the current status of this topic, you will find
below the latest text relating to allocator member functions (n2641). We
see over there there are no dictinction between the pointer type returned by
allocate() and the pointer type expected by deallocate() and destroy().
This is a big problem because this logic doesn't make sense anymore if smart
pointers are to be used. Smart pointers are owners of their objects and
aren't in no way going to give away external access to its object. We need
these functions to use
1) distinct pointer type from the one returned by allocate()
2) make the parameter (pointer) passed as a non-const reference
The latter is necessary to make changes to either the smart pointer itself
or the object pointed to in case raw pointer are used. We can see my
personnal implementation here and I would like to propose the following
function signatures:
template <typename T>
class shifted_allocator
{
public:
typedef shifted<T value_type;
typedef shifted_ptr<T pointer;
typedef shifted_ptr<const T const_pointer;
value_type * allocate(size_type s, const void * = 0);
void deallocate(pointer & p, size_type);
void construct(value_type * p, const T & x);
void destroy(pointer & p);
...
};
** Allocator member functions **
1)
pointer X::allocate(size_type n);
pointer X::allocate(size_type n, const_generic_pointer hint);
Effects: Memory is allocated for n objects of type value_type but the
objects are not constructed. [Footnote: It is intended that a.allocate be an
efficient means of allocating a single object of type T, even when sizeof(T)
is small. That is, there is no need for a container to maintain its own
"free list". - end footnote] The optional argument, p, may
Returns: A pointer to the allocated memory. [Note: If n == 0, the return
value is unspecified. If n 1, the means by which a program gains access to
the second and subsequent allocated objects is determined outside of the
Allocator concept. See RandomAccessAllocator, below, for one common
approach. - end note]
Throws: allocate may raise an appropriate exception.
Remark: The use of hint is unspecified, but intended as an aid to locality
if an implementation so desires. [ Note: In a container member function, the
address of an adjacent element is often a good choice to pass for the hint
argument. - end note ]
2)
void X::deallocate(pointer p, size_type n);
Preconditions: All n value_type objects in the area pointed to by p shall be
destroyed prior to this call. n shall match the value passed to allocate to
obtain this memory. [Note: p shall not be singular. - end note]
Throws: Does not throw exceptions.
3)
void X::destroy(pointer p);
Effects: Calls the destructor on the object at p but does not deallocate it.
Regards,
-Phil
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]