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 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/interprocess/detail/config_begin.hpp>
17 #include <boost/interprocess/managed_external_buffer.hpp>
18 #include <boost/interprocess/managed_heap_memory.hpp>
19 #include <boost/interprocess/containers/list.hpp>
20 #include <boost/interprocess/detail/type_traits.hpp>
21 #include <boost/move/detail/type_traits.hpp>
22 #include <boost/interprocess/allocators/node_allocator.hpp>
23 #include "print_container.hpp"
25 /******************************************************************************/
27 /* This example constructs repeats the same operations with std::list, */
28 /* shmem_list in user provided buffer, and shmem_list in heap memory */
30 /******************************************************************************/
32 using namespace boost::interprocess
;
34 //We will work with wide characters for user memory objects
35 //Alias <integer> node allocator type
36 typedef node_allocator
37 <int, wmanaged_external_buffer::segment_manager
> user_node_allocator_t
;
38 typedef node_allocator
39 <int, wmanaged_heap_memory::segment_manager
> heap_node_allocator_t
;
42 typedef list
<int, user_node_allocator_t
> MyUserList
;
43 typedef list
<int, heap_node_allocator_t
> MyHeapList
;
44 typedef std::list
<int> MyStdList
;
46 //Function to check if both lists are equal
47 bool CheckEqual(MyUserList
*userlist
, MyStdList
*stdlist
, MyHeapList
*heaplist
)
49 return std::equal(userlist
->begin(), userlist
->end(), stdlist
->begin()) &&
50 std::equal(heaplist
->begin(), heaplist
->end(), stdlist
->begin());
55 //Create the user memory who will store all objects
56 const int size_aligner
= sizeof(::boost::container::container_detail::max_align_t
);
57 const int memsize
= 65536/size_aligner
*size_aligner
;
58 static ::boost::container::container_detail::max_align_t static_buffer
[memsize
/size_aligner
];
61 //Now test move semantics
62 managed_heap_memory
original(memsize
);
63 managed_heap_memory
move_ctor(boost::move(original
));
64 managed_heap_memory move_assign
;
65 move_assign
= boost::move(move_ctor
);
66 original
.swap(move_assign
);
69 //Now test move semantics
70 managed_external_buffer
original(create_only
, static_buffer
, memsize
);
71 managed_external_buffer
move_ctor(boost::move(original
));
72 managed_external_buffer move_assign
;
73 move_assign
= boost::move(move_ctor
);
74 original
.swap(move_assign
);
77 //Named new capable user mem allocator
78 wmanaged_external_buffer
user_buffer(create_only
, static_buffer
, memsize
);
80 //Named new capable heap mem allocator
81 wmanaged_heap_memory
heap_buffer(memsize
);
85 wmanaged_external_buffer user_default
;
86 wmanaged_external_buffer
temp_external(boost::move(user_buffer
));
87 user_default
= boost::move(temp_external
);
88 user_buffer
= boost::move(user_default
);
89 wmanaged_heap_memory heap_default
;
90 wmanaged_heap_memory
temp_heap(boost::move(heap_buffer
));
91 heap_default
= boost::move(temp_heap
);
92 heap_buffer
= boost::move(heap_default
);
96 user_buffer
.reserve_named_objects(100);
97 heap_buffer
.reserve_named_objects(100);
99 //User memory allocator must be always be initialized
100 //since it has no default constructor
101 MyUserList
*userlist
= user_buffer
.construct
<MyUserList
>(L
"MyUserList")
102 (user_buffer
.get_segment_manager());
104 MyHeapList
*heaplist
= heap_buffer
.construct
<MyHeapList
>(L
"MyHeapList")
105 (heap_buffer
.get_segment_manager());
108 MyStdList
*stdlist
= new MyStdList
;
112 for(i
= 0; i
< max
; ++i
){
113 userlist
->push_back(i
);
114 heaplist
->push_back(i
);
115 stdlist
->push_back(i
);
117 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
119 userlist
->erase(userlist
->begin()++);
120 heaplist
->erase(heaplist
->begin()++);
121 stdlist
->erase(stdlist
->begin()++);
122 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
124 userlist
->pop_back();
125 heaplist
->pop_back();
127 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
129 userlist
->pop_front();
130 heaplist
->pop_front();
131 stdlist
->pop_front();
132 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
134 std::vector
<int> aux_vect
;
135 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
136 aux_vect
.assign(50, -1);
137 userlist
->assign(aux_vect
.begin(), aux_vect
.end());
138 heaplist
->assign(aux_vect
.begin(), aux_vect
.end());
139 stdlist
->assign(aux_vect
.begin(), aux_vect
.end());
140 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
146 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
148 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
149 aux_vect
.assign(50, 0);
151 userlist
->insert(userlist
->begin(), aux_vect
.begin(), aux_vect
.end());
152 heaplist
->insert(heaplist
->begin(), aux_vect
.begin(), aux_vect
.end());
153 stdlist
->insert(stdlist
->begin(), aux_vect
.begin(), aux_vect
.end());
158 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
160 userlist
->sort(std::greater
<int>());
161 heaplist
->sort(std::greater
<int>());
162 stdlist
->sort(std::greater
<int>());
163 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
165 userlist
->resize(userlist
->size()/2);
166 heaplist
->resize(heaplist
->size()/2);
167 stdlist
->resize(stdlist
->size()/2);
168 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
170 userlist
->remove(*userlist
->begin());
171 heaplist
->remove(*heaplist
->begin());
172 stdlist
->remove(*stdlist
->begin());
173 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
175 for(i
= 0; i
< max
; ++i
){
176 userlist
->push_back(i
);
177 heaplist
->push_back(i
);
178 stdlist
->push_back(i
);
181 MyUserList
otheruserlist(*userlist
);
182 MyHeapList
otherheaplist(*heaplist
);
183 MyStdList
otherstdlist(*stdlist
);
184 userlist
->splice(userlist
->begin(), otheruserlist
);
185 heaplist
->splice(heaplist
->begin(), otherheaplist
);
186 stdlist
->splice(stdlist
->begin(), otherstdlist
);
187 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
189 otheruserlist
= *userlist
;
190 otherheaplist
= *heaplist
;
191 otherstdlist
= *stdlist
;
193 userlist
->sort(std::greater
<int>());
194 heaplist
->sort(std::greater
<int>());
195 stdlist
->sort(std::greater
<int>());
196 otheruserlist
.sort(std::greater
<int>());
197 otherheaplist
.sort(std::greater
<int>());
198 otherstdlist
.sort(std::greater
<int>());
199 userlist
->merge(otheruserlist
, std::greater
<int>());
200 heaplist
->merge(otherheaplist
, std::greater
<int>());
201 stdlist
->merge(otherstdlist
, std::greater
<int>());
202 if(!CheckEqual(userlist
, stdlist
, heaplist
)) return 1;
204 user_buffer
.destroy
<MyUserList
>(L
"MyUserList");
207 //Fill heap buffer until is full
210 heaplist
->insert(heaplist
->end(), 0);
213 catch(boost::interprocess::bad_alloc
&){}
215 MyHeapList::size_type heap_list_size
= heaplist
->size();
217 //Copy heap buffer to another
218 const char *insert_beg
= static_cast<char*>(heap_buffer
.get_address());
219 const char *insert_end
= insert_beg
+ heap_buffer
.get_size();
220 std::vector
<char> grow_copy (insert_beg
, insert_end
);
223 heap_buffer
.destroy
<MyHeapList
>(L
"MyHeapList");
226 grow_copy
.resize(memsize
*2);
228 //Open Interprocess machinery in the new managed external buffer
229 wmanaged_external_buffer
user_buffer2(open_only
, &grow_copy
[0], memsize
);
231 //Expand old Interprocess machinery to the new size
232 user_buffer2
.grow(memsize
);
234 //Get a pointer to the full list
235 userlist
= user_buffer2
.find
<MyUserList
>(L
"MyHeapList").first
;
240 //Fill user buffer until is full
243 userlist
->insert(userlist
->end(), 0);
246 catch(boost::interprocess::bad_alloc
&){}
248 MyUserList::size_type user_list_size
= userlist
->size();
250 if(user_list_size
<= heap_list_size
){
254 user_buffer2
.destroy_ptr(userlist
);
259 #include <boost/interprocess/detail/config_end.hpp>