$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2007-06-09 12:20:56
Hi,
Evan Torrie wrote:
> [snip]
> 
>   Specifically, say I'm trying to port an existing heap-based structure into shared memory.
> 
> struct foo {
>   int x, y;
>   std::vector< std::string > keys;
>   struct foo* left, right;
> }
> 
> struct foo* root;
 >   What would this translate to in the boost::interprocess world?
Something like:
struct foo
{
    typedef boost::interprocess::allocator<char> char_allocator_t;
    typedef boost::interprocess::
       basic_string<char, std::char_traits<char>, char_allocator_t>
          string_t;
    typedef boost::interprocess::allocator<string_t> string_allocator_t;
    typedef boost::interprocess::
       vector<string_t, string_allocator_t> vector_t;
    int x, y;
    vector_t keys;
    boost::interprocess offset_ptr<foo> left, right;
}
>   Is it possible to write templatized versions of these data structures that would work
 > either with the existing std::allocator heap-based memory or with 
boost::interprocess
 >stateful allocators without needing to create two versions of this 
data structure?
Boost Interprocess containers can work with std allocators (code not 
compiled, it will surely contain errors):
//This is provided by boost 1.34
#include<boost/pointer_to_other.hpp>
template<class CharAllocator>
struct foo
{
    typedef CharAllocator char_allocator_t;
    typedef boost::interprocess::
       basic_string<char, std::char_traits<char>, char_allocator_t>
          string_t;
    typedef typename CharAllocator::template
       rebind<string_t>::other string_allocator_t;
    typedef boost::interprocess::
       vector<string_t, string_allocator_t> vector_t;
    typedef boost::pointer_to_other
       <typename CharAllocator::pointer, foo>::type foo_ptr_t;
    //Or alternatively, without using pointer_to_other
    //typedef typename CharAllocator::template
    //rebind<foo>::other::pointer foo_ptr_t;
    int x, y;
    vector_t keys;
    foo_ptr_t left, right;
    //Constructor needed for interprocess allocators
    foo(const CharAllocator &alloc)
       :   keys(string_allocator_t(alloc))
    {}
};
With the pointer type defined by the allocator you can define more 
pointers to other types. With Boost.Interprocess allocators you can use 
use rebind<> or pointer_to_other.
>   One problem I've encountered is that default constructors for
>   boost::interprocess::vector/string etc are not possible since they need 
>   to be constructed with a stateful allocator... so, does this mean that any constructor
>   for object foo requires an allocator to be passed in which is then used in the initializer
 >   list to initialize these member containers?
Yes. There is no way to have a default constructor, because the 
allocator needs the address of the shared memory segment and you can 
have several managed_shared_memory objects around.
Hope this helps,
Ion