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
29using namespace boost::interprocess;
30
31typedef test::dummy_test_allocator<char> DummyCharAllocator;
32typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString;
33typedef test::dummy_test_allocator<DummyString> DummyStringAllocator;
34typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
35typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
36typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
37
38struct 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
51template<class StrVector1, class StrVector2>
52bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
53{
54 StringEqual comp;
55 return std::equal(strvect1->begin(), strvect1->end(),
56 strvect2->begin(), comp);
57}
58
59template<class CharType, template<class T, class SegmentManager> class AllocatorType >
60int 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
262bool 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
272bool 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
310int 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

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