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 | |
31 | using namespace boost::interprocess; |
32 | |
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; |
39 | |
40 | //Alias list types |
41 | typedef list<int, user_node_allocator_t> MyUserList; |
42 | typedef list<int, heap_node_allocator_t> MyHeapList; |
43 | typedef std::list<int> MyStdList; |
44 | |
45 | //Function to check if both lists are equal |
46 | bool 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 | |
52 | int 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 | |