I am trying to use boost MultiIndex container in shared memory, I am using the replace function to update the records, when trying to compile, the compiler complained about the operator = being not present so I have overloaded the operator = as shown in the code below, however it seems that the compilation errors that are being thrown are because of the allocators. This is the first time I am using custom allocator for shared memory. Is there anything special that we need to do while overloading the operator = for strings with custom allocator?
1 #include <boost/interprocess/managed_shared_memory.hpp>
2 #include <boost/interprocess/allocators/allocator.hpp>
3 #include <boost/interprocess/containers/string.hpp>
4
5 #include <boost/multi_index_container.hpp>
6 #include <boost/multi_index/member.hpp>
7 #include <boost/multi_index/ordered_index.hpp>
8 #include <iostream>
9
10 using namespace boost::interprocess;
11 namespace bmi = boost::multi_index;
12
13 typedef managed_shared_memory::allocator<char>::type char_allocator;
14 typedef basic_string<char, std::char_traits<char>, char_allocator> shm_string;
15
16 //Data to insert in shared memory
17 struct tickerUpdateInfo
18 {
19 shm_string id;
20 shm_string symbol;
21 int last_update_time;
22
23 tickerUpdateInfo( const char * id_,
24 const char *symbol_,
25 int last_update_time_,
26 const char_allocator &a)
27 : id(id_, a), symbol(symbol_, a), last_update_time(last_update_time_) {
28 }
29
30 tickerUpdateInfo& operator=(const tickerUpdateInfo& other)
31 {
32 if (this != &other) {
33 id = other.id;
34 symbol = other.symbol;
35 last_update_time = other.last_update_time;
36 }
37 return *this;
38 }
39 };
40
41 std::ostream& operator<<(std::ostream& os, const tickerUpdateInfo& obj)
42 {
43 // write obj to stream
44 os << obj.id << " ";
45 os << obj.symbol << " ";
46 os << obj.last_update_time << " " << std::endl;
47 return os;
48 };
49
50
51 //Tags
52 struct id{};
53 struct symbol{};
54 struct last_update_time{};
55
56 // Define a multi_index_container of tickerUpdateInfos with following indices:
57 // - a unique index sorted by tickerUpdateInfo::id,
58 // - a unique index sorted by tickerUpdateInfo::symbol,
59 // - a non-unique index sorted by tickerUpdateInfo::last_update_time.
60 typedef bmi::multi_index_container<
61 tickerUpdateInfo,
62 bmi::indexed_by<
63 bmi::ordered_unique
64 <bmi::tag<id>, BOOST_MULTI_INDEX_MEMBER( tickerUpdateInfo, shm_string, id)>,
65 bmi::ordered_unique<
66 bmi::tag<symbol>,BOOST_MULTI_INDEX_MEMBER(tickerUpdateInfo, shm_string, symbol)>,
67 bmi::ordered_non_unique
68 <bmi::tag<last_update_time>, BOOST_MULTI_INDEX_MEMBER(tickerUpdateInfo, int, last_update_time)> >,
69 managed_shared_memory::allocator<tickerUpdateInfo>::type
70 > tickerUpdateInfo_set;
71
72 int main ()
73 {
74 //Remove shared memory on construction and destruction
75 struct shm_remove
76 {
77 shm_remove() { shared_memory_object::remove("MySharedMemory"); }
78 ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
79 } remover;
80
81 //Create shared memory
82 managed_shared_memory segment(create_only,"MySharedMemory", 65536);
83
84 //Construct the multi_index in shared memory
85 tickerUpdateInfo_set *es = segment.construct<tickerUpdateInfo_set>
86 ("TickerUpdateContainer") //Container's name in shared memory
87 ( tickerUpdateInfo_set::ctor_args_list()
88 , segment.get_allocator<tickerUpdateInfo>()); //Ctor parameters
89
90 //Now insert elements
91 char_allocator ca(segment.get_allocator<char>());
92 es->insert(tickerUpdateInfo("0","Joe", 31,ca));
93 es->insert(tickerUpdateInfo("1", "Robert",27, ca));
94 es->insert(tickerUpdateInfo( "2","John", 36,ca));
95 const tickerUpdateInfo_set::nth_index<1>::type& name_index = (*es).get<1>();
96 std::cout << "Before update " << std::endl;
97 std::copy(
98 name_index.begin(),name_index.end(),
99 std::ostream_iterator<tickerUpdateInfo>(std::cout));
100
101
102 typedef tickerUpdateInfo_set::index<symbol>::type ticker_update_info_set_by_symbol;
103 ticker_update_info_set_by_symbol & nm_index = (*es).get<symbol>();
104 ticker_update_info_set_by_symbol::iterator it=nm_index.find("Joe");
105 tickerUpdateInfo ticker_info = *it;
106 ticker_info.symbol = "Deb"; // update key
107 nm_index.replace(it, ticker_info ); // update her record
108 std::cout << "After update " << std::endl;
109 std::copy(
110 nm_index.begin(),nm_index.end(),
111 std::ostream_iterator<tickerUpdateInfo>(std::cout));
112 return 0;
113 }
Compilation Errors:
-- Compiling src/writer.cxx
In file included from include/boost/multi_index/ordered_index.hpp:56,
from src/writer.cxx:7:
include/boost/multi_index/detail/ord_index_ops.hpp: In constructor 'boost::container::basic_string<CharT, Traits, Alloc>::basic_string(const CharT*, const A&) [with CharT = char, Traits = std::char_traits<char>, A = boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >]':
include/boost/multi_index/detail/ord_index_ops.hpp:67: instantiated from 'Node* boost::multi_index::detail::ordered_index_find(Node*, Node*, const KeyFromValue&, const CompatibleKey&, const CompatibleCompare&) [with Node = boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<tickerUpdateInfo, boost::interprocess::allocator<tickerUpdateInfo, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > > >, KeyFromValue = boost::multi_index::member<tickerUpdateInfo, boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, &tickerUpdateInfo::symbol>, CompatibleKey = char [4], CompatibleCompare = std::less<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > >]'
include/boost/multi_index/ordered_index.hpp:434: instantiated from 'boost::multi_index::detail::bidir_node_iterator<boost::multi_index::detail::ordered_index_node<typename SuperMeta::type::node_type> > boost::multi_index::detail::ordered_index<KeyFromValue, Compare, SuperMeta, TagList, Category>::find(const CompatibleKey&) const [with CompatibleKey = char [4], KeyFromValue = boost::multi_index::member<tickerUpdateInfo, boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, &tickerUpdateInfo::symbol>, Compare = std::less<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > > >, SuperMeta = boost::multi_index::detail::nth_layer<2, tickerUpdateInfo, boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::tag<id, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<tickerUpdateInfo, boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, &tickerUpdateInfo::id>, mpl_::na>, boost::multi_index::ordered_unique<boost::multi_index::tag<symbol, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<tickerUpdateInfo, boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, &tickerUpdateInfo::symbol>, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::tag<last_update_time, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::member<tickerUpdateInfo, int, &tickerUpdateInfo::last_update_time>, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::interprocess::allocator<tickerUpdateInfo, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> > >, TagList = boost::mpl::v_item<symbol, boost::mpl::vector0<mpl_::na>, 0>, Category = boost::multi_index::detail::ordered_unique_tag]'
src/writer.cxx:107: instantiated from here
include/boost/multi_index/detail/ord_index_ops.hpp:67: error: no matching function for call to 'boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index> >::allocator()'
include/boost/interprocess/allocators/allocator.hpp:130: note: candidates are: boost::interprocess::allocator<T, SegmentManager>::allocator(const boost::interprocess::allocator<T, SegmentManager>&) [with T = char, SegmentManager = boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0ul>, boost::interprocess::iset_index>]
include/boost/in