string_test.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  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. #include <boost/interprocess/detail/config_begin.hpp>
  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. using namespace boost::interprocess;
  29. typedef test::dummy_test_allocator<char> DummyCharAllocator;
  30. typedef basic_string<char, std::char_traits<char>, DummyCharAllocator> DummyString;
  31. typedef test::dummy_test_allocator<DummyString> DummyStringAllocator;
  32. typedef test::dummy_test_allocator<wchar_t> DummyWCharAllocator;
  33. typedef basic_string<wchar_t, std::char_traits<wchar_t>, DummyWCharAllocator> DummyWString;
  34. typedef test::dummy_test_allocator<DummyWString> DummyWStringAllocator;
  35. struct StringEqual
  36. {
  37. template<class Str1, class Str2>
  38. bool operator ()(const Str1 &string1, const Str2 &string2) const
  39. {
  40. if(string1.size() != string2.size())
  41. return false;
  42. return std::char_traits<typename Str1::value_type>::compare
  43. (string1.c_str(), string2.c_str(), (std::size_t)string1.size()) == 0;
  44. }
  45. };
  46. //Function to check if both lists are equal
  47. template<class StrVector1, class StrVector2>
  48. bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2)
  49. {
  50. StringEqual comp;
  51. return std::equal(strvect1->begin(), strvect1->end(),
  52. strvect2->begin(), comp);
  53. }
  54. template<class CharType, template<class T, class SegmentManager> class AllocatorType >
  55. int string_test()
  56. {
  57. typedef std::allocator<CharType> StdAllocatorChar;
  58. typedef std::basic_string<CharType, std::char_traits<CharType>, StdAllocatorChar> StdString;
  59. typedef std::allocator<StdString> StdStringAllocator;
  60. typedef vector<StdString, StdStringAllocator> StdStringVector;
  61. typedef AllocatorType<CharType, managed_shared_memory::segment_manager> ShmemAllocatorChar;
  62. typedef basic_string<CharType, std::char_traits<CharType>, ShmemAllocatorChar> ShmString;
  63. typedef AllocatorType<ShmString, managed_shared_memory::segment_manager> ShmemStringAllocator;
  64. typedef vector<ShmString, ShmemStringAllocator> ShmStringVector;
  65. const int MaxSize = 100;
  66. std::string process_name;
  67. test::get_process_id_name(process_name);
  68. //Create shared memory
  69. shared_memory_object::remove(process_name.c_str());
  70. {
  71. managed_shared_memory segment
  72. (create_only,
  73. process_name.c_str(),//segment name
  74. 65536); //segment size in bytes
  75. ShmemAllocatorChar shmallocator (segment.get_segment_manager());
  76. //Initialize vector with a range or iterators and allocator
  77. ShmStringVector *shmStringVect =
  78. segment.construct<ShmStringVector>
  79. (anonymous_instance, std::nothrow) //object name
  80. (shmallocator);
  81. StdStringVector *stdStringVect = new StdStringVector;
  82. ShmString auxShmString (segment.get_segment_manager());
  83. StdString auxStdString(StdString(auxShmString.begin(), auxShmString.end() ));
  84. CharType buffer [20];
  85. //First, push back
  86. for(int i = 0; i < MaxSize; ++i){
  87. auxShmString = "String";
  88. auxStdString = "String";
  89. std::sprintf(buffer, "%i", i);
  90. auxShmString += buffer;
  91. auxStdString += buffer;
  92. shmStringVect->push_back(auxShmString);
  93. stdStringVect->push_back(auxStdString);
  94. }
  95. if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
  96. return 1;
  97. }
  98. //Now push back moving
  99. for(int i = 0; i < MaxSize; ++i){
  100. auxShmString = "String";
  101. auxStdString = "String";
  102. std::sprintf(buffer, "%i", i);
  103. auxShmString += buffer;
  104. auxStdString += buffer;
  105. shmStringVect->push_back(boost::move(auxShmString));
  106. stdStringVect->push_back(auxStdString);
  107. }
  108. if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
  109. return 1;
  110. }
  111. //push front
  112. for(int i = 0; i < MaxSize; ++i){
  113. auxShmString = "String";
  114. auxStdString = "String";
  115. std::sprintf(buffer, "%i", i);
  116. auxShmString += buffer;
  117. auxStdString += buffer;
  118. shmStringVect->insert(shmStringVect->begin(), auxShmString);
  119. stdStringVect->insert(stdStringVect->begin(), auxStdString);
  120. }
  121. if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
  122. return 1;
  123. }
  124. //Now push front moving
  125. for(int i = 0; i < MaxSize; ++i){
  126. auxShmString = "String";
  127. auxStdString = "String";
  128. std::sprintf(buffer, "%i", i);
  129. auxShmString += buffer;
  130. auxStdString += buffer;
  131. shmStringVect->insert(shmStringVect->begin(), boost::move(auxShmString));
  132. stdStringVect->insert(stdStringVect->begin(), auxStdString);
  133. }
  134. if(!CheckEqualStringVector(shmStringVect, stdStringVect)){
  135. return 1;
  136. }
  137. //Now test long and short representation swapping
  138. auxShmString = "String";
  139. auxStdString = "String";
  140. ShmString shm_swapper(segment.get_segment_manager());
  141. StdString std_swapper;
  142. shm_swapper.swap(auxShmString);
  143. std_swapper.swap(auxStdString);
  144. if(!StringEqual()(auxShmString, auxStdString))
  145. return 1;
  146. if(!StringEqual()(shm_swapper, std_swapper))
  147. return 1;
  148. shm_swapper.swap(auxShmString);
  149. std_swapper.swap(auxStdString);
  150. if(!StringEqual()(auxShmString, auxStdString))
  151. return 1;
  152. if(!StringEqual()(shm_swapper, std_swapper))
  153. return 1;
  154. auxShmString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
  155. auxStdString = "LongLongLongLongLongLongLongLongLongLongLongLongLongString";
  156. shm_swapper = ShmString (segment.get_segment_manager());
  157. std_swapper = StdString ();
  158. shm_swapper.swap(auxShmString);
  159. std_swapper.swap(auxStdString);
  160. if(!StringEqual()(auxShmString, auxStdString))
  161. return 1;
  162. if(!StringEqual()(shm_swapper, std_swapper))
  163. return 1;
  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. //No sort
  171. std::sort(shmStringVect->begin(), shmStringVect->end());
  172. std::sort(stdStringVect->begin(), stdStringVect->end());
  173. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  174. const CharType prefix [] = "Prefix";
  175. const int prefix_size = sizeof(prefix)/sizeof(prefix[0])-1;
  176. const CharType sufix [] = "Suffix";
  177. for(int i = 0; i < MaxSize; ++i){
  178. (*shmStringVect)[i].append(sufix);
  179. (*stdStringVect)[i].append(sufix);
  180. (*shmStringVect)[i].insert((*shmStringVect)[i].begin(),
  181. prefix, prefix + prefix_size);
  182. (*stdStringVect)[i].insert((*stdStringVect)[i].begin(),
  183. prefix, prefix + prefix_size);
  184. }
  185. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  186. for(int i = 0; i < MaxSize; ++i){
  187. std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end());
  188. std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
  189. }
  190. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  191. for(int i = 0; i < MaxSize; ++i){
  192. std::reverse((*shmStringVect)[i].begin(), (*shmStringVect)[i].end());
  193. std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end());
  194. }
  195. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  196. for(int i = 0; i < MaxSize; ++i){
  197. std::sort(shmStringVect->begin(), shmStringVect->end());
  198. std::sort(stdStringVect->begin(), stdStringVect->end());
  199. }
  200. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  201. for(int i = 0; i < MaxSize; ++i){
  202. (*shmStringVect)[i].replace((*shmStringVect)[i].begin(),
  203. (*shmStringVect)[i].end(),
  204. "String");
  205. (*stdStringVect)[i].replace((*stdStringVect)[i].begin(),
  206. (*stdStringVect)[i].end(),
  207. "String");
  208. }
  209. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  210. shmStringVect->erase(std::unique(shmStringVect->begin(), shmStringVect->end()),
  211. shmStringVect->end());
  212. stdStringVect->erase(std::unique(stdStringVect->begin(), stdStringVect->end()),
  213. stdStringVect->end());
  214. if(!CheckEqualStringVector(shmStringVect, stdStringVect)) return 1;
  215. //When done, delete vector
  216. segment.destroy_ptr(shmStringVect);
  217. delete stdStringVect;
  218. }
  219. shared_memory_object::remove(process_name.c_str());
  220. return 0;
  221. }
  222. bool test_expand_bwd()
  223. {
  224. //Now test all back insertion possibilities
  225. typedef test::expand_bwd_test_allocator<char>
  226. allocator_type;
  227. typedef basic_string<char, std::char_traits<char>, allocator_type>
  228. string_type;
  229. return test::test_all_expand_bwd<string_type>();
  230. }
  231. int main()
  232. {
  233. if(string_test<char, allocator>()){
  234. return 1;
  235. }
  236. if(string_test<char, test::allocator_v1>()){
  237. return 1;
  238. }
  239. if(!test_expand_bwd())
  240. return 1;
  241. return 0;
  242. }
  243. #include <boost/interprocess/detail/config_end.hpp>