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 <boost/interprocess/managed_shared_memory.hpp> |
12 | #include <boost/interprocess/allocators/allocator.hpp> |
13 | #include <boost/interprocess/containers/vector.hpp> |
14 | #include <boost/interprocess/containers/string.hpp> |
15 | #include <boost/interprocess/offset_ptr.hpp> |
16 | #include <string> |
17 | #include <algorithm> |
18 | #include <cstring> |
19 | #include <cstdio> |
20 | #include <cstddef> |
21 | #include "dummy_test_allocator.hpp" |
22 | #include "check_equal_containers.hpp" |
23 | #include "expand_bwd_test_allocator.hpp" |
24 | #include "expand_bwd_test_template.hpp" |
25 | #include "allocator_v1.hpp" |
26 | #include "get_process_id_name.hpp" |
27 | #include <new> //std::nothrow |
28 | |
29 | using namespace boost::interprocess; |
30 | |
31 | typedef test::dummy_test_allocator<char> DummyCharAllocator; |
32 | typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString; |
33 | typedef test::dummy_test_allocator<DummyString> DummyStringAllocator; |
34 | typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator; |
35 | typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString; |
36 | typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator; |
37 | |
38 | struct StringEqual |
39 | { |
40 | template<class Str1, class Str2> |
41 | bool operator ()(const Str1 &string1, const Str2 &string2) const |
42 | { |
43 | if(string1.size() != string2.size()) |
44 | return false; |
45 | return std::char_traits<typename Str1::value_type>::compare |
46 | (string1.c_str(), string2.c_str(), (std::size_t)string1.size()) == 0; |
47 | } |
48 | }; |
49 | |
50 | //Function to check if both lists are equal |
51 | template<class StrVector1, class StrVector2> |
52 | bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) |
53 | { |
54 | StringEqual comp; |
55 | return std::equal(strvect1->begin(), strvect1->end(), |
56 | strvect2->begin(), comp); |
57 | } |
58 | |
59 | template<class CharType, template<class T, class SegmentManager> class AllocatorType > |
60 | int string_test() |
61 | { |
62 | typedef std::allocator<CharType> StdAllocatorChar; |
63 | typedef std::basic_string<CharType, std::char_traits<CharType>, StdAllocatorChar> StdString; |
64 | typedef std::allocator<StdString> StdStringAllocator; |
65 | typedef vector<StdString, StdStringAllocator> StdStringVector; |
66 | typedef AllocatorType<CharType, managed_shared_memory::segment_manager> ShmemAllocatorChar; |
67 | typedef basic_string<CharType, std::char_traits<CharType>, ShmemAllocatorChar> ShmString; |
68 | typedef AllocatorType<ShmString, managed_shared_memory::segment_manager> ShmemStringAllocator; |
69 | typedef vector<ShmString, ShmemStringAllocator> ShmStringVector; |
70 | |
71 | const int MaxSize = 100; |
72 | |
73 | std::string process_name; |
74 | test::get_process_id_name(str&: process_name); |
75 | |
76 | //Create shared memory |
77 | shared_memory_object::remove(filename: process_name.c_str()); |
78 | { |
79 | managed_shared_memory segment |
80 | (create_only, |
81 | process_name.c_str(),//segment name |
82 | 65536); //segment size in bytes |
83 | |
84 | ShmemAllocatorChar shmallocator (segment.get_segment_manager()); |
85 | |
86 | //Initialize vector with a range or iterators and allocator |
87 | ShmStringVector *shmStringVect = |
88 | segment.construct<ShmStringVector> |
89 | (anonymous_instance, std::nothrow) //object name |
90 | (shmallocator); |
91 | |
92 | StdStringVector *stdStringVect = new StdStringVector; |
93 | |
94 | ShmString auxShmString (segment.get_segment_manager()); |
95 | StdString auxStdString(StdString(auxShmString.begin(), auxShmString.end() )); |
96 | |
97 | CharType buffer [20]; |
98 | |
99 | //First, push back |
100 | for(std::size_t i = 0; i < MaxSize; ++i){ |
101 | auxShmString = "String" ; |
102 | auxStdString = "String" ; |
103 | std::sprintf(s: buffer, format: "%u" , (unsigned)i); |
104 | auxShmString += buffer; |
105 | auxStdString += buffer; |
106 | shmStringVect->push_back(auxShmString); |
107 | stdStringVect->push_back(auxStdString); |
108 | } |
109 | |
110 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
111 | return 1; |
112 | } |
113 | |
114 | //Now push back moving |
115 | for(std::size_t i = 0; i < MaxSize; ++i){ |
116 | auxShmString = "String" ; |
117 | auxStdString = "String" ; |
118 | std::sprintf(s: buffer, format: "%u" , (unsigned)i); |
119 | auxShmString += buffer; |
120 | auxStdString += buffer; |
121 | shmStringVect->push_back(boost::move(auxShmString)); |
122 | stdStringVect->push_back(auxStdString); |
123 | } |
124 | |
125 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
126 | return 1; |
127 | } |
128 | |
129 | //push front |
130 | for(std::size_t i = 0; i < MaxSize; ++i){ |
131 | auxShmString = "String" ; |
132 | auxStdString = "String" ; |
133 | std::sprintf(s: buffer, format: "%u" , (unsigned)i); |
134 | auxShmString += buffer; |
135 | auxStdString += buffer; |
136 | shmStringVect->insert(shmStringVect->begin(), auxShmString); |
137 | stdStringVect->insert(stdStringVect->begin(), auxStdString); |
138 | } |
139 | |
140 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
141 | return 1; |
142 | } |
143 | |
144 | //Now push front moving |
145 | for(std::size_t i = 0; i < MaxSize; ++i){ |
146 | auxShmString = "String" ; |
147 | auxStdString = "String" ; |
148 | std::sprintf(s: buffer, format: "%u" , (unsigned)i); |
149 | auxShmString += buffer; |
150 | auxStdString += buffer; |
151 | shmStringVect->insert(shmStringVect->begin(), boost::move(auxShmString)); |
152 | stdStringVect->insert(stdStringVect->begin(), auxStdString); |
153 | } |
154 | |
155 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)){ |
156 | return 1; |
157 | } |
158 | |
159 | //Now test long and short representation swapping |
160 | auxShmString = "String" ; |
161 | auxStdString = "String" ; |
162 | ShmString shm_swapper(segment.get_segment_manager()); |
163 | StdString std_swapper; |
164 | shm_swapper.swap(auxShmString); |
165 | std_swapper.swap(auxStdString); |
166 | if(!StringEqual()(auxShmString, auxStdString)) |
167 | return 1; |
168 | if(!StringEqual()(shm_swapper, std_swapper)) |
169 | return 1; |
170 | |
171 | shm_swapper.swap(auxShmString); |
172 | std_swapper.swap(auxStdString); |
173 | if(!StringEqual()(auxShmString, auxStdString)) |
174 | return 1; |
175 | if(!StringEqual()(shm_swapper, std_swapper)) |
176 | return 1; |
177 | |
178 | auxShmString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString" ; |
179 | auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString" ; |
180 | shm_swapper = ShmString (segment.get_segment_manager()); |
181 | std_swapper = StdString (); |
182 | shm_swapper.swap(auxShmString); |
183 | std_swapper.swap(auxStdString); |
184 | if(!StringEqual()(auxShmString, auxStdString)) |
185 | return 1; |
186 | if(!StringEqual()(shm_swapper, std_swapper)) |
187 | return 1; |
188 | |
189 | shm_swapper.swap(auxShmString); |
190 | std_swapper.swap(auxStdString); |
191 | if(!StringEqual()(auxShmString, auxStdString)) |
192 | return 1; |
193 | if(!StringEqual()(shm_swapper, std_swapper)) |
194 | return 1; |
195 | |
196 | //No sort |
197 | std::sort(shmStringVect->begin(), shmStringVect->end()); |
198 | std::sort(stdStringVect->begin(), stdStringVect->end()); |
199 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
200 | |
201 | const CharType prefix [] = "Prefix" ; |
202 | const std::size_t prefix_size = sizeof(prefix)/sizeof(prefix[0])-1; |
203 | const CharType sufix [] = "Suffix" ; |
204 | |
205 | for(std::size_t i = 0; i < MaxSize; ++i){ |
206 | (*shmStringVect)[i].append(sufix); |
207 | (*stdStringVect)[i].append(sufix); |
208 | (*shmStringVect)[i].insert((*shmStringVect)[i].begin(), |
209 | prefix, prefix + prefix_size); |
210 | (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), |
211 | prefix, prefix + prefix_size); |
212 | } |
213 | |
214 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
215 | |
216 | for(std::size_t i = 0; i < MaxSize; ++i){ |
217 | std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); |
218 | std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); |
219 | } |
220 | |
221 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
222 | |
223 | for(std::size_t i = 0; i < MaxSize; ++i){ |
224 | std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end()); |
225 | std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); |
226 | } |
227 | |
228 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
229 | |
230 | for(std::size_t i = 0; i < MaxSize; ++i){ |
231 | std::sort(shmStringVect->begin(), shmStringVect->end()); |
232 | std::sort(stdStringVect->begin(), stdStringVect->end()); |
233 | } |
234 | |
235 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
236 | |
237 | for(std::size_t i = 0; i < MaxSize; ++i){ |
238 | (*shmStringVect)[i].replace((*shmStringVect)[i].begin(), |
239 | (*shmStringVect)[i].end(), |
240 | "String" ); |
241 | (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), |
242 | (*stdStringVect)[i].end(), |
243 | "String" ); |
244 | } |
245 | |
246 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
247 | |
248 | shmStringVect->erase(std::unique(shmStringVect->begin(), shmStringVect->end()), |
249 | shmStringVect->end()); |
250 | stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()), |
251 | stdStringVect->end()); |
252 | if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1; |
253 | |
254 | //When done, delete vector |
255 | segment.destroy_ptr(shmStringVect); |
256 | delete stdStringVect; |
257 | } |
258 | shared_memory_object::remove(filename: process_name.c_str()); |
259 | return 0; |
260 | } |
261 | |
262 | bool test_expand_bwd() |
263 | { |
264 | //Now test all back insertion possibilities |
265 | typedef test::expand_bwd_test_allocator<char> |
266 | allocator_type; |
267 | typedef basic_string<char, std::char_traits<char>, allocator_type> |
268 | string_type; |
269 | return test::test_all_expand_bwd<string_type>(); |
270 | } |
271 | |
272 | bool vector_of_strings_test() |
273 | { |
274 | using namespace boost::interprocess; |
275 | typedef allocator<char, managed_shared_memory::segment_manager> ShmCharAllocator; |
276 | typedef allocator<int, managed_shared_memory::segment_manager> ShmIntAllocator; |
277 | typedef basic_string<char, std::char_traits<char>, ShmCharAllocator > ShmString; |
278 | typedef allocator<ShmString, managed_shared_memory::segment_manager> ShmStringAllocator; |
279 | |
280 | const char *memoryName = "test_memory" ; |
281 | shared_memory_object::remove(filename: memoryName); |
282 | managed_shared_memory shm(create_only, memoryName, 1024 * 1024); |
283 | shared_memory_object::remove(filename: memoryName); |
284 | |
285 | ShmStringAllocator stringAllocator(shm.get_segment_manager()); |
286 | ShmIntAllocator intAllocator(shm.get_segment_manager()); |
287 | |
288 | vector<ShmString, ShmStringAllocator> vectorOfStrings(stringAllocator); |
289 | vector <int, ShmIntAllocator> vectorOfInts(intAllocator); |
290 | |
291 | { |
292 | ShmString z("aaaaaaaa" , stringAllocator); |
293 | vectorOfStrings.push_back(x: z); |
294 | vectorOfInts.push_back(x: 7); |
295 | } |
296 | { |
297 | ShmString z("ccccccccccccccccccccccc" , stringAllocator); |
298 | vectorOfStrings.push_back(x: z); |
299 | } |
300 | { |
301 | ShmString z("bbbb" , stringAllocator); |
302 | vectorOfStrings.push_back(x: z); |
303 | } |
304 | |
305 | return std::strcmp(s1: vectorOfStrings.at(n: 0).c_str(), s2: "aaaaaaaa" ) == 0 |
306 | && std::strcmp(s1: vectorOfStrings.at(n: 1).c_str(), s2: "ccccccccccccccccccccccc" ) == 0 |
307 | && std::strcmp(s1: vectorOfStrings.at(n: 2).c_str(), s2: "bbbb" ) == 0; |
308 | } |
309 | |
310 | int main() |
311 | { |
312 | if(string_test<char, allocator>()){ |
313 | return 1; |
314 | } |
315 | |
316 | if(string_test<char, test::allocator_v1>()){ |
317 | return 1; |
318 | } |
319 | |
320 | if(!test_expand_bwd()) |
321 | return 1; |
322 | |
323 | if(!vector_of_strings_test()) |
324 | return 1; |
325 | |
326 | return 0; |
327 | } |
328 | |
329 | |