1 /*============================================================================= 2 Blobby Volley 2 3 Copyright (C) 2006 Jonathan Sieber (jonathan_sieber@yahoo.de) 4 Copyright (C) 2006 Daniel Knobe (daniel-knobe@web.de) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 =============================================================================*/ 20 21 #pragma once 22 23 #include <typeinfo> 24 #include <iosfwd> 25 #include <utility> 26 #include <cstddef> 27 #include <cstdlib> 28 #include <memory> 29 #include <string> 30 31 int count(const std::type_info& type); 32 int uncount(const std::type_info& type); 33 int count(const std::type_info& type, std::string tag, int num); 34 int uncount(const std::type_info& type, std::string tag, int num); 35 36 /*! \class ObjectCounter 37 \brief Logging number of creations and living objects 38 \details To use this class for logging creations of a class TYPE, just derive it 39 from ObjectCounter<TYPE>. A full memory report can be written to a stream 40 by the record function. 41 \todo more specific reporting, watches, etc. 42 */ 43 template<class Base> 44 class ObjectCounter 45 { 46 public: ObjectCounter()47 ObjectCounter() 48 { 49 count(typeid(Base)); 50 }; 51 ~ObjectCounter()52 ~ObjectCounter() 53 { 54 uncount(typeid(Base)); 55 }; 56 ObjectCounter(const ObjectCounter & other)57 ObjectCounter(const ObjectCounter& other) 58 { 59 count(typeid(Base)); 60 } 61 62 ObjectCounter& operator=(const ObjectCounter& other) 63 { 64 return *this; 65 } 66 }; 67 68 69 void report(std::ostream& stream); 70 int getObjectCount(const std::type_info& type); 71 72 struct CountingReport 73 { CountingReportCountingReport74 CountingReport() : alive(0), created(0) 75 { 76 77 } 78 79 int alive; 80 int created; 81 }; 82 83 // counting allocator 84 template<class T, typename tag_type> 85 struct CountingAllocator : private std::allocator<T> 86 { 87 typedef std::allocator<T> Base; 88 typedef T value_type; 89 typedef T* pointer; 90 typedef T& reference; 91 typedef const T* const_pointer; 92 typedef const T& const_reference; 93 typedef size_t size_type; 94 typedef ptrdiff_t difference_type ; 95 CountingAllocatorCountingAllocator96 CountingAllocator() 97 { 98 99 } 100 101 template<class V, typename tag2> CountingAllocatorCountingAllocator102 CountingAllocator(const CountingAllocator<V, tag2>& other) 103 { 104 } 105 106 template<typename _Tp1> 107 struct rebind 108 { 109 typedef CountingAllocator<_Tp1, tag_type> other; 110 }; 111 112 113 114 pointer allocate (size_type n, std::allocator<void>::const_pointer hint = 0) 115 { 116 count(typeid(T), tag_type::tag(), n); 117 return Base::allocate(n, hint); 118 } 119 deallocateCountingAllocator120 void deallocate (pointer p, size_type n) 121 { 122 uncount(typeid(T), tag_type::tag(), n); 123 Base::deallocate(p, n); 124 } 125 126 using Base::address; 127 using Base::max_size; 128 using Base::construct; 129 using Base::destroy; 130 }; 131 132 133 134 int count(const std::type_info& type, std::string tag, void* address, int num); 135 int uncount(const std::type_info& type, std::string tag, void* address); 136 137 template<class T, typename tag_type> 138 struct CountingMalloc 139 { 140 typedef T* pointer; 141 typedef T& reference; 142 typedef size_t size_type; 143 mallocCountingMalloc144 static pointer malloc (size_type n) 145 { 146 pointer nm = static_cast<pointer> ( ::malloc(n) ); 147 count(typeid(T), tag_type::tag(), nm, n); 148 return nm; 149 } 150 freeCountingMalloc151 static void free (pointer& p) 152 { 153 uncount(typeid(T), tag_type::tag(), p); 154 ::free(p); 155 p = 0; 156 } 157 reallocCountingMalloc158 static pointer realloc ( pointer ptr, size_t size ) 159 { 160 uncount(typeid(T), tag_type::tag(), ptr); 161 pointer nm = static_cast<pointer>(::realloc(ptr, size)); 162 count(typeid(T), tag_type::tag(), nm, size); 163 } 164 }; 165 166 struct string_tag 167 { tagstring_tag168 static std::string tag() 169 { 170 return "basic_string<char>"; 171 } 172 }; 173 174 typedef std::basic_string< char, std::char_traits<char>, CountingAllocator<char, string_tag> > TrackedString; 175 176 void debug_count_execution_fkt(std::string file, int line); 177 178 #define DEBUG_COUNT_EXECUTION debug_count_execution_fkt(__FILE__, __LINE__); 179 180 181 182 #ifdef DEBUG 183 184 #define DEBUG_STATUS(x) std::cout << x << std::endl; 185 186 #else 187 188 #define DEBUG_STATUS(x) 189 190 #endif // DEBUG 191 192 193 194 195