/Src/Dependencies/Boost/libs/unordered/test/helpers/memory.hpp

http://hadesmem.googlecode.com/ · C++ Header · 173 lines · 136 code · 24 blank · 13 comment · 19 complexity · 303314a62a63e389a40809702cddb039 MD5 · raw file

  1. // Copyright 2006-2009 Daniel James.
  2. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
  5. #define BOOST_UNORDERED_TEST_MEMORY_HEADER
  6. #include <memory>
  7. #include <map>
  8. #include <boost/mpl/apply.hpp>
  9. #include <boost/assert.hpp>
  10. #include <boost/unordered/detail/allocator_helpers.hpp>
  11. #include <boost/mpl/aux_/config/eti.hpp>
  12. #include "../helpers/test.hpp"
  13. namespace test
  14. {
  15. namespace detail
  16. {
  17. struct memory_area {
  18. void const* start;
  19. void const* end;
  20. memory_area(void const* s, void const* e)
  21. : start(s), end(e)
  22. {
  23. BOOST_ASSERT(start != end);
  24. }
  25. };
  26. struct memory_track {
  27. explicit memory_track(int tag = -1) :
  28. constructed_(0),
  29. tag_(tag) {}
  30. int constructed_;
  31. int tag_;
  32. };
  33. // This is a bit dodgy as it defines overlapping
  34. // areas as 'equal', so this isn't a total ordering.
  35. // But it is for non-overlapping memory regions - which
  36. // is what'll be stored.
  37. //
  38. // All searches will be for areas entirely contained by
  39. // a member of the set - so it should find the area that contains
  40. // the region that is searched for.
  41. struct memory_area_compare {
  42. bool operator()(memory_area const& x, memory_area const& y) const {
  43. return x.end <= y.start;
  44. }
  45. };
  46. template <class Alloc>
  47. struct allocator_memory_type_gen {
  48. typedef std::map<memory_area, memory_track, memory_area_compare,
  49. Alloc> type;
  50. };
  51. #if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
  52. template <>
  53. struct allocator_memory_type_gen<int> {
  54. typedef std::map<memory_area, memory_track, memory_area_compare>
  55. type;
  56. };
  57. #endif
  58. template <class Alloc = std::allocator<int> >
  59. struct memory_tracker {
  60. typedef BOOST_DEDUCED_TYPENAME
  61. boost::unordered_detail::rebind_wrap<Alloc,
  62. std::pair<memory_area const, memory_track> >::type
  63. allocator_type;
  64. typedef BOOST_DEDUCED_TYPENAME
  65. allocator_memory_type_gen<allocator_type>::type
  66. allocated_memory_type;
  67. allocated_memory_type allocated_memory;
  68. unsigned int count_allocators;
  69. unsigned int count_allocations;
  70. unsigned int count_constructions;
  71. memory_tracker() :
  72. count_allocators(0), count_allocations(0),
  73. count_constructions(0)
  74. {}
  75. void allocator_ref()
  76. {
  77. if(count_allocators == 0) {
  78. count_allocations = 0;
  79. count_constructions = 0;
  80. allocated_memory.clear();
  81. }
  82. ++count_allocators;
  83. }
  84. void allocator_unref()
  85. {
  86. BOOST_TEST(count_allocators > 0);
  87. if(count_allocators > 0) {
  88. --count_allocators;
  89. if(count_allocators == 0) {
  90. bool no_allocations_left = (count_allocations == 0);
  91. bool no_constructions_left = (count_constructions == 0);
  92. bool allocated_memory_empty = allocated_memory.empty();
  93. // Clearing the data before the checks terminate the
  94. // tests.
  95. count_allocations = 0;
  96. count_constructions = 0;
  97. allocated_memory.clear();
  98. BOOST_TEST(no_allocations_left);
  99. BOOST_TEST(no_constructions_left);
  100. BOOST_TEST(allocated_memory_empty);
  101. }
  102. }
  103. }
  104. void track_allocate(void *ptr, std::size_t n, std::size_t size,
  105. int tag)
  106. {
  107. if(n == 0) {
  108. BOOST_ERROR("Allocating 0 length array.");
  109. }
  110. else {
  111. ++count_allocations;
  112. allocated_memory.insert(
  113. std::pair<memory_area const, memory_track>(
  114. memory_area(ptr, (char*) ptr + n * size),
  115. memory_track(tag)));
  116. }
  117. }
  118. void track_deallocate(void* ptr, std::size_t n, std::size_t size,
  119. int tag)
  120. {
  121. BOOST_DEDUCED_TYPENAME allocated_memory_type::iterator pos =
  122. allocated_memory.find(
  123. memory_area(ptr, (char*) ptr + n * size));
  124. if(pos == allocated_memory.end()) {
  125. BOOST_ERROR("Deallocating unknown pointer.");
  126. } else {
  127. BOOST_TEST(pos->first.start == ptr);
  128. BOOST_TEST(pos->first.end == (char*) ptr + n * size);
  129. BOOST_TEST(pos->second.tag_ == tag);
  130. allocated_memory.erase(pos);
  131. }
  132. BOOST_TEST(count_allocations > 0);
  133. if(count_allocations > 0) --count_allocations;
  134. }
  135. void track_construct(void* /*ptr*/, std::size_t /*size*/,
  136. int /*tag*/)
  137. {
  138. ++count_constructions;
  139. }
  140. void track_destroy(void* /*ptr*/, std::size_t /*size*/,
  141. int /*tag*/)
  142. {
  143. BOOST_TEST(count_constructions > 0);
  144. if(count_constructions > 0) --count_constructions;
  145. }
  146. };
  147. }
  148. }
  149. #endif