1 /*
2  *  tDMSingleton.h
3  *  Avida
4  *
5  *  Created by David on 10/31/08.
6  *  Copyright 2008-2011 Michigan State University. All rights reserved.
7  *
8  *
9  *  This file is part of Avida.
10  *
11  *  Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12  *  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13  *
14  *  Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License along with Avida.
18  *  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef tDMSingleton_h
23 #define tDMSingleton_h
24 
25 #include "apto/core/Mutex.h"
26 #include "avida/core/GlobalObject.h"
27 
28 using namespace Avida;
29 
30 
31 template<typename T> class tDMSingleton : public virtual GlobalObject
32 {
33 private:
34   static tDMSingleton* s_dms;
35 
36   T* m_object;
37 
38 
tDMSingleton(T * object)39   tDMSingleton(T* object) : m_object(object) { ; }
40 
41   tDMSingleton(); // @not_implemented
42   tDMSingleton(const tDMSingleton&); // @not_implemented
43   tDMSingleton& operator=(const tDMSingleton&); // @not_implemented
44 
45 
46 public:
~tDMSingleton()47   ~tDMSingleton() { delete m_object; }
48 
Initialize(T * (construct)())49   static void Initialize(T* (construct)())
50   {
51     if (!s_dms) {
52       s_dms = new tDMSingleton((*construct)());
53       GlobalObjectManager::Register(s_dms);
54     }
55   }
56 
GetInstance()57   static T& GetInstance() { return *s_dms->m_object; }
58 };
59 
60 template<typename T> tDMSingleton<T>* tDMSingleton<T>::s_dms = NULL;
61 
62 
63 template<typename T> class tLazyDMSingleton : public virtual GlobalObject
64 {
65 private:
66   static tLazyDMSingleton* s_dms;
67 
68   Apto::Mutex m_mutex;
69   T* (*m_construct)();
70   T* m_object;
71 
72 
tLazyDMSingleton(T * (* construct)())73   tLazyDMSingleton(T* (*construct)()) : m_object(NULL), m_construct(construct) { ; }
74 
75   tLazyDMSingleton(); // @not_implemented
76   tLazyDMSingleton(const tLazyDMSingleton&); // @not_implemented
77   tLazyDMSingleton& operator=(const tLazyDMSingleton&); // @not_implemented
78 
79 
80 public:
~tLazyDMSingleton()81   ~tLazyDMSingleton() { delete m_object; }
82 
Initialize(T * (* construct)())83   static void Initialize(T* (*construct)())
84   {
85     if (!s_dms) {
86       s_dms = new tLazyDMSingleton(construct);
87       GlobalObjectManager::Register(s_dms);
88     }
89   }
90 
GetInstance()91   static T& GetInstance()
92   {
93     Apto::MutexAutoLock lock(s_dms->m_mutex);
94 
95     if (!s_dms->m_object) {
96       s_dms->m_object = (*s_dms->m_construct)();
97     }
98 
99     return *s_dms->m_object;
100   }
101 };
102 
103 template<typename T> tLazyDMSingleton<T>* tLazyDMSingleton<T>::s_dms = NULL;
104 
105 #endif
106