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