1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2004-2012. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
16 #include <boost/interprocess/managed_external_buffer.hpp>
17 #include <boost/interprocess/managed_heap_memory.hpp>
18 #include <boost/interprocess/containers/list.hpp>
19 #include <boost/interprocess/detail/type_traits.hpp>
20 #include <boost/move/detail/type_traits.hpp>
21 #include <boost/interprocess/allocators/node_allocator.hpp>
22 #include "print_container.hpp"
24 /******************************************************************************/
26 /* This example constructs repeats the same operations with std::list, */
27 /* shmem_list in user provided buffer, and shmem_list in heap memory */
29 /******************************************************************************/
31 using namespace boost::interprocess
;
33 //We will work with wide characters for user memory objects
34 //Alias <integer> node allocator type
35 typedef node_allocator
36 <int, wmanaged_external_buffer::segment_manager
> user_node_allocator_t
;
37 typedef node_allocator
38 <int, wmanaged_heap_memory::segment_manager
> heap_node_allocator_t
;
41 typedef list
<int, user_node_allocator_t
> MyUserList
;
42 typedef list
<int, heap_node_allocator_t
> MyHeapList
;
43 typedef std::list
<int> MyStdList
;
45 //Function to check if both lists are equal
46 bool CheckEqual(MyUserList
*userlist
, MyStdList
*stdlist
, MyHeapList
*heaplist
)
48 return std::equal(userlist
->begin(), userlist
->end(), stdlist
->begin()) &&
49 std::equal(heaplist
->begin(), heaplist
->end(), stdlist
->begin());
54 //Create the user memory who will store all objects
55 const int size_aligner
= sizeof(::boost::container::dtl::max_align_t
);
56 const int memsize
= 65536/size_aligner
*size_aligner
;
57 static ::boost::container::dtl::max_align_t static_buffer
[memsize
/size_aligner
];
60 //Now test move semantics
61 managed_heap_memory
original(memsize
);
62 managed_heap_memory
move_ctor(boost::move(original
));
63 managed_heap_memory move_assign
;
64 move_assign
= boost::move(move_ctor
);
65 original
.swap(move_assign
);
68 //Now test move semantics
69 managed_external_buffer
original(create_only
, static_buffer
, memsize
);
70 managed_external_buffer
move_ctor(boost::move(original
));
71 managed_external_buffer move_assign
;
72 move_assign
= boost::move(move_ctor
);
73 original
.swap(move_assign
);
76 //Named new capable user mem allocator
77 wmanaged_external_buffer
user_buffer(create_only
, static_buffer
, memsize
);
79 //Named new capable heap mem allocator
80 wmanaged_heap_memory
heap_buffer(memsize
);
84 wmanaged_external_buffer user_default
;
85 wmanaged_external_buffer
temp_external(boost::move(user_buffer
));
86 user_default
= boost::move(temp_external
);
87 user_buffer
= boost::move(user_default
);
88 wmanaged_heap_memory heap_default
;
89 wmanaged_heap_memory
temp_heap(boost::move(heap_buffer
));
90 heap_default
= boost::move(temp_heap
);
91 heap_buffer
= boost::move(heap_default
);
95 user_buffer
.reserve_named_objects(100);
96 heap_buffer
.reserve_named_objects(100);
98 //User memory allocator must be always be initialized
99 //since it has no default constructor
100 MyUserList
*userlist
= user_buffer
.construct
<MyUserList
>(L
"MyUserList")
101 (user_buffer
.get_segment_manager());
103 MyHeapList
*heaplist
= heap_buffer
.construct
<MyHeapList
>(L
"MyHeapList")
104 (heap_buffer
.get_segment_manager());
107 MyStdList
*stdlist
= new MyStdList
;
111 for(i
= 0; i
< max
; ++i
){
112 userlist
->push_back(i
);
113 heaplist
->push_back(i
);
114 stdlist
->push_back(i
);
116 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
118 userlist
->erase(userlist
->begin()++);
119 heaplist
->erase(heaplist
->begin()++);
120 stdlist
->erase(stdlist
->begin()++);
121 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
123 userlist
->pop_back();
124 heaplist
->pop_back();
126 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
128 userlist
->pop_front();
129 heaplist
->pop_front();
130 stdlist
->pop_front();
131 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
133 std::vector
<int> aux_vect
;
134 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
135 aux_vect
.assign(50, -1);
136 userlist
->assign(aux_vect
.begin(), aux_vect
.end());
137 heaplist
->assign(aux_vect
.begin(), aux_vect
.end());
138 stdlist
->assign(aux_vect
.begin(), aux_vect
.end());
139 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
145 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
147 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
148 aux_vect
.assign(50, 0);
150 userlist
->insert(userlist
->begin(), aux_vect
.begin(), aux_vect
.end());
151 heaplist
->insert(heaplist
->begin(), aux_vect
.begin(), aux_vect
.end());
152 stdlist
->insert(stdlist
->begin(), aux_vect
.begin(), aux_vect
.end());
157 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
159 userlist
->sort(std::greater
<int>());
160 heaplist
->sort(std::greater
<int>());
161 stdlist
->sort(std::greater
<int>());
162 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
164 userlist
->resize(userlist
->size()/2);
165 heaplist
->resize(heaplist
->size()/2);
166 stdlist
->resize(stdlist
->size()/2);
167 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
169 userlist
->remove(*userlist
->begin());
170 heaplist
->remove(*heaplist
->begin());
171 stdlist
->remove(*stdlist
->begin());
172 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
174 for(i
= 0; i
< max
; ++i
){
175 userlist
->push_back(i
);
176 heaplist
->push_back(i
);
177 stdlist
->push_back(i
);
180 MyUserList
otheruserlist(*userlist
);
181 MyHeapList
otherheaplist(*heaplist
);
182 MyStdList
otherstdlist(*stdlist
);
183 userlist
->splice(userlist
->begin(), otheruserlist
);
184 heaplist
->splice(heaplist
->begin(), otherheaplist
);
185 stdlist
->splice(stdlist
->begin(), otherstdlist
);
186 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
188 otheruserlist
= *userlist
;
189 otherheaplist
= *heaplist
;
190 otherstdlist
= *stdlist
;
192 userlist
->sort(std::greater
<int>());
193 heaplist
->sort(std::greater
<int>());
194 stdlist
->sort(std::greater
<int>());
195 otheruserlist
.sort(std::greater
<int>());
196 otherheaplist
.sort(std::greater
<int>());
197 otherstdlist
.sort(std::greater
<int>());
198 userlist
->merge(otheruserlist
, std::greater
<int>());
199 heaplist
->merge(otherheaplist
, std::greater
<int>());
200 stdlist
->merge(otherstdlist
, std::greater
<int>());
201 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
203 user_buffer
.destroy
<MyUserList
>(L
"MyUserList");
206 //Fill heap buffer until is full
209 heaplist
->insert(heaplist
->end(), 0);
212 catch(boost::interprocess::bad_alloc
&){}
214 MyHeapList::size_type heap_list_size
= heaplist
->size();
216 //Copy heap buffer to another
217 const char *insert_beg
= static_cast<char*>(heap_buffer
.get_address());
218 const char *insert_end
= insert_beg
+ heap_buffer
.get_size();
219 std::vector
<char> grow_copy (insert_beg
, insert_end
);
222 heap_buffer
.destroy
<MyHeapList
>(L
"MyHeapList");
225 grow_copy
.resize(memsize
*2);
227 //Open Interprocess machinery in the new managed external buffer
228 wmanaged_external_buffer
user_buffer2(open_only
, &grow_copy
[0], memsize
);
230 //Expand old Interprocess machinery to the new size
231 user_buffer2
.grow(memsize
);
233 //Get a pointer to the full list
234 userlist
= user_buffer2
.find
<MyUserList
>(L
"MyHeapList").first
;
239 //Fill user buffer until is full
242 userlist
->insert(userlist
->end(), 0);
245 catch(boost::interprocess::bad_alloc
&){}
247 MyUserList::size_type user_list_size
= userlist
->size();
249 if(user_list_size
<= heap_list_size
){
253 user_buffer2
.destroy_ptr(userlist
);