]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/generic/static.h
50fb3b711523ed2040ed849fb006124a9183dc4e
[xonotic/netradiant.git] / libs / generic / static.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_GENERIC_STATIC_H)
23 #define INCLUDED_GENERIC_STATIC_H
24
25 /// \file
26 /// \brief Template techniques for instantiating singletons.
27
28 #include <cstddef>
29
30 /// \brief A singleton which is statically initialised.
31 ///
32 /// \param Type The singleton object type.
33 ///
34 /// \dontinclude generic/static.cpp
35 /// \skipline Static example
36 /// \until end example
37 template<typename Type>
38 class Static
39 {
40   static Type m_instance;
41 public:
42   static Type& instance()
43   {
44     return m_instance;
45   }
46 };
47
48 template<typename Type>
49 Type Static<Type>::m_instance;
50
51
52 /// \brief A singleton which is lazily initialised.
53 /// The instance is constructed the first time it is referenced, and is never destroyed.
54 ///
55 /// \param Type The singleton object type.
56 ///
57 /// \dontinclude generic/static.cpp
58 /// \skipline LazyStatic example
59 /// \until end example
60 template<typename Type>
61 class LazyStatic
62 {
63   static Type* m_instance; // this will be initialised to 0 by the CRT, according to the c++ standard
64 public:
65   static Type& instance()
66   {
67     if(m_instance == 0)
68     {
69       m_instance = new Type; // allocate using 'new' to get the correct alignment
70     }
71     return *m_instance;
72   }
73 };
74
75 template<typename Type>
76 Type* LazyStatic<Type>::m_instance;
77
78
79 /// \brief A singleton which keeps a count of the number of times it is referenced.
80 ///
81 /// The instance is constructed when its reference count changes from 0 to 1 and destroyed when its reference count changes from 1 to 0.
82 /// Use with SmartStatic.
83 ///
84 /// \param Type The singleton object type.
85 template<typename Type>
86 class CountedStatic
87 {
88   static std::size_t m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard
89   static Type* m_instance;
90 public:
91   static Type& instance()
92   {
93     return *m_instance;
94   }
95   static void capture()
96   {
97     if(++m_refcount == 1)
98     {
99       m_instance = new Type; // allocate using 'new' to get the correct alignment
100     }
101   }
102   static void release()
103   {
104     if(--m_refcount == 0)
105     {
106       delete m_instance;
107     }
108   }
109 };
110
111 template<typename Type>
112 std::size_t CountedStatic<Type>::m_refcount; // this will be initialised to 0 by the CRT, according to the c++ standard
113 template<typename Type>
114 Type* CountedStatic<Type>::m_instance;
115
116 /// \brief A reference to a CountedStatic.
117 /// Guarantees that CountedStatic<Type> will be constructed for the lifetime of this object.
118 ///
119 /// \param Type The type parameter of the CountedStatic to reference.
120 ///
121 /// \dontinclude generic/static.cpp
122 /// \skipline SmartStatic example
123 /// \until end example
124 template<typename Type>
125 class SmartStatic
126 {
127 public:
128   SmartStatic()
129   {
130     CountedStatic<Type>::capture();
131   }
132   ~SmartStatic()
133   {
134     CountedStatic<Type>::release();
135   }
136   Type& instance()
137   {
138     return CountedStatic<Type>::instance();
139   }
140 };
141
142
143 #endif