1//////////////////////////////////////////////////////////////////////////////
2//
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)
6//
7// See http://www.boost.org/libs/interprocess for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#include <algorithm>
12#include <vector>
13#include <list>
14#include <iostream>
15#include <functional>
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"
23
24/******************************************************************************/
25/* */
26/* This example constructs repeats the same operations with std::list, */
27/* shmem_list in user provided buffer, and shmem_list in heap memory */
28/* */
29/******************************************************************************/
30
31using namespace boost::interprocess;
32
33//We will work with wide characters for user memory objects
34//Alias <integer> node allocator type
35typedef node_allocator
36 <int, wmanaged_external_buffer::segment_manager> user_node_allocator_t;
37typedef node_allocator
38 <int, wmanaged_heap_memory::segment_manager> heap_node_allocator_t;
39
40//Alias list types
41typedef list<int, user_node_allocator_t> MyUserList;
42typedef list<int, heap_node_allocator_t> MyHeapList;
43typedef std::list<int> MyStdList;
44
45//Function to check if both lists are equal
46bool CheckEqual(MyUserList *userlist, MyStdList *stdlist, MyHeapList *heaplist)
47{
48 return std::equal(first1: userlist->begin(), last1: userlist->end(), first2: stdlist->begin()) &&
49 std::equal(first1: heaplist->begin(), last1: heaplist->end(), first2: stdlist->begin());
50}
51
52int main ()
53{
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];
58
59 {
60 //Now test move semantics
61 managed_heap_memory original(memsize);
62 managed_heap_memory move_ctor(boost::move(t&: original));
63 managed_heap_memory move_assign;
64 move_assign = boost::move(t&: move_ctor);
65 original.swap(other&: move_assign);
66 }
67 {
68 //Now test move semantics
69 managed_external_buffer original(create_only, static_buffer, memsize);
70 managed_external_buffer move_ctor(boost::move(t&: original));
71 managed_external_buffer move_assign;
72 move_assign = boost::move(t&: move_ctor);
73 original.swap(other&: move_assign);
74 }
75
76 //Named new capable user mem allocator
77 wmanaged_external_buffer user_buffer(create_only, static_buffer, memsize);
78
79 //Named new capable heap mem allocator
80 wmanaged_heap_memory heap_buffer(memsize);
81
82 //Test move semantics
83 {
84 wmanaged_external_buffer user_default;
85 wmanaged_external_buffer temp_external(boost::move(t&: user_buffer));
86 user_default = boost::move(t&: temp_external);
87 user_buffer = boost::move(t&: user_default);
88 wmanaged_heap_memory heap_default;
89 wmanaged_heap_memory temp_heap(boost::move(t&: heap_buffer));
90 heap_default = boost::move(t&: temp_heap);
91 heap_buffer = boost::move(t&: heap_default);
92 }
93
94 //Initialize memory
95 user_buffer.reserve_named_objects(num: 100);
96 heap_buffer.reserve_named_objects(num: 100);
97
98 //User memory allocator must be always be initialized
99 //since it has no default constructor
100 MyUserList *userlist = user_buffer.construct<MyUserList>(name: L"MyUserList")
101 (user_buffer.get_segment_manager());
102
103 MyHeapList *heaplist = heap_buffer.construct<MyHeapList>(name: L"MyHeapList")
104 (heap_buffer.get_segment_manager());
105
106 //Alias heap list
107 MyStdList *stdlist = new MyStdList;
108
109 int i;
110 const int max = 100;
111 for(i = 0; i < max; ++i){
112 userlist->push_back(x: i);
113 heaplist->push_back(x: i);
114 stdlist->push_back(x: i);
115 }
116 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
117
118 userlist->erase(p: userlist->begin()++);
119 heaplist->erase(p: heaplist->begin()++);
120 stdlist->erase(position: stdlist->begin()++);
121 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
122
123 userlist->pop_back();
124 heaplist->pop_back();
125 stdlist->pop_back();
126 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
127
128 userlist->pop_front();
129 heaplist->pop_front();
130 stdlist->pop_front();
131 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
132
133 std::vector<int> aux_vect;
134 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
135 aux_vect.assign(n: 50, val: -1);
136 userlist->assign(first: aux_vect.begin(), last: aux_vect.end());
137 heaplist->assign(first: aux_vect.begin(), last: aux_vect.end());
138 stdlist->assign(first: aux_vect.begin(), last: aux_vect.end());
139 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
140 #endif
141
142 userlist->sort();
143 heaplist->sort();
144 stdlist->sort();
145 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
146
147 #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
148 aux_vect.assign(n: 50, val: 0);
149 #endif
150 userlist->insert(position: userlist->begin(), first: aux_vect.begin(), last: aux_vect.end());
151 heaplist->insert(position: heaplist->begin(), first: aux_vect.begin(), last: aux_vect.end());
152 stdlist->insert(position: stdlist->begin(), first: aux_vect.begin(), last: aux_vect.end());
153
154 userlist->unique();
155 heaplist->unique();
156 stdlist->unique();
157 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
158
159 userlist->sort(comp: std::greater<int>());
160 heaplist->sort(comp: std::greater<int>());
161 stdlist->sort(comp: std::greater<int>());
162 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
163
164 userlist->resize(new_size: userlist->size()/2);
165 heaplist->resize(new_size: heaplist->size()/2);
166 stdlist->resize(new_size: stdlist->size()/2);
167 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
168
169 userlist->remove(value: *userlist->begin());
170 heaplist->remove(value: *heaplist->begin());
171 stdlist->remove(value: *stdlist->begin());
172 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
173
174 for(i = 0; i < max; ++i){
175 userlist->push_back(x: i);
176 heaplist->push_back(x: i);
177 stdlist->push_back(x: i);
178 }
179
180 MyUserList otheruserlist(*userlist);
181 MyHeapList otherheaplist(*heaplist);
182 MyStdList otherstdlist(*stdlist);
183 userlist->splice(p: userlist->begin(), x&: otheruserlist);
184 heaplist->splice(p: heaplist->begin(), x&: otherheaplist);
185 stdlist->splice(position: stdlist->begin(), x&: otherstdlist);
186 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
187
188 otheruserlist = *userlist;
189 otherheaplist = *heaplist;
190 otherstdlist = *stdlist;
191
192 userlist->sort(comp: std::greater<int>());
193 heaplist->sort(comp: std::greater<int>());
194 stdlist->sort(comp: std::greater<int>());
195 otheruserlist.sort(comp: std::greater<int>());
196 otherheaplist.sort(comp: std::greater<int>());
197 otherstdlist.sort(comp: std::greater<int>());
198 userlist->merge(x&: otheruserlist, comp: std::greater<int>());
199 heaplist->merge(x&: otherheaplist, comp: std::greater<int>());
200 stdlist->merge(x&: otherstdlist, comp: std::greater<int>());
201 if(!CheckEqual(userlist, stdlist, heaplist)) return 1;
202
203 user_buffer.destroy<MyUserList>(name: L"MyUserList");
204 delete stdlist;
205
206 //Fill heap buffer until is full
207 BOOST_TRY{
208 while(1){
209 heaplist->insert(arg1: heaplist->end(), x: 0);
210 }
211 }
212 BOOST_CATCH(boost::interprocess::bad_alloc &){} BOOST_CATCH_END
213
214 MyHeapList::size_type heap_list_size = heaplist->size();
215
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);
220
221 //Destroy old list
222 heap_buffer.destroy<MyHeapList>(name: L"MyHeapList");
223
224 //Resize copy buffer
225 grow_copy.resize(new_size: memsize*2);
226
227 //Open Interprocess machinery in the new managed external buffer
228 wmanaged_external_buffer user_buffer2(open_only, &grow_copy[0], memsize);
229
230 //Expand old Interprocess machinery to the new size
231 user_buffer2.grow(extra_bytes: memsize);
232
233 //Get a pointer to the full list
234 userlist = user_buffer2.find<MyUserList>(name: L"MyHeapList").first;
235 if(!userlist){
236 return 1;
237 }
238
239 //Fill user buffer until is full
240 BOOST_TRY{
241 while(1){
242 userlist->insert(arg1: userlist->end(), x: 0);
243 }
244 }
245 BOOST_CATCH(boost::interprocess::bad_alloc &){} BOOST_CATCH_END
246
247 MyUserList::size_type user_list_size = userlist->size();
248
249 if(user_list_size <= heap_list_size){
250 return 1;
251 }
252
253 user_buffer2.destroy_ptr(ptr: userlist);
254
255 return 0;
256}
257

source code of boost/libs/interprocess/test/user_buffer_test.cpp