[interprocess] Container requirements for Boost.Interprocess allocators

The boost inteprocess documentation [1] says that all objects must be constructed-destroyed via allocator::construct and allocator::destroy functions when using the interprocess allocators. However, according to the draft of the next C++ Standard [2] 20.1.6/2, allocator::construct is strictly equivalent to placement new and allocator::destroy stricly equivalent to a call to the destructor, with the pointer type casted to void*. Therefore why is such a requirement necessary? [1] http://ice.prohosting.com/newfunk/boost/libs/interprocess/doc/html/interproc... [2] http://open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1905.pdf

Mathias Gaunard wrote:
The boost inteprocess documentation [1] says that all objects must be constructed-destroyed via allocator::construct and allocator::destroy functions when using the interprocess allocators.
However, according to the draft of the next C++ Standard [2] 20.1.6/2, allocator::construct is strictly equivalent to placement new and allocator::destroy stricly equivalent to a call to the destructor, with the pointer type casted to void*.
Therefore why is such a requirement necessary?
Basically because the pointer type of Interprocess allocators is not a raw pointer, but a relative one (offset_ptr). This way containers using allocator::pointer as their pointer type can be mapped by different processes, in different base addresses. If you try to do this: using boost::interprocess; typedef allocator<MyClass, managed_shared_memory::segment_manager> MyAlloc; managed_shared_memory mem(); MyAlloc alloc(mem.get_segment_manager()); MyClass *myclass = new(alloc.allocate(1)) MyClass; you will get a compilation error, because "allocate" returns allocator::pointer and that pointer is not MyClass * but offset_ptr<MyClass>. You can get the raw pointer from offset_ptr<> using offset_ptr<T>::get() method. That's why containers should use allocator::construct() that is defined like: void construct(const pointer &ptr, const Convertible &value) { new(detail::get_pointer(ptr)) value_type(value); } It's conforming for a STL container to ignore allocator::pointer and suppose it's a raw pointer, but this sadly can support shared memory or any other smart pointer based allocators. Regards, Ion

Ion Gaztañaga wrote:
Basically because the pointer type of Interprocess allocators is not a raw pointer, but a relative one (offset_ptr).
Since in the standard there is a cast to void*, I thought that all pointer types needed to be convertibles to void* (with a conversion operator for example). But well, I guess it's cleaner to use the construct function.
participants (2)
-
Ion Gaztañaga
-
Mathias Gaunard