1 //////////////////////////////////////////////////////////////////
5 // All singleton objects are put into a list
6 // so that it would be delete when program exits.
9 // This work is published under the GNU Public License (GPL)
10 // see file COPYING for details.
11 // We also explicitely grant the right to link this code
12 // with the OpenH323 library.
14 //////////////////////////////////////////////////////////////////
17 #define SINGLETON_H "@(#) $Id: singleton.h,v 1.14 2007/03/21 22:30:16 willamowius Exp $"
25 // a list of pointers that would delete all objects
26 // referred by the pointers in the list on destruction
28 template<class T> class listptr : public std::list<void *> {
30 listptr() : clear_list(false) {}
35 static void delete_obj(void *t) { delete static_cast<T *>(t); }
38 template<class T> listptr<T>::~listptr()
41 std::for_each(begin(), end(), delete_obj);
45 // Base class for all singletons
48 SingletonBase(const char *);
49 virtual ~SingletonBase();
53 // Note the SingletonBase instance is not singleton itself :p
54 // However, list of singletons *are* singleton
55 // But we can't put the singleton into the list :(
56 static listptr<SingletonBase> _instance_list;
60 // A singleton class should be derived from this template.
61 // class Ts : public Singleton<Ts> {
65 // If the class is instantiated more than once,
66 // a runtime error would be thrown
68 // I provide two ways to access the singleton:
69 // (since I'm not sure which is better)
70 // T::Instance() or InstanceOf<T>
72 template<class T> class Singleton : public SingletonBase {
75 template<class U> static T *Instance(const U &);
78 Singleton(const char *);
83 static PMutex m_CreationLock;
86 template<class T> Singleton<T>::Singleton(const char *n) : SingletonBase(n)
88 // if (m_Instance != 0)
89 // throw std::runtime_error("Duplicate instances");
92 template<class T> Singleton<T>::~Singleton()
94 PWaitAndSignal lock(m_CreationLock);
98 // Function to access the singleton
99 template<class T> T *Singleton<T>::Instance()
101 if (m_Instance == 0) {
102 PWaitAndSignal lock(m_CreationLock);
103 // We have to check it again after we got the lock
110 #ifndef _WIN32 // VC++ doesn't support nested template?
111 template<class T> template <class U> T *Singleton<T>::Instance(const U &u)
113 if (m_Instance == 0) {
114 PWaitAndSignal lock(m_CreationLock);
115 // We have to check it again after we got the lock
117 m_Instance = new T(u);
123 // Function to access the singleton
124 template<class T> T *InstanceOf()
126 if (Singleton<T>::m_Instance == 0) {
127 PWaitAndSignal lock(Singleton<T>::m_CreationLock);
128 // We have to check it again after we got the lock
129 if (Singleton<T>::m_Instance == 0)
130 Singleton<T>::m_Instance = new T;
132 return Singleton<T>::m_Instance;
136 template<class T> T *Singleton<T>::m_Instance=0;
137 template<class T> PMutex Singleton<T>::m_CreationLock;
140 #endif // SINGLETON_H