source: src/CodePatterns/Singleton_impl.hpp@ 163eec

Last change on this file since 163eec was 163eec, checked in by Frederik Heber <heber@…>, 10 years ago

Added Singleton:getConstInstance() and ..Pointer() functions.

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Singleton_impl.hpp
3 *
4 * Created on: Mar 10, 2010
5 * Author: crueger
6 */
7
8#ifndef SINGLETON_IMPL_HPP_
9#define SINGLETON_IMPL_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include "CodePatterns/Assert.hpp"
17#include "CodePatterns/Singleton.hpp"
18
19/****** Static instance Variables of the template *******/
20
21template <class T,bool _may_create>
22typename Singleton<T,_may_create>::ptr_t Singleton<T,_may_create>::theInstance(0);
23
24template <class T,bool _may_create>
25boost::recursive_mutex Singleton<T,_may_create>::instanceLock;
26
27/****** templates singleton creation and destruction functions ******/
28
29template <class T,bool _may_create>
30T& Singleton<T,_may_create>::getInstance(){
31 // boost supports RAII-Style locking, so we don't need to unlock
32 boost::recursive_mutex::scoped_lock guard(instanceLock);
33 if(!theInstance.get()) {
34 theInstance.reset(creator::make());
35 }
36 return *theInstance;
37}
38
39template <class T,bool _may_create>
40const T& Singleton<T,_may_create>::getConstInstance(){
41 // boost supports RAII-Style locking, so we don't need to unlock
42 boost::recursive_mutex::scoped_lock guard(instanceLock);
43 if(!theInstance.get()) {
44 theInstance.reset(creator::make());
45 }
46 return *theInstance;
47}
48
49template <class T,bool _may_create>
50T* Singleton<T,_may_create>::getPointer(){
51 // boost supports RAII-Style locking, so we don't need to unlock
52 boost::recursive_mutex::scoped_lock guard(instanceLock);
53 if(!theInstance.get()) {
54 theInstance.reset(creator::make());
55 }
56 return theInstance.get();
57
58}
59
60template <class T,bool _may_create>
61const T* Singleton<T,_may_create>::getConstPointer(){
62 // boost supports RAII-Style locking, so we don't need to unlock
63 boost::recursive_mutex::scoped_lock guard(instanceLock);
64 if(!theInstance.get()) {
65 theInstance.reset(creator::make());
66 }
67 return theInstance.get();
68
69}
70
71template <class T,bool _may_create>
72void Singleton<T,_may_create>::purgeInstance(){
73 // boost supports RAII-Style locking, so we don't need to unlock
74 boost::recursive_mutex::scoped_lock guard(instanceLock);
75 theInstance.reset();
76}
77
78template <class T,bool _may_create>
79T& Singleton<T,_may_create>::resetInstance(){
80 ptr_t oldInstance;
81 {
82 // boost supports RAII-Style locking, so we don't need to unlock
83 boost::recursive_mutex::scoped_lock guard(instanceLock);
84
85 oldInstance = theInstance;
86 theInstance.reset(creator::make());
87 // oldworld does not need protection any more,
88 // since we should have the only reference
89
90 // worldLock handles access to the pointer,
91 // not to the object
92 } // scope-end releases the lock
93
94 // oldInstance goes out of scope at the End of this function. The carried object will then be destroyed by the auto_ptr
95 return *theInstance;
96}
97
98
99template <class T,bool _may_create>
100void Singleton<T,_may_create>::setInstance(T* newInstance){
101 ASSERT(!theInstance.get(), "Trying to set the instance of an already created singleton");
102 boost::recursive_mutex::scoped_lock guard(instanceLock);
103 theInstance.reset(newInstance);
104}
105
106template<class T, bool _may_create>
107Singleton<T,_may_create>::Singleton(){/* empty */}
108
109// private copy constructor to avoid unintended copying
110template <class T, bool _may_create>
111Singleton<T,_may_create>::Singleton(const Singleton<T,_may_create>&){
112 ASSERT(0, "Copy constructor of singleton template called");
113}
114
115/**
116 * This define allows simple instantiation of the necessary singleton functions
117 * at a chosen place.
118 */
119#define CONSTRUCT_SINGLETON(name) \
120 template name& Singleton< name , name::may_create >::getInstance(); \
121 template const name& Singleton< name , name::may_create >::getConstInstance(); \
122 template name* Singleton< name , name::may_create >::getPointer(); \
123 template const name* Singleton< name , name::may_create >::getConstPointer(); \
124 template void Singleton< name , name::may_create >::purgeInstance(); \
125 template name& Singleton< name , name::may_create >::resetInstance(); \
126 template void Singleton< name , name::may_create >::setInstance( name* );
127
128/************ Internal Pointer Wrapper to allow automatic purging *************/
129
130template <class T,bool _may_create>
131Singleton<T,_may_create>::ptr_t::ptr_t() :
132content(0){};
133
134template <class T,bool _may_create>
135Singleton<T,_may_create>::ptr_t::ptr_t(T* _content) :
136content(_content){};
137
138template <class T,bool _may_create>
139Singleton<T,_may_create>::ptr_t:: ~ptr_t()
140{delete content;};
141
142template <class T,bool _may_create>
143T& Singleton<T,_may_create>::ptr_t::operator*()
144{return *content;};
145
146template <class T,bool _may_create>
147T* Singleton<T,_may_create>::ptr_t::get()
148{return content;};
149
150template <class T,bool _may_create>
151void Singleton<T,_may_create>::ptr_t::reset(T* _content){
152 delete content;
153 content = _content;
154}
155
156template <class T,bool _may_create>
157void Singleton<T,_may_create>::ptr_t::reset()
158{reset(0);}
159
160template <class T,bool _may_create>
161typename Singleton<T,_may_create>::ptr_t& Singleton<T,_may_create>::ptr_t::operator=(const typename Singleton<T,_may_create>::ptr_t& rhs){
162 if(&rhs!=this){
163 delete content;
164 content = rhs.content;
165 rhs.content = 0;
166 }
167 return *this;
168}
169
170
171#endif /* SINGLETON_IMPL_HPP_ */
Note: See TracBrowser for help on using the repository browser.