2 // Copyright 2006-2009 Daniel James.
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
7 #define BOOST_UNORDERED_TEST_MEMORY_HEADER
9 #include "../helpers/test.hpp"
10 #include <boost/assert.hpp>
11 #include <boost/unordered/detail/implementation.hpp>
22 memory_area(void const* s, void const* e) : start(s), end(e)
24 BOOST_ASSERT(start != end);
30 explicit memory_track(int tag = -1) : constructed_(0), tag_(tag) {}
36 // This is a bit dodgy as it defines overlapping
37 // areas as 'equal', so this isn't a total ordering.
38 // But it is for non-overlapping memory regions - which
39 // is what'll be stored.
41 // All searches will be for areas entirely contained by
42 // a member of the set - so it should find the area that contains
43 // the region that is searched for.
45 struct memory_area_compare
47 bool operator()(memory_area const& x, memory_area const& y) const
49 return x.end <= y.start;
55 typedef std::map<memory_area, memory_track, memory_area_compare,
56 std::allocator<std::pair<memory_area const, memory_track> > >
57 allocated_memory_type;
59 allocated_memory_type allocated_memory;
60 unsigned int count_allocators;
61 unsigned int count_allocations;
62 unsigned int count_constructions;
65 : count_allocators(0), count_allocations(0), count_constructions(0)
71 if (count_allocators == 0) {
72 count_allocations = 0;
73 count_constructions = 0;
74 allocated_memory.clear();
79 void allocator_unref()
81 BOOST_TEST(count_allocators > 0);
82 if (count_allocators > 0) {
84 if (count_allocators == 0) {
85 bool no_allocations_left = (count_allocations == 0);
86 bool no_constructions_left = (count_constructions == 0);
87 bool allocated_memory_empty = allocated_memory.empty();
89 // Clearing the data before the checks terminate the
91 count_allocations = 0;
92 count_constructions = 0;
93 allocated_memory.clear();
95 BOOST_TEST(no_allocations_left);
96 BOOST_TEST(no_constructions_left);
97 BOOST_TEST(allocated_memory_empty);
102 void track_allocate(void* ptr, std::size_t n, std::size_t size, int tag)
105 BOOST_ERROR("Allocating 0 length array.");
108 allocated_memory.insert(std::pair<memory_area const, memory_track>(
109 memory_area(ptr, (char*)ptr + n * size), memory_track(tag)));
113 void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag,
114 bool check_tag_ = true)
116 allocated_memory_type::iterator pos =
117 allocated_memory.find(memory_area(ptr, (char*)ptr + n * size));
118 if (pos == allocated_memory.end()) {
119 BOOST_ERROR("Deallocating unknown pointer.");
121 BOOST_TEST(pos->first.start == ptr);
122 BOOST_TEST(pos->first.end == (char*)ptr + n * size);
124 BOOST_TEST(pos->second.tag_ == tag);
125 allocated_memory.erase(pos);
127 BOOST_TEST(count_allocations > 0);
128 if (count_allocations > 0)
132 void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
134 ++count_constructions;
137 void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
139 BOOST_TEST(count_constructions > 0);
140 if (count_constructions > 0)
141 --count_constructions;
147 // This won't be a problem as I'm only using a single compile unit
148 // in each test (this is actually required by the minimal test
151 // boostinspect:nounnamed
153 test::detail::memory_tracker tracker;