1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gcounter.h
19 ///
20 
21 #ifndef G_OBJECT_COUNTER_H
22 #define G_OBJECT_COUNTER_H
23 
24 #include "gdef.h"
25 #include "gdebug.h"
26 
27 /// \namespace G
28 namespace G
29 {
30 	class CounterImp ;
31 }
32 
33 /// \class G::CounterImp
34 /// A private implementation class used
35 /// by the G::Counter<> class template.
36 ///
37 class G::CounterImp
38 {
39 public:
40 	static void check( const char * class_name , unsigned long n ) ;
41 		///< Checks the instance counter.
42 } ;
43 
44 /// \namespace G
45 namespace G
46 {
47 
48 /// \class G::Counter
49 /// An instance counter to help with leak testing.
50 ///
51 /// Typically used as a private base class. (Strictly
52 /// this uses the curiously recurring template pattern, but
53 /// it does not do any static_cast<D> downcasting.)
54 ///
55 /// Note that the second template parameter (the class name)
56 /// needs a declaration like "extern char FooClassName[]",
57 /// not a string literal.
58 ///
59 template <typename D, const char * C>
60 class Counter : private CounterImp
61 {
62 public:
63 	Counter() ;
64 		///< Constructor.
65 
66 	~Counter() ;
67 		///< Destructor.
68 
69 	Counter( const Counter<D,C> & ) ;
70 		///< Copy constructor.
71 
72 	void operator=( const Counter<D,C> & ) ;
73 		///< Assignment operator.
74 
75 private:
76 	static unsigned long m_n ;
77 } ;
78 
79 template <typename D, const char * C>
80 unsigned long Counter<D,C>::m_n = 0UL ;
81 
82 template <typename D, const char * C>
Counter()83 Counter<D,C>::Counter()
84 {
85 	m_n++ ;
86 	check( C , m_n ) ;
87 }
88 
89 template <typename D, const char * C>
~Counter()90 Counter<D,C>::~Counter()
91 {
92 	m_n-- ;
93 	check( C , m_n ) ;
94 }
95 
96 template <typename D, const char * C>
Counter(const Counter<D,C> &)97 Counter<D,C>::Counter( const Counter<D,C> & )
98 {
99 	m_n++ ;
100 	check( C , m_n ) ;
101 }
102 
103 template <typename D, const char * C>
104 void Counter<D,C>::operator=( const Counter<D,C> & )
105 {
106 }
107 
108 }
109 
110 #endif
111