blocxx
src
blocxx
LazyGlobal.hpp
Go to the documentation of this file.
1
/*******************************************************************************
2
* Copyright (C) 2005, Quest Software, Inc. All rights reserved.
3
* Copyright (C) 2006, Novell, Inc. All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
7
*
8
* * Redistributions of source code must retain the above copyright notice,
9
* this list of conditions and the following disclaimer.
10
* * Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* * Neither the name of
14
* Quest Software, Inc.,
15
* nor Novell, Inc.,
16
* nor the names of its contributors or employees may be used to
17
* endorse or promote products derived from this software without
18
* specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
* POSSIBILITY OF SUCH DAMAGE.
31
*******************************************************************************/
32
33
38
39
#ifndef BLOCXX_LAZY_GLOBAL_HPP_INCLUDE_GUARD_
40
#define BLOCXX_LAZY_GLOBAL_HPP_INCLUDE_GUARD_
41
42
#include "blocxx/BLOCXX_config.h"
43
#include "
blocxx/ThreadOnce.hpp
"
44
#include "
blocxx/GlobalPtr.hpp
"
45
46
#ifdef BLOCXX_HAVE_STD_TR1_IS_POD
47
#include "
blocxx/StaticAssert.hpp
"
48
49
#include <tr1/type_traits>
50
#endif
51
52
namespace
BLOCXX_NAMESPACE
53
{
54
55
template
<
typename
T,
typename
PODType>
56
struct
DefaultVariableConstructorFactory
57
{
58
static
T*
create
(
const
PODType& t)
59
{
60
return
new
T(t);
61
}
62
};
63
113
template
<
typename
T,
typename
PODType,
typename
FactoryT = DefaultVariableConstructorFactory<T, PODType> >
114
class
LazyGlobal
115
{
116
#ifdef BLOCXX_HAVE_STD_TR1_IS_POD
117
BLOCXX_STATIC_ASSERT
(std::tr1::is_pod<PODType>::value);
118
#endif
119
private
:
120
struct
InitPtr
121
{
122
InitPtr
(T*& p,
const
PODType& str)
123
:
m_p
(p)
124
,
m_pod
(str)
125
{ }
126
T*&
m_p
;
127
const
PODType&
m_pod
;
128
129
void
operator()
()
130
{
131
m_p
=
static_cast<
T*
>
(FactoryT::create(
m_pod
));
132
}
133
};
134
135
T*
getPtr
()
const
136
{
137
callOnce
(
m_onceFlag
, InitPtr(
m_p
,
m_pod
));
138
return
m_p
;
139
}
140
141
public
:
142
~LazyGlobal
()
143
{
144
delete
m_p
;
145
// reset these variables in case get() is called after the destructor runs.
146
m_p
= 0;
147
OnceFlag tmp = BLOCXX_ONCE_INIT;
148
m_onceFlag
= tmp;
149
}
150
151
T&
get
()
const
152
{
153
callOnce
(
m_onceFlag
, InitPtr(
m_p
,
m_pod
));
154
return
*
m_p
;
155
}
156
157
// The two different operators are defined because there may be some
158
// global variables marked as const. We'll want them treated
159
// differently.
160
operator
T&()
161
{
162
return
get
();
163
}
164
165
operator
const
T&()
const
166
{
167
return
get
();
168
}
169
170
template
<
typename
T2>
171
T&
operator=
(
const
T2& rhs)
172
{
173
// checking for self assignment is handled by type T
174
return
(
get
() = rhs);
175
}
176
177
// These members should be treated as private. They aren't marked private
178
// because if they are, POD initializer syntax can't be used.
179
PODType
m_pod
;
180
mutable
T*
m_p
;
181
mutable
OnceFlag
m_onceFlag
;
182
};
183
188
#define BLOCXX_LAZY_GLOBAL_INIT(...) { __VA_ARGS__, 0, BLOCXX_ONCE_INIT }
189
190
}
// end namespace BLOCXX_NAMESPACE
191
192
193
#endif
GlobalPtr.hpp
StaticAssert.hpp
BLOCXX_STATIC_ASSERT
#define BLOCXX_STATIC_ASSERT(B)
Definition
StaticAssert.hpp:55
ThreadOnce.hpp
BLOCXX_NAMESPACE::LazyGlobal
This class can be used to store a global variable that is lazily initialized in a thread safe manner.
Definition
LazyGlobal.hpp:115
BLOCXX_NAMESPACE::LazyGlobal< Mutex, int, GlobalMutexFactory >::m_pod
int m_pod
Definition
LazyGlobal.hpp:179
BLOCXX_NAMESPACE::LazyGlobal< Mutex, int, GlobalMutexFactory >::m_p
Mutex * m_p
Definition
LazyGlobal.hpp:180
BLOCXX_NAMESPACE::LazyGlobal::getPtr
T * getPtr() const
Definition
LazyGlobal.hpp:135
BLOCXX_NAMESPACE::LazyGlobal::get
T & get() const
Definition
LazyGlobal.hpp:151
BLOCXX_NAMESPACE::LazyGlobal::operator=
T & operator=(const T2 &rhs)
Definition
LazyGlobal.hpp:171
BLOCXX_NAMESPACE::LazyGlobal< Mutex, int, GlobalMutexFactory >::m_onceFlag
OnceFlag m_onceFlag
Definition
LazyGlobal.hpp:181
BLOCXX_NAMESPACE::LazyGlobal::~LazyGlobal
~LazyGlobal()
Definition
LazyGlobal.hpp:142
BLOCXX_NAMESPACE
Taken from RFC 1321.
Definition
AppenderLogger.cpp:48
BLOCXX_NAMESPACE::callOnce
void BLOCXX_COMMON_API callOnce(OnceFlag &flag, FuncT F)
The first time callOnce is called with a given onceFlag argument, it calls func with no argument and ...
BLOCXX_NAMESPACE::DefaultVariableConstructorFactory
Definition
LazyGlobal.hpp:57
BLOCXX_NAMESPACE::DefaultVariableConstructorFactory::create
static T * create(const PODType &t)
Definition
LazyGlobal.hpp:58
BLOCXX_NAMESPACE::LazyGlobal::InitPtr::InitPtr
InitPtr(T *&p, const PODType &str)
Definition
LazyGlobal.hpp:122
BLOCXX_NAMESPACE::LazyGlobal::InitPtr::m_p
T *& m_p
Definition
LazyGlobal.hpp:126
BLOCXX_NAMESPACE::LazyGlobal::InitPtr::m_pod
const PODType & m_pod
Definition
LazyGlobal.hpp:127
BLOCXX_NAMESPACE::LazyGlobal::InitPtr::operator()
void operator()()
Definition
LazyGlobal.hpp:129
Generated by
1.13.1