test_simple_seg_storage.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /* Copyright (C) 2000, 2001 Stephen Cleary
  2. * Copyright (C) 2011 Kwan Ting Chan
  3. *
  4. * Use, modification and distribution is subject to the
  5. * Boost Software License, Version 1.0. (See accompanying
  6. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
  9. #define BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
  10. #include <boost/pool/simple_segregated_storage.hpp>
  11. #include <boost/assert.hpp>
  12. #include <boost/detail/lightweight_test.hpp>
  13. #include <functional>
  14. #include <set>
  15. #include <utility>
  16. #include <vector>
  17. #include <cstddef>
  18. class test_simp_seg_store : public boost::simple_segregated_storage<std::size_t>
  19. {
  20. private:
  21. // ::first is the address of the start of the added block,
  22. // ::second is the size in bytes of the added block
  23. std::vector<std::pair<void*, std::size_t> > allocated_blocks;
  24. size_type np_sz;
  25. std::set<void*> allocated_chunks;
  26. void set_partition_size(const size_type sz)
  27. {
  28. if(allocated_blocks.empty())
  29. {
  30. np_sz = sz;
  31. }
  32. else
  33. {
  34. BOOST_ASSERT(np_sz == sz);
  35. }
  36. }
  37. // Return: true if chunk is from added blocks, false otherwise
  38. bool is_inside_allocated_blocks(void* const chunk) const
  39. {
  40. typedef std::vector<std::pair<void*, std::size_t> >::const_iterator
  41. VPIter;
  42. for(VPIter iter = allocated_blocks.begin();
  43. iter != allocated_blocks.end();
  44. ++iter)
  45. {
  46. if( std::less_equal<void*>()(iter->first, chunk)
  47. && std::less_equal<void*>()(static_cast<char*>(chunk) + np_sz,
  48. static_cast<char*>(iter->first) + iter->second) )
  49. {
  50. return true;
  51. }
  52. }
  53. return false;
  54. }
  55. void check_in(void* const chunk)
  56. {
  57. // Check that the newly allocated chunk has not already previously
  58. // been allocated, and that the memory does not overlap with
  59. // previously allocated chunks
  60. for(std::set<void*>::const_iterator iter = allocated_chunks.begin();
  61. iter != allocated_chunks.end();
  62. ++iter)
  63. {
  64. BOOST_TEST( std::less_equal<void*>()(static_cast<char*>(chunk)
  65. + np_sz, *iter)
  66. || std::less_equal<void*>()(static_cast<char*>(*iter)
  67. + np_sz, chunk) );
  68. }
  69. allocated_chunks.insert(chunk);
  70. }
  71. void check_out(void* const chunk)
  72. {
  73. BOOST_TEST(allocated_chunks.erase(chunk) == 1);
  74. }
  75. public:
  76. test_simp_seg_store()
  77. : np_sz(0) {}
  78. void* get_first() { return first; }
  79. static void*& get_nextof(void* const ptr) { return nextof(ptr); }
  80. // (Test) Pre: npartition_sz of all added block is the same
  81. // different blocks of memory does not overlap
  82. void add_block(void* const block,
  83. const size_type nsz, const size_type npartition_sz)
  84. {
  85. set_partition_size(npartition_sz);
  86. allocated_blocks.push_back(
  87. std::pair<void*, std::size_t>(block, nsz) );
  88. boost::simple_segregated_storage<std::size_t>::add_block(
  89. block, nsz, npartition_sz );
  90. // Post: !empty()
  91. BOOST_TEST(!empty());
  92. }
  93. // (Test) Pre: npartition_sz of all added block is the same
  94. // different blocks of memory does not overlap
  95. void add_ordered_block(void* const block,
  96. const size_type nsz, const size_type npartition_sz)
  97. {
  98. set_partition_size(npartition_sz);
  99. allocated_blocks.push_back(
  100. std::pair<void*, std::size_t>(block, nsz) );
  101. boost::simple_segregated_storage<std::size_t>::add_ordered_block(
  102. block, nsz, npartition_sz );
  103. // Post: !empty()
  104. BOOST_TEST(!empty());
  105. }
  106. void* malloc()
  107. {
  108. void* const ret
  109. = boost::simple_segregated_storage<std::size_t>::malloc();
  110. // Chunk returned should actually be from added blocks
  111. BOOST_TEST(is_inside_allocated_blocks(ret));
  112. check_in(ret);
  113. return ret;
  114. }
  115. void free(void* const chunk)
  116. {
  117. BOOST_ASSERT(chunk);
  118. check_out(chunk);
  119. boost::simple_segregated_storage<std::size_t>::free(chunk);
  120. // Post: !empty()
  121. BOOST_TEST(!empty());
  122. }
  123. void ordered_free(void* const chunk)
  124. {
  125. BOOST_ASSERT(chunk);
  126. check_out(chunk);
  127. boost::simple_segregated_storage<std::size_t>::ordered_free(chunk);
  128. // Post: !empty()
  129. BOOST_TEST(!empty());
  130. }
  131. void* malloc_n(size_type n, size_type partition_size)
  132. {
  133. void* const ret
  134. = boost::simple_segregated_storage<std::size_t>::malloc_n(
  135. n, partition_size );
  136. if(ret)
  137. {
  138. for(std::size_t i=0; i < n; ++i)
  139. {
  140. void* const chunk = static_cast<char*>(ret)
  141. + (i * partition_size);
  142. // Memory returned should actually be from added blocks
  143. BOOST_TEST(is_inside_allocated_blocks(chunk));
  144. check_in(chunk);
  145. }
  146. }
  147. return ret;
  148. }
  149. };
  150. #endif // BOOST_POOL_TEST_SIMP_SEG_STORE_HPP