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
11 #include <boost/assert.hpp>
12 #include <boost/unordered/detail/allocate.hpp>
13 #include "../helpers/test.hpp"
23 memory_area(void const* s, void const* e)
26 BOOST_ASSERT(start != end);
31 explicit memory_track(int tag = -1) :
39 // This is a bit dodgy as it defines overlapping
40 // areas as 'equal', so this isn't a total ordering.
41 // But it is for non-overlapping memory regions - which
42 // is what'll be stored.
44 // All searches will be for areas entirely contained by
45 // a member of the set - so it should find the area that contains
46 // the region that is searched for.
48 struct memory_area_compare {
49 bool operator()(memory_area const& x, memory_area const& y) const {
50 return x.end <= y.start;
54 struct memory_tracker {
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),
66 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,
106 BOOST_ERROR("Allocating 0 length array.");
110 allocated_memory.insert(
111 std::pair<memory_area const, memory_track>(
112 memory_area(ptr, (char*) ptr + n * size),
117 void track_deallocate(void* ptr, std::size_t n, std::size_t size,
118 int tag, bool check_tag_ = true)
120 allocated_memory_type::iterator pos =
121 allocated_memory.find(
122 memory_area(ptr, (char*) ptr + n * size));
123 if(pos == allocated_memory.end()) {
124 BOOST_ERROR("Deallocating unknown pointer.");
126 BOOST_TEST(pos->first.start == ptr);
127 BOOST_TEST(pos->first.end == (char*) ptr + n * size);
128 if (check_tag_) BOOST_TEST(pos->second.tag_ == tag);
129 allocated_memory.erase(pos);
131 BOOST_TEST(count_allocations > 0);
132 if(count_allocations > 0) --count_allocations;
135 void track_construct(void* /*ptr*/, std::size_t /*size*/,
138 ++count_constructions;
141 void track_destroy(void* /*ptr*/, std::size_t /*size*/,
144 BOOST_TEST(count_constructions > 0);
145 if(count_constructions > 0) --count_constructions;
152 // This won't be a problem as I'm only using a single compile unit
153 // in each test (this is actually required by the minimal test
156 // boostinspect:nounnamed
158 test::detail::memory_tracker tracker;