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>
operator ()StringEqual41 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>
CheckEqualStringVector(StrVector1 * strvect1,StrVector2 * strvect2)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 >
string_test()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(process_name);
75
76 //Create shared memory
77 shared_memory_object::remove(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(int i = 0; i < MaxSize; ++i){
101 auxShmString = "String";
102 auxStdString = "String";
103 std::sprintf(buffer, "%i", 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(int i = 0; i < MaxSize; ++i){
116 auxShmString = "String";
117 auxStdString = "String";
118 std::sprintf(buffer, "%i", 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(int i = 0; i < MaxSize; ++i){
131 auxShmString = "String";
132 auxStdString = "String";
133 std::sprintf(buffer, "%i", 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(int i = 0; i < MaxSize; ++i){
146 auxShmString = "String";
147 auxStdString = "String";
148 std::sprintf(buffer, "%i", 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 int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
203 const CharType sufix [] = "Suffix";
204
205 for(int 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(int 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(int 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(int 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(int 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(process_name.c_str());
259 return 0;
260 }
261
test_expand_bwd()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
main()272 int main()
273 {
274 if(string_test<char, allocator>()){
275 return 1;
276 }
277
278 if(string_test<char, test::allocator_v1>()){
279 return 1;
280 }
281
282 if(!test_expand_bwd())
283 return 1;
284
285 return 0;
286 }
287
288