offset_ptr_test.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2007-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/offset_ptr.hpp>
  12. #include <boost/interprocess/detail/type_traits.hpp>
  13. #include <boost/intrusive/pointer_traits.hpp>
  14. #include <boost/static_assert.hpp>
  15. #include <boost/core/lightweight_test.hpp>
  16. using namespace boost::interprocess;
  17. class Base
  18. {};
  19. class Derived
  20. : public Base
  21. {};
  22. class VirtualDerived
  23. : public virtual Base
  24. {};
  25. void test_types_and_conversions()
  26. {
  27. typedef offset_ptr<int> pint_t;
  28. typedef offset_ptr<const int> pcint_t;
  29. typedef offset_ptr<volatile int> pvint_t;
  30. typedef offset_ptr<const volatile int> pcvint_t;
  31. BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::element_type, int>::value));
  32. BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::element_type, const int>::value));
  33. BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::element_type, volatile int>::value));
  34. BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::element_type, const volatile int>::value));
  35. BOOST_STATIC_ASSERT((ipcdetail::is_same<pint_t::value_type, int>::value));
  36. BOOST_STATIC_ASSERT((ipcdetail::is_same<pcint_t::value_type, int>::value));
  37. BOOST_STATIC_ASSERT((ipcdetail::is_same<pvint_t::value_type, int>::value));
  38. BOOST_STATIC_ASSERT((ipcdetail::is_same<pcvint_t::value_type, int>::value));
  39. int dummy_int = 9;
  40. { pint_t pint(&dummy_int);
  41. pcint_t pcint(pint);
  42. BOOST_TEST(pcint.get() == &dummy_int);
  43. }
  44. { pint_t pint(&dummy_int);
  45. pvint_t pvint(pint);
  46. BOOST_TEST(pvint.get() == &dummy_int);
  47. }
  48. { pint_t pint(&dummy_int);
  49. pcvint_t pcvint(pint);
  50. BOOST_TEST(pcvint.get() == &dummy_int);
  51. }
  52. { pcint_t pcint(&dummy_int);
  53. pcvint_t pcvint(pcint);
  54. BOOST_TEST(pcvint.get() == &dummy_int);
  55. }
  56. { pvint_t pvint(&dummy_int);
  57. pcvint_t pcvint(pvint);
  58. BOOST_TEST(pcvint.get() == &dummy_int);
  59. }
  60. pint_t pint(0);
  61. pcint_t pcint(0);
  62. pvint_t pvint(0);
  63. pcvint_t pcvint(0);
  64. pint = &dummy_int;
  65. pcint = &dummy_int;
  66. pvint = &dummy_int;
  67. pcvint = &dummy_int;
  68. { pcint = pint;
  69. BOOST_TEST(pcint.get() == &dummy_int);
  70. }
  71. { pvint = pint;
  72. BOOST_TEST(pvint.get() == &dummy_int);
  73. }
  74. { pcvint = pint;
  75. BOOST_TEST(pcvint.get() == &dummy_int);
  76. }
  77. { pcvint = pcint;
  78. BOOST_TEST(pcvint.get() == &dummy_int);
  79. }
  80. { pcvint = pvint;
  81. BOOST_TEST(pcvint.get() == &dummy_int);
  82. }
  83. BOOST_TEST(pint);
  84. pint = 0;
  85. BOOST_TEST(!pint);
  86. BOOST_TEST(pint == 0);
  87. BOOST_TEST(0 == pint);
  88. pint = &dummy_int;
  89. BOOST_TEST(0 != pint);
  90. pcint = &dummy_int;
  91. BOOST_TEST( (pcint - pint) == 0);
  92. BOOST_TEST( (pint - pcint) == 0);
  93. }
  94. template<class BasePtr, class DerivedPtr>
  95. void test_base_derived_impl()
  96. {
  97. typename DerivedPtr::element_type d;
  98. DerivedPtr pderi(&d);
  99. BasePtr pbase(pderi);
  100. pbase = pderi;
  101. BOOST_TEST(pbase == pderi);
  102. BOOST_TEST(!(pbase != pderi));
  103. BOOST_TEST((pbase - pderi) == 0);
  104. BOOST_TEST(!(pbase < pderi));
  105. BOOST_TEST(!(pbase > pderi));
  106. BOOST_TEST(pbase <= pderi);
  107. BOOST_TEST((pbase >= pderi));
  108. }
  109. void test_base_derived()
  110. {
  111. typedef offset_ptr<Base> pbase_t;
  112. typedef offset_ptr<const Base> pcbas_t;
  113. typedef offset_ptr<Derived> pderi_t;
  114. typedef offset_ptr<VirtualDerived> pvder_t;
  115. test_base_derived_impl<pbase_t, pderi_t>();
  116. test_base_derived_impl<pbase_t, pvder_t>();
  117. test_base_derived_impl<pcbas_t, pderi_t>();
  118. test_base_derived_impl<pcbas_t, pvder_t>();
  119. }
  120. void test_arithmetic()
  121. {
  122. typedef offset_ptr<int> pint_t;
  123. const int NumValues = 5;
  124. int values[NumValues];
  125. //Initialize p
  126. pint_t p = values;
  127. BOOST_TEST(p.get() == values);
  128. //Initialize p + NumValues
  129. pint_t pe = &values[NumValues];
  130. BOOST_TEST(pe != p);
  131. BOOST_TEST(pe.get() == &values[NumValues]);
  132. //ptr - ptr
  133. BOOST_TEST((pe - p) == NumValues);
  134. //ptr - integer
  135. BOOST_TEST((pe - NumValues) == p);
  136. //ptr + integer
  137. BOOST_TEST((p + NumValues) == pe);
  138. //integer + ptr
  139. BOOST_TEST((NumValues + p) == pe);
  140. //indexing
  141. BOOST_TEST(pint_t(&p[NumValues]) == pe);
  142. BOOST_TEST(pint_t(&pe[-NumValues]) == p);
  143. //ptr -= integer
  144. pint_t p0 = pe;
  145. p0-= NumValues;
  146. BOOST_TEST(p == p0);
  147. //ptr += integer
  148. pint_t penew = p0;
  149. penew += NumValues;
  150. BOOST_TEST(penew == pe);
  151. //++ptr
  152. penew = p0;
  153. for(int j = 0; j != NumValues; ++j, ++penew);
  154. BOOST_TEST(penew == pe);
  155. //--ptr
  156. p0 = pe;
  157. for(int j = 0; j != NumValues; ++j, --p0);
  158. BOOST_TEST(p == p0);
  159. //ptr++
  160. penew = p0;
  161. for(int j = 0; j != NumValues; ++j){
  162. pint_t p_new_copy = penew;
  163. BOOST_TEST(p_new_copy == penew++);
  164. }
  165. //ptr--
  166. p0 = pe;
  167. for(int j = 0; j != NumValues; ++j){
  168. pint_t p0_copy = p0;
  169. BOOST_TEST(p0_copy == p0--);
  170. }
  171. }
  172. void test_comparison()
  173. {
  174. typedef offset_ptr<int> pint_t;
  175. const int NumValues = 5;
  176. int values[NumValues];
  177. //Initialize p
  178. pint_t p = values;
  179. BOOST_TEST(p.get() == values);
  180. //Initialize p + NumValues
  181. pint_t pe = &values[NumValues];
  182. BOOST_TEST(pe != p);
  183. BOOST_TEST(pe.get() == &values[NumValues]);
  184. //operators
  185. BOOST_TEST(p != pe);
  186. BOOST_TEST(p == p);
  187. BOOST_TEST((p < pe));
  188. BOOST_TEST((p <= pe));
  189. BOOST_TEST((pe > p));
  190. BOOST_TEST((pe >= p));
  191. }
  192. bool test_pointer_traits()
  193. {
  194. typedef offset_ptr<int> OInt;
  195. typedef boost::intrusive::pointer_traits< OInt > PTOInt;
  196. BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::element_type, int>::value));
  197. BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::pointer, OInt >::value));
  198. BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::difference_type, OInt::difference_type >::value));
  199. BOOST_STATIC_ASSERT((ipcdetail::is_same<PTOInt::rebind_pointer<double>::type, offset_ptr<double> >::value));
  200. int dummy;
  201. OInt oi(&dummy);
  202. if(boost::intrusive::pointer_traits<OInt>::pointer_to(dummy) != oi){
  203. return false;
  204. }
  205. return true;
  206. }
  207. struct node
  208. {
  209. offset_ptr<node> next;
  210. };
  211. void test_pointer_plus_bits()
  212. {
  213. BOOST_STATIC_ASSERT((boost::intrusive::max_pointer_plus_bits< offset_ptr<void>, boost::move_detail::alignment_of<node>::value >::value >= 1U));
  214. typedef boost::intrusive::pointer_plus_bits< offset_ptr<node>, 1u > ptr_plus_bits;
  215. node n, n2;
  216. offset_ptr<node> pnode(&n);
  217. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
  218. BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
  219. ptr_plus_bits::set_bits(pnode, 1u);
  220. BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
  221. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n);
  222. ptr_plus_bits::set_pointer(pnode, &n2);
  223. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
  224. BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
  225. ptr_plus_bits::set_bits(pnode, 0u);
  226. BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
  227. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == &n2);
  228. ptr_plus_bits::set_pointer(pnode, offset_ptr<node>());
  229. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) ==0);
  230. BOOST_TEST(0 == ptr_plus_bits::get_bits(pnode));
  231. ptr_plus_bits::set_bits(pnode, 1u);
  232. BOOST_TEST(1 == ptr_plus_bits::get_bits(pnode));
  233. BOOST_TEST(ptr_plus_bits::get_pointer(pnode) == 0);
  234. }
  235. int main()
  236. {
  237. test_types_and_conversions();
  238. test_base_derived();
  239. test_arithmetic();
  240. test_comparison();
  241. test_pointer_traits();
  242. test_pointer_plus_bits();
  243. return ::boost::report_errors();
  244. }
  245. #include <boost/interprocess/detail/config_end.hpp>
  246. /*
  247. //Offset ptr benchmark
  248. #include <vector>
  249. #include <iostream>
  250. #include <boost/interprocess/managed_shared_memory.hpp>
  251. #include <boost/interprocess/containers/vector.hpp>
  252. #include <boost/interprocess/allocators/allocator.hpp>
  253. #include <boost/timer.hpp>
  254. #include <cstddef>
  255. template<class InIt,
  256. class Ty> inline
  257. Ty accumulate2(InIt First, InIt Last, Ty Val)
  258. { // return sum of Val and all in [First, Last)
  259. for (; First != Last; ++First) //First = First + 1)
  260. Val = Val + *First;
  261. return (Val);
  262. }
  263. template <typename Vector>
  264. void time_test(const Vector& vec, std::size_t iterations, const char* label) {
  265. // assert(!vec.empty())
  266. boost::timer t;
  267. typename Vector::const_iterator first = vec.begin();
  268. typename Vector::value_type result(0);
  269. while (iterations != 0) {
  270. result = accumulate2(first, first + vec.size(), result);
  271. --iterations;
  272. }
  273. std::cout << label << t.elapsed() << " " << result << std::endl;
  274. }
  275. int main()
  276. {
  277. using namespace boost::interprocess;
  278. typedef allocator<double, managed_shared_memory::segment_manager> alloc_t;
  279. std::size_t n = 0x1 << 26;
  280. std::size_t file_size = n * sizeof(double) + 1000000;
  281. {
  282. shared_memory_object::remove("MyMappedFile");
  283. managed_shared_memory segment(open_or_create, "MyMappedFile", file_size);
  284. shared_memory_object::remove("MyMappedFile");
  285. alloc_t alloc_inst(segment.get_segment_manager());
  286. vector<double, alloc_t> v0(n, double(42.42), alloc_inst);
  287. time_test(v0, 10, "iterator shared: ");
  288. }
  289. {
  290. std::vector<double> v1(n, double(42.42));
  291. time_test(v1, 10, "iterator non-shared: ");
  292. }
  293. return 0;
  294. }
  295. */