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