I have a similar question as before in boost::interprocess Containers of containers NOT in shared memory and How to I create a boost interprocess vector of interprocess containers but this time I like to use my class, which uses a scoped_allocator, also on the heap and shared memory.
- The solution to my first question was to use a template class with an allocator type
- In my second previous question it turned out that using a scoped_allocator together with a container of containers within the shared memory makes live easier.
Now I like to have both, is this possible? Attached a example with a working scoped_allocator but I have no idea how to template in this case the allocator of the class?
Thanks in advance :-)
Markus
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/container/scoped_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/algorithm/string.hpp>
namespace bi = boost::interprocess;
namespace bc = boost::container;
typedef bi::managed_shared_memory::segment_manager segment_manager_t;
typedef bc::scoped_allocator_adaptor<bi::allocator<void, segment_manager_t> > void_allocator;
class CheckList {
typedef void_allocator::rebind<double>::other double_allocator;
typedef bc::vector<double, double_allocator> double_vector;
public:
double_vector values;
typedef void_allocator allocator_type;
//Since void_allocator is convertible to any other allocator<T>, we can simplify
//the initialization taking just one allocator for all inner containers.
CheckList ( const allocator_type &void_alloc )
: values ( void_alloc ) {}
CheckList ( CheckList const& other, const allocator_type &void_alloc )
: values ( other.values, void_alloc ) {}
friend std::ostream &operator << ( std::ostream &os, const CheckList &o ) {
for ( size_t i = 0; i < o.values.size(); i++ ) os << (i>0?", ":"") << o.values[i];
return os;
}
};
class Lists {
typedef void_allocator::rebind<CheckList>::other checklist_allocator;
typedef bc::vector<CheckList, checklist_allocator> checklist_vector;
public:
Lists ( const void_allocator &void_alloc )
: checklists ( void_alloc )
{}
checklist_vector checklists;
friend std::ostream &operator << ( std::ostream &os, const Lists &o ) {
for ( size_t i = 0; i < o.checklists.size(); i++ ) os << o.checklists[i] << std::endl;
return os;
}
};
int main ( int argc, char **argv ) {
if ( argc > 1 && (boost::iequals ( "clear", argv[1] ) || boost::iequals ( "c", argv[1] ) ) ) {
std::cout << "Remove shared memory" << std::endl;
bi::shared_memory_object::remove ( "MySharedMemory" );
}
//Create shared memory
bi::managed_shared_memory segment ( bi::open_or_create,"MySharedMemory", 16*1024*1024 );
//An allocator convertible to any allocator<T, segment_manager_t> type
void_allocator alloc_inst ( segment.get_segment_manager() );
Lists *lists = segment.find_or_construct<Lists> ( "Lists" ) ( alloc_inst );
if ( lists->checklists.size() != 10 ) {
std::cout << "Create Data" << std::endl;
lists->checklists.resize ( 10 );
for ( size_t i = 0; i < lists->checklists.size(); i++ ) {
lists->checklists[i].values.resize ( i+1 );
for ( size_t j = 0; j < lists->checklists[i].values.size(); j++ ) {
lists->checklists[i].values[j] = j;
}
}
} else {
std::cout << "Data Exists" << std::endl;
}
std::cout << *lists << std::endl;
}