resource_adaptor_test.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2015-2015. 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/container for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. #include <boost/container/pmr/resource_adaptor.hpp>
  11. #include <boost/core/lightweight_test.hpp>
  12. #include "propagation_test_allocator.hpp"
  13. #include "derived_from_memory_resource.hpp"
  14. #include <boost/container/new_allocator.hpp>
  15. #include <memory>
  16. using namespace boost::container::pmr;
  17. static const std::size_t max_alignment_value = boost::move_detail::alignment_of<boost::move_detail::max_align_t>::value;
  18. void test_default_constructor()
  19. {
  20. typedef propagation_test_allocator<char, 0> alloc_t;
  21. resource_adaptor<alloc_t> ra;
  22. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  23. }
  24. void test_copy_constructor()
  25. {
  26. typedef propagation_test_allocator<char, 0> alloc_t;
  27. resource_adaptor<alloc_t> ra;
  28. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  29. resource_adaptor<alloc_t> rb(ra);
  30. BOOST_TEST(rb.get_allocator().m_default_contructed == false);
  31. BOOST_TEST(rb.get_allocator().m_move_contructed == false);
  32. }
  33. void test_move_constructor()
  34. {
  35. typedef propagation_test_allocator<char, 0> alloc_t;
  36. resource_adaptor<alloc_t> ra;
  37. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  38. resource_adaptor<alloc_t> rb(::boost::move(ra));
  39. BOOST_TEST(rb.get_allocator().m_default_contructed == false);
  40. BOOST_TEST(rb.get_allocator().m_move_contructed == true);
  41. }
  42. void test_lvalue_alloc_constructor()
  43. {
  44. typedef propagation_test_allocator<char, 0> alloc_t;
  45. alloc_t a;
  46. resource_adaptor<alloc_t> ra(a);
  47. BOOST_TEST(ra.get_allocator().m_default_contructed == false);
  48. BOOST_TEST(ra.get_allocator().m_move_contructed == false);
  49. }
  50. void test_rvalue_alloc_constructor()
  51. {
  52. typedef propagation_test_allocator<char, 0> alloc_t;
  53. alloc_t a;
  54. resource_adaptor<alloc_t> ra(::boost::move(a));
  55. BOOST_TEST(ra.get_allocator().m_default_contructed == false);
  56. BOOST_TEST(ra.get_allocator().m_move_contructed == true);
  57. }
  58. void test_copy_assign()
  59. {
  60. typedef propagation_test_allocator<char, 0> alloc_t;
  61. resource_adaptor<alloc_t> ra;
  62. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  63. resource_adaptor<alloc_t> rb;
  64. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  65. rb = ra;
  66. BOOST_TEST(rb.get_allocator().m_move_contructed == false);
  67. BOOST_TEST(rb.get_allocator().m_move_assigned == false);
  68. }
  69. void test_move_assign()
  70. {
  71. typedef propagation_test_allocator<char, 0> alloc_t;
  72. resource_adaptor<alloc_t> ra;
  73. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  74. resource_adaptor<alloc_t> rb;
  75. BOOST_TEST(ra.get_allocator().m_default_contructed == true);
  76. rb = ::boost::move(ra);
  77. BOOST_TEST(rb.get_allocator().m_move_contructed == false);
  78. BOOST_TEST(rb.get_allocator().m_move_assigned == true);
  79. }
  80. struct stateful
  81. {
  82. public:
  83. typedef char value_type;
  84. template<class U>
  85. struct rebind
  86. { typedef stateful other; };
  87. stateful()
  88. : m_u(0u)
  89. {}
  90. char *allocate(std::size_t n)
  91. { allocate_size = n; return allocate_return; }
  92. void deallocate(char *p, std::size_t n)
  93. { deallocate_p = p; deallocate_size = n; }
  94. friend bool operator==(const stateful &l, const stateful &r)
  95. { return l.m_u == r.m_u; }
  96. friend bool operator!=(const stateful &l, const stateful &r)
  97. { return l.m_u != r.m_u; }
  98. public:
  99. unsigned m_u;
  100. std::size_t allocate_size;
  101. char *allocate_return;
  102. std::size_t deallocate_size;
  103. char *deallocate_p;
  104. };
  105. void test_get_allocator()
  106. {
  107. stateful a;
  108. a.m_u = 999;
  109. resource_adaptor<stateful> ra(a);
  110. const resource_adaptor<stateful> & cra = ra;
  111. BOOST_TEST( ra.get_allocator().m_u == 999);
  112. BOOST_TEST(cra.get_allocator().m_u == 999);
  113. }
  114. typedef resource_adaptor<stateful> stateful_resource_adaptor_t;
  115. struct derived_from_resource_adaptor_stateful
  116. : public stateful_resource_adaptor_t
  117. {
  118. public:
  119. typedef stateful_resource_adaptor_t base_t;
  120. using base_t::do_allocate;
  121. using base_t::do_deallocate;
  122. using base_t::do_is_equal;
  123. };
  124. void test_do_allocate_deallocate()
  125. {
  126. {
  127. derived_from_resource_adaptor_stateful dra;
  128. char dummy = 0;
  129. dra.get_allocator().allocate_return = &dummy;
  130. void *allocate_ret = dra.do_allocate(998, 1);
  131. BOOST_TEST(allocate_ret == &dummy);
  132. BOOST_TEST(dra.get_allocator().allocate_size == 998);
  133. }
  134. {
  135. derived_from_resource_adaptor_stateful dra;
  136. char dummy = 0;
  137. dra.do_deallocate(&dummy, 1234, 1);
  138. BOOST_TEST(dra.get_allocator().deallocate_p == &dummy);
  139. BOOST_TEST(dra.get_allocator().deallocate_size == 1234);
  140. }
  141. {
  142. //Overaligned allocation
  143. derived_from_resource_adaptor_stateful dra;
  144. const std::size_t alignment = max_alignment_value*2u;
  145. const std::size_t bytes = alignment/2;
  146. char dummy[alignment*2u+sizeof(void*)];
  147. dra.get_allocator().allocate_return = dummy;
  148. //First allocate
  149. void *allocate_ret = dra.do_allocate(bytes, alignment);
  150. BOOST_TEST( (char*)allocate_ret >= (dummy+sizeof(void*)) && (char*)allocate_ret < (dummy + sizeof(dummy)) );
  151. BOOST_TEST( (std::size_t(allocate_ret) & (alignment - 1u)) == 0 );
  152. BOOST_TEST( dra.get_allocator().allocate_size >= (alignment/2+sizeof(void*)) );
  153. //Then allocate
  154. dra.do_deallocate(allocate_ret, bytes, alignment);
  155. BOOST_TEST(dra.get_allocator().deallocate_p == dummy);
  156. BOOST_TEST(dra.get_allocator().deallocate_size == dra.get_allocator().allocate_size);
  157. }
  158. {
  159. typedef resource_adaptor< boost::container::new_allocator<int> > new_resource_alloc_t;
  160. new_resource_alloc_t ra;
  161. boost::container::pmr::memory_resource &mr = ra;
  162. //new_allocator, low alignment
  163. mr.deallocate(mr.allocate(16, 1), 16, 1);
  164. //new_allocator, high alignment
  165. mr.deallocate(mr.allocate(16, max_alignment_value*4u), 16, max_alignment_value*4u);
  166. }
  167. {
  168. typedef resource_adaptor<std ::allocator<int> > new_resource_alloc_t;
  169. new_resource_alloc_t ra;
  170. boost::container::pmr::memory_resource &mr = ra;
  171. //std::allocator, low alignment
  172. mr.deallocate(mr.allocate(16, 1), 16, 1);
  173. //std::allocator, high alignment
  174. mr.deallocate(mr.allocate(16, max_alignment_value*4u), 16, max_alignment_value*4u);
  175. }
  176. }
  177. void test_do_is_equal()
  178. {
  179. derived_from_resource_adaptor_stateful dra;
  180. derived_from_memory_resource dmr;
  181. //Different dynamic type must return false
  182. BOOST_TEST(dra.do_is_equal(dmr) == false);
  183. //Same dynamic type with same state must return true
  184. derived_from_resource_adaptor_stateful dra2;
  185. BOOST_TEST(dra.do_is_equal(dra2) == true);
  186. //Same dynamic type with different state must return false
  187. dra2.get_allocator().m_u = 1234;
  188. BOOST_TEST(dra.do_is_equal(dra2) == false);
  189. }
  190. int main()
  191. {
  192. test_default_constructor();
  193. test_copy_constructor();
  194. test_move_constructor();
  195. test_lvalue_alloc_constructor();
  196. test_rvalue_alloc_constructor();
  197. test_copy_assign();
  198. test_move_assign();
  199. test_get_allocator();
  200. test_do_allocate_deallocate();
  201. test_do_is_equal();
  202. return ::boost::report_errors();
  203. }