HDK
Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
SYS_StaticInit.h
Go to the documentation of this file.
1
/*
2
* PROPRIETARY INFORMATION. This software is proprietary to
3
* Side Effects Software Inc., and is not to be reproduced,
4
* transmitted, or disclosed in any way withoSYS_StaticInit written permission.
5
*
6
* NAME: SYS_StaticInit.h (SYS Library, C++)
7
*
8
* COMMENTS:
9
* This file contains defines and classes to help with static initializers.
10
*/
11
12
#ifndef __SYS_StaticInit__
13
#define __SYS_StaticInit__
14
15
/// @{
16
/// Static initializers in C++ are very dangerous and the interactions
17
/// are undefined when one static initializer accesses another statically
18
/// defined object.
19
///
20
/// These macros allow you to use statically initialized objects safely,
21
/// or, to call a static initialization function at startup. As well, these
22
/// macros handle destruction and cleanup when the last users of your
23
/// code have themselved been destructed.
24
///
25
/// To avoid name conflicts, you may need to use descriptive names for
26
/// the static objects. Eg for an instance of a UT_Lock class, instead
27
/// of the name theLock choose theSharedStringLock, when it is used in
28
/// UT_SharedString.C
29
///
30
///
31
/// HOW TO USE:
32
///
33
/// FOR OBJECTS:
34
///
35
/// To have an staticly initialized object that is safe to access from
36
/// other locations during static initialization, do this:
37
///
38
/// DECLARATION:
39
///
40
/// // In the header (.h) do this
41
/// SYSdeclareStaticObject(SYS_API,theFoobar);
42
///
43
/// IMPLEMENTATION
44
///
45
/// // In the implementation (.C) do this
46
/// SYSimplementStaticObject(theFoobar,SYS_Foobar);
47
///
48
/// // Then, later you can to
49
/// theFoobar->doStuff();
50
///
51
///
52
/// FOR FUNCTIONS
53
///
54
/// You can also have just plain initialization and cleanup functions.
55
///
56
/// DECLARATION:
57
///
58
/// // In the header (.h) do this
59
/// SYSdeclareStaticInit(SYS_API,foobar);
60
///
61
/// IMPLEMENTATION
62
///
63
/// // Declare two void functions based on the name you chose
64
/// void foobarInit() {
65
/// // do stuff
66
/// }
67
///
68
/// void foobarCleanUp() {
69
/// // clean up stuff
70
/// }
71
///
72
/// // In the implementation (.C) do this
73
/// SYSimplementStaticInit(foobar);
74
///
75
/// HOW DOES THIS WORK?
76
///
77
/// This works because a small statically initialized object is inserted
78
/// into each .C file that includes your header. That little object uses
79
/// reference counting to ensure that your static initialization is done
80
/// the first time a .o file that references your code is statically
81
/// initialized.
82
///
83
/// That reference counting also makes sure that your static stuff is
84
/// cleaned up when all .o's containing references have had their static
85
/// destructors run.
86
///
87
///
88
89
#define SYSdeclareStaticObject(API,NAME) \
90
static class API NAME##StaticInit { \
91
public: \
92
NAME##StaticInit (); \
93
~NAME##StaticInit (); \
94
NAME##StaticInit (const NAME##StaticInit &) = delete; \
95
NAME##StaticInit &operator=(const NAME##StaticInit &) = delete; \
96
} NAME##Initializer;
97
98
#define SYSimplementStaticObject(NAME,TYPE) \
99
static int NAME##StaticInitCounter = 0; \
100
static TYPE * NAME = NULL; \
101
NAME##StaticInit::NAME##StaticInit () \
102
{ \
103
if (0 == NAME##StaticInitCounter++) \
104
NAME = new TYPE(); \
105
} \
106
NAME##StaticInit::~NAME##StaticInit () \
107
{ \
108
if (0 == --NAME##StaticInitCounter) \
109
delete NAME; \
110
}
111
112
#define SYSdeclareStaticInit(API,NAME) \
113
static class API NAME##StaticInit { \
114
public: \
115
NAME##StaticInit (); \
116
~NAME##StaticInit (); \
117
NAME##StaticInit (const NAME##StaticInit &) = delete; \
118
NAME##StaticInit &operator=(const NAME##StaticInit &) = delete; \
119
} NAME##Initializer;
120
121
#define SYSimplementStaticInit(NAME) \
122
static int NAME##StaticInitCounter = 0; \
123
NAME##StaticInit::NAME##StaticInit () \
124
{ \
125
if (0 == NAME##StaticInitCounter++) \
126
NAME##Init(); \
127
} \
128
NAME##StaticInit::~NAME##StaticInit () \
129
{ \
130
if (0 == --NAME##StaticInitCounter) \
131
NAME##CleanUp(); \
132
}
133
134
/// @}
135
136
/// @brief Class to help deal with the "static initialization order fiasco"
137
///
138
/// Please see: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
139
///
140
/// For example, something like @code
141
/// static UT_SymbolMap<void *> theTable;
142
///
143
/// void addSymbol(const char *n, void *v) { theTable.addSymbol(n, v); }
144
/// void delSymbol(const char *n) { theTable.deleteSymbol(n);
145
/// @endcode;
146
/// may cause problems if the @c addSymbol() method or the @c delSymbol()
147
/// method are called @b when the table isn't constructed (i.e. before
148
/// construction, after destruction). This can happen if there's another
149
/// static object which has @c addSymbol() or @c delSymbol() in the code path
150
/// of its static destructor.
151
///
152
/// The way to "fix" this is to use the SYS_StaticInit class @code
153
/// static SYS_StaticInit<UT_SymbolMap<void *>> theTable;
154
///
155
/// void addSymbol(const char *n, void *v) { theTable->addSymbol(n, v); }
156
/// void delSymbol(const char *n) { theTable->deleteSymbol(n);
157
/// @endcode;
158
/// @note The object will not be destructed (so there will be a memory leak)
159
/// @note The data object is created on first access. This means that it may
160
/// not be 100% thread-safe. Passing @c create == @c true in the
161
/// constructor can cause initial
162
163
#if defined(__cplusplus)
164
#include "
SYS_Types.h
"
165
166
template
<
typename
T>
167
class
SYS_StaticInit {
168
public
:
169
///
170
SYS_StaticInit(
bool
create_on_construction=
false
)
171
{
172
if
(create_on_construction)
173
get
();
174
}
175
176
/// Allocate the object if needed.
177
T
*
get
()
178
{
179
static
T
*theObject = NULL;
180
if
(!theObject)
181
theObject =
new
T
();
182
return
theObject;
183
}
184
/// Accessor methods
185
T
&
operator*
() {
return
*
get
(); }
186
T
*operator->() {
return
get
(); }
187
private
:
188
};
189
#endif
190
191
#endif
SYS_Types.h
operator*
IMATH_HOSTDEVICE constexpr Color4< T > operator*(S a, const Color4< T > &v) IMATH_NOEXCEPT
Reverse multiplication: S * Color4.
Definition:
ImathColor.h:732
OBJ_MatchTransform::T
SYS
SYS_StaticInit.h
Generated on Sun Nov 17 2024 03:03:31 for HDK by
1.8.6