source: src/CodePatterns/Singleton.hpp@ 084729c

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 084729c was 084729c, checked in by Frederik Heber <heber@…>, 8 years ago

Squashed 'ThirdParty/CodePatterns/' content from commit c1e1041

git-subtree-dir: ThirdParty/CodePatterns
git-subtree-split: c1e10418c454f98be2f43d93167642b0008428fc

  • Property mode set to 100644
File size: 12.4 KB
Line 
1/*
2 * Singleton.hpp
3 *
4 * Created on: Mar 10, 2010
5 * Author: crueger
6 */
7
8#ifndef SINGLETON_HPP_
9#define SINGLETON_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include <boost/thread.hpp>
17
18#include "CodePatterns/Assert.hpp"
19#include "CodePatterns/AtomicInstance.hpp"
20
21/**
22 * This template produces the generic singleton pattern using the CRTP idiom.
23 *
24 * <h1> Singleton Howto </h1>
25 * <h2> Introduction </h2>
26 *
27 * A Singleton is a class of which there can only be a single Object in the programm. It is
28 * described as an design-pattern in Gof:96 (the famous design-pattern book). In the
29 * molecuilder there are so far several Singletons serving a wide range of purposes:
30 *
31 * - the World, which handles all atoms, molecules and bonds
32 * - the ActionRegistry, which stores all created actions by name for later use
33 * - the UIFactory, which is an AbstractFactory (another design-pattern from Gof:96) and
34 * handles all creation of gui elements to ensure a single type throughout the programm
35 * - the logger and errorLogger classes, that can be used to output messages on the screen
36 * depending on certain conditions
37 *
38 * Because those classes can only be instantiated once you cannot simply call <code>new World()</code>
39 * or <code>delete</code> on them. Rather they have to be constructed and accessed using the singleton
40 * mechanism. This mechanism consists of four static functions (and a fifth that is used internally,
41 * but we will get to that later). These functions are:
42 *
43 * - <code>Singleton& Singleton::getInstance()</code> : returns the instance of the singleton as
44 * a reference
45 * - <code>Singleton* Singleton::getPointer()</code> : returns the instance of the singleton as a
46 * pointer
47 * - <code>void Singleton::purgeInstance()</code> : destroys the single Instance of the singleton
48 * - <code>Singleton& Singleton::resetInstance()</code> : resets the Singleton, i.e. destroys the
49 * old instance and creates a new one
50 *
51 * If you need the instance of the singleton it is usually fine just to use one off the accessor
52 * functions (i.e. <code>getInstance()</code> or <code>getPointer()</code>. Any creation of the
53 * Singleton is then handled by these functions, so that the same object will be returned whenever
54 * one of these functions is called. This easy process is true for most singletons you will need
55 * to use. The only special singleton is the UIFactory.
56 *
57 * <h3>Special functions of the UIFactory</h3>
58 *
59 * If you simply call the <code>getInstance()</code> method of the UIFactory class the program
60 * will crash. This happens, because the UIFactory in itself is abstract and needs to know what
61 * kind of user interface it should produce later on. You need to tell the class the type of UI
62 * using the void <code>UIFactory::makeUserInterface(InterfaceTypes type)</code> method. This will
63 * also take care of creating the sole instance, so that the accessor functions will work afterwards.
64 * What this also means is, that you cannot <code>reset()</code> the UIFactory, because at that
65 * point it wont know anymore what to construct. A sequence of <code>UIFactory::purgeInstance()</code>,
66 * <code>UIFactory::makeUserInterface()</code> and <code>UIFactory::getInstance()</code> will work
67 * though.
68 *
69 * In order to make life easier and propagate changes to the singleton mechanism to all those
70 * classes, there is a simple framework class that can be used to make any other class a
71 * singleton through inheritance. This class can be found in the Pattern directory.
72 *
73 * <h2>How to make a class Singleton</h2>
74 *
75 * Most of the time you will only need singletons that don't require additional
76 * information for creation. So I will cover the basic case for constructing singletons
77 * first and then explain what has to be changed to make it accept special parameters.
78 * Singletons are created by inheriting from the <code>Singleton<class T></code> template
79 * using the Curiously recurring template pattern (CRTP). What this means is, that the
80 * class they inherit from carries the inheriting class as a template parameter. For example
81 * <code>class MySingletonExaple : public Singleton<MySingletonExample>{...}</code>. If you
82 * want to know more about this idiom have a look at the
83 * <A HREF="http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern">wikipedia
84 * page for this idiom</A>, but don't worry if you don't quite get how this works for now, for
85 * the use of the singleton framework this is not important.
86 *
87 * If you want to make a class a singleton you can use the following sequence of steps.
88 *
89 * - Inherit from the singleton pattern using the CRTP as above:<br>
90 * @code
91 * class MySingletonExaple : public Singleton<MySingletonExample>{ ...}
92 * @endcode
93 * - Make constructor and destructor private to avoid creation or destruction from
94 * outside the class:<br>
95 * @code
96 * class MySingletonExaple : public Singleton<MySingletonExample>{
97 * private:
98 * MySingletonExample();
99 * ~MySingletonExample();
100 * ...}
101 * @endcode
102 * - give the inherited class access to the class internals using a friend declaration:<br>
103 * @code
104 * class MySingletonExaple : public Singleton<MySingletonExample>{
105 * friend class Singleton<MySingletonExample>; // don't forget the template parameters here
106 * private:
107 * MySingletonExample();
108 * ~MySingletonExample();
109 * ...}
110 * @endcode
111 *
112 * - include the file "Singleton_impl.hpp" that carries the implementation details of
113 * the singleton functions in your implementation file of the class.
114 * - make the compiler construct the template instantiations. For this you can use the defined
115 * keyword <code>CONSTRUCT_SINGLETON(name)</code> at any toplevel point in the implementation
116 * file:<br>
117 * @code
118 * void MySingletonExample::foo(){...}
119 * void MySingletonExample::bar(){...}
120 * CONSTRUCT_SINGLETON(MySingletonExample) // no ; after this
121 * @endcode
122 *
123 * <h3>Singleton with initialization parameters</h3>
124 *
125 * Sometimes it is necessary for a singleton to be passed some initilization parameters. For
126 * example the UIFactory mentioned above needs to know what kind of user interface it has to
127 * produce. Making a singleton that takes initialization parameters is only sligtly different
128 * from the steps lined out above. Here are all the differences:
129 *
130 * - pass an extra <code>false</code> to the template to deactivate the standard instantiation
131 * mechanism
132 * - write a method that handles the special parameters and instantiation. In this method you
133 * can use the <code>setInstance(T*)</code> method inherited from the singleton pattern to set
134 * the created instance. The <code>setInstance()</code> method will only work when the
135 * <code>false<code> template parameter has been set and produce errors otherwise.
136 *
137 */
138template <class T, bool _may_create=true>
139class Singleton
140{
141private:
142 /**
143 * simple auto_ptr that is used by Singleton template
144 *
145 * This ptr_t allows destruction of the object using a private destructor,
146 * when only the Singleton pattern is friend with the class
147 *
148 * All methods have similar semantics to auto_ptr
149 */
150 class ptr_t {
151 public:
152 ptr_t();
153 ptr_t(T* _content);
154 ~ptr_t();
155 T& operator*();
156 T* get();
157 void reset(T* _content);
158 void reset();
159 ptr_t& operator=(const ptr_t& rhs);
160 private:
161 mutable T* content;
162 };
163
164 /**
165 * This object handles the actual creation inside the singleton
166 *
167 * Using template specialization this will allways know what it can
168 * do or cannot do at compile time
169 */
170 template<class creator_T, bool creator_may_create>
171 struct creator_t {
172 inline static creator_T* make();
173 inline static void set(creator_T*&,creator_T*);
174 };
175
176 // specialization to allow fast creations
177
178 /**
179 * Specialized template that allows automatic construction only
180 */
181 template<class creator_T>
182 struct creator_t<creator_T,true>{
183 inline static creator_T* make(){
184 return new creator_T();
185 }
186
187 inline static void set(creator_T*&,creator_T*){
188 ASSERT(0, "Cannot set the Instance for a singleton of this type");
189 }
190 };
191
192 /**
193 * specialized template that allows setting only
194 */
195 template<class creator_T>
196 struct creator_t<creator_T,false>{
197 inline static creator_T* make(){
198 ASSERT(0, "Cannot create a singleton of this type directly");
199 return 0;
200 }
201 inline static void set(ptr_t& dest,creator_T* src){
202 dest.reset(src);
203 }
204 };
205
206 // this is used for creation
207 typedef creator_t<T,_may_create> creator; //< the creator used
208
209public:
210 // make the state of this singleton accessible
211 static const bool may_create=_may_create; //!< the type of singleton that we have
212
213 /**
214 * returns the instance of this Singleton as a reference
215 *
216 * If no Singleton exists at this point and we are allowed to create one
217 * a new one is created and stored inside the singleton
218 *
219 * If no automatic creation is allowed, make sure to create an instance first
220 * using the appropriate methods of the derived class. Otherwise this method
221 * would fail.
222 */
223 static T& getInstance();
224
225 /**
226 * returns the instance of this Singleton as a reference
227 *
228 * If no Singleton exists at this point and we are allowed to create one
229 * a new one is created and stored inside the singleton
230 *
231 * If no automatic creation is allowed, make sure to create an instance first
232 * using the appropriate methods of the derived class. Otherwise this method
233 * would fail.
234 */
235 static const T& getConstInstance();
236
237 /**
238 * returns the instance of this Singleton as a reference inside a mutex-locked
239 * unique ptr.
240 *
241 * If no Singleton exists at this point and we are allowed to create one
242 * a new one is created and stored inside the singleton. If the mutex is locked,
243 * the function will wait until the mutex is released. This can be used to
244 * ensure atomic access to the static instance.
245 */
246 static AtomicInstance<T> getLockedInstance();
247
248 /**
249 * returns the instance of this singleton as a pointer
250 *
251 * If no Singleton exists at this point and we are allowed to create one
252 * a new one is created and stored inside the singleton.
253 *
254 * If no automatic creation is allowed, make sure to create an instance first
255 * using the appropriate methods of the derived class. Otherwise this method
256 * would fail.
257 */
258 static T* getPointer();
259
260 /**
261 * returns the instance of this singleton as a pointer
262 *
263 * If no Singleton exists at this point and we are allowed to create one
264 * a new one is created and stored inside the singleton.
265 *
266 * If no automatic creation is allowed, make sure to create an instance first
267 * using the appropriate methods of the derived class. Otherwise this method
268 * would fail.
269 */
270 static const T* getConstPointer();
271
272 /**
273 * destroys the current instance of this singleton
274 */
275 static void purgeInstance();
276
277 /**
278 * destroys the current instance of the singleton and immidiately constructs
279 * a new one. Similar to using <code>purgeInstance()</code> and <code>getInstance()</code>
280 * but plays more nicely when observers are present. Especially the new instance is created
281 * before the old one is destroyed so observers can switch their targets, when they are notified
282 * of the destruction.
283 *
284 * If no automatic creation is allowed this method wont work.
285 */
286 static T& resetInstance();
287
288protected:
289 /**
290 * Method used to set the instance, when no automatic creation is allowed.
291 *
292 * Call this after the instantiation method in the derived class has created
293 * it's instance and want's the singleton mechanism to keep it around for later
294 * use.
295 *
296 * This method will always fail when automatic creation is enabled.
297 */
298 static void setInstance(T*);
299
300
301 /**
302 * empty constructor to allow creation of subclases
303 */
304 Singleton();
305
306private:
307 /**
308 * the copy constructor is private to avoid accidental copying of Singletons, for example
309 * when passing singletons to functions by value instead of by reference. If you
310 * need copying of singletons call the default constructor in the copy constructor
311 * of the derived object. The copyied object wont be known to the singleton mechanism.
312 */
313 Singleton(const Singleton&);
314
315 static boost::recursive_mutex instanceLock; //!< a lock for the pointer of the instance
316 static ptr_t theInstance; //!< the actual instance of the singleton
317};
318
319#endif /* SINGLETON_HPP_ */
Note: See TracBrowser for help on using the repository browser.