2
* Copyright (c) 2005, Eric Crahen
4
* Permission is hereby granted, free of charge, to any person obtaining a copy
5
* of this software and associated documentation files (the "Software"), to deal
6
* in the Software without restriction, including without limitation the rights
7
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
* copies of the Software, and to permit persons to whom the Software is furnished
9
* to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice shall be included in all
12
* copies or substantial portions of the Software.
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
#ifndef __ZTSINGLETON_H__
24
#define __ZTSINGLETON_H__
26
#include "zthread/Guard.h"
27
#include "zthread/FastMutex.h"
33
// This policy controls how an object is instantiated
34
// as well as how and when its destroyed. Phoenix-style
35
// singletons are not supported easily with type of policy,
36
// this is intentional since I do not believe that is in
37
// the true spirit of a singleton.
39
// InstantiationPolicContract {
41
// create(pointer_type&)
46
* @class LocalStaticInstantiation
47
* @author Eric Crahen <http://www.code-foo.com>
48
* @date <2003-07-16T17:57:45-0400>
51
* The LocalStaticInstantiation policy allows the creation
52
* and lifetime of an instance of a particular type
53
* to be managed using static local values. This will
54
* abide by the standard C++ rules for static objects
57
class LocalStaticInstantiation {
61
* Create an instance of an object, using a local static. The
62
* object will be destroyed by the system.
64
* @param ptr reference to location to receive the address
65
* of the allocated object
68
static void create(T*& ptr) {
79
class StaticInstantiationHelper {
81
friend class StaticInstantiation;
88
T StaticInstantiationHelper<T>::instance;
91
* @class StaticInstantiation
92
* @author Eric Crahen <http://www.code-foo.com>
93
* @date <2003-07-16T17:57:45-0400>
96
* The StaticInstantiation policy allows the creation
97
* and lifetime of an instance of a particular type
98
* to be managed using static instantiation. This will
99
* abide by the standard C++ rules for static objects
102
class StaticInstantiation {
106
* Create an instance of an object using by simply allocating it statically.
108
* @param ptr reference to location to receive the address
109
* of the allocated object
112
static void create(T*& ptr) {
113
ptr = &StaticInstantiationHelper<T>::instance;
118
//! SingletonDestroyer
126
Destroyer(T* q) : doomed(q) {
135
Destroyer<T>::~Destroyer() {
150
* @class LazyInstantiation
151
* @author Eric Crahen <http://www.code-foo.com>
152
* @date <2003-07-16T17:57:45-0400>
155
* The LazyInstantiation policy allows the creation
156
* and lifetime of an instance of a particular type
157
* to be managed using dynamic allocation and a singleton
158
* destroyer. This will abide by the standard C++ rules
159
* for static objects lifetimes.
161
class LazyInstantiation {
165
* Create an instance of an object, using new, that will be
166
* destroyed when an associated Destroyer object (allocated
167
* statically) goes out of scope.
169
* @param ptr reference to location to receive the address
170
* of the allocated object
173
static void create(T*& ptr) {
176
static Destroyer<T> destroyer(ptr);
185
* @author Eric Crahen <http://www.code-foo.com>
186
* @date <2003-07-16T17:57:45-0400>
189
* Based on the work of John Vlissidles in his book 'Pattern Hatching'
190
* an article by Douglas Schmidtt on double-checked locking and policy
191
* templates described by Andrei Alexandrescu.
193
* This is a thread safe wrapper for creating Singleton classes. The
194
* synchronization method and instantiation methods can be changed
195
* easily by specifying different policy implementations as the
196
* templates parameters.
200
* // Most common Singleton
201
* Singletion<LonesomeType>
203
* // Singleton that uses static storage
204
* Singletion<LonesomeType, StaticInstantiation>
206
* // Single-threaded singleton that uses static storage (Meyers-like)
207
* Singletion<LonesomeType, LocalStaticInstantiation, NotLocked>
211
template <class T, class InstantiationPolicy=LazyInstantiation, class LockType=FastMutex>
212
class Singleton : private InstantiationPolicy, private NonCopyable {
216
* Provide access to the single instance through double-checked locking
218
* @return T* single instance
220
static T* instance();
224
template <class T, class InstantiationPolicy, class LockType>
225
T* Singleton<T, InstantiationPolicy, LockType>::instance() {
227
// Uses local static storage to avoid static construction
228
// sequence issues. (regaring when the lock is created)
230
static LockType lock;
234
Guard<LockType, LockedScope> g(lock);
236
InstantiationPolicy::create(ptr);
240
return const_cast<T*>(ptr);