• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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