
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