PageRenderTime 47ms CodeModel.GetById 13ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 1ms

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