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##Initializer;
95
96
#define SYSimplementStaticObject(NAME,TYPE) \
97
static int NAME##StaticInitCounter = 0; \
98
static TYPE * NAME = NULL; \
99
NAME##StaticInit::NAME##StaticInit () \
100
{ \
101
if (0 == NAME##StaticInitCounter++) \
102
NAME = new TYPE(); \
103
} \
104
NAME##StaticInit::~NAME##StaticInit () \
105
{ \
106
if (0 == --NAME##StaticInitCounter) \
107
delete NAME; \
108
}
109
110
#define SYSdeclareStaticInit(API,NAME) \
111
static class API NAME##StaticInit { \
112
public: \
113
NAME##StaticInit (); \
114
~NAME##StaticInit (); \
115
} NAME##Initializer;
116
117
#define SYSimplementStaticInit(NAME) \
118
static int NAME##StaticInitCounter = 0; \
119
NAME##StaticInit::NAME##StaticInit () \
120
{ \
121
if (0 == NAME##StaticInitCounter++) \
122
NAME##Init(); \
123
} \
124
NAME##StaticInit::~NAME##StaticInit () \
125
{ \
126
if (0 == --NAME##StaticInitCounter) \
127
NAME##CleanUp(); \
128
}
129
130
/// @}
131
132
/// @brief Class to help deal with the "static initialization order fiasco"
133
///
134
/// Please see: http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
135
///
136
/// For example, something like @code
137
/// static UT_SymbolMap<void *> theTable;
138
///
139
/// void addSymbol(const char *n, void *v) { theTable.addSymbol(n, v); }
140
/// void delSymbol(const char *n) { theTable.deleteSymbol(n);
141
/// @endcode;
142
/// may cause problems if the @c addSymbol() method or the @c delSymbol()
143
/// method are called @b when the table isn't constructed (i.e. before
144
/// construction, after destruction). This can happen if there's another
145
/// static object which has @c addSymbol() or @c delSymbol() in the code path
146
/// of its static destructor.
147
///
148
/// The way to "fix" this is to use the SYS_StaticInit class @code
149
/// static SYS_StaticInit<UT_SymbolMap<void *>> theTable;
150
///
151
/// void addSymbol(const char *n, void *v) { theTable->addSymbol(n, v); }
152
/// void delSymbol(const char *n) { theTable->deleteSymbol(n);
153
/// @endcode;
154
/// @note The object will not be destructed (so there will be a memory leak)
155
/// @note The data object is created on first access. This means that it may
156
/// not be 100% thread-safe. Passing @c create == @c true in the
157
/// constructor can cause initial
158
159
#if defined(__cplusplus)
160
#include "
SYS_Types.h
"
161
162
template
<
typename
T>
163
class
SYS_StaticInit {
164
public
:
165
///
166
SYS_StaticInit(
bool
create_on_construction=
false
)
167
{
168
if
(create_on_construction)
169
get
();
170
}
171
~SYS_StaticInit()
172
{
173
}
174
175
/// Allocate the object if needed.
176
T
*
get
()
177
{
178
static
T
*theObject = NULL;
179
if
(!theObject)
180
theObject =
new
T
();
181
return
theObject;
182
}
183
/// Accessor methods
184
T
&
operator*
() {
return
*
get
(); }
185
T
*operator->() {
return
get
(); }
186
private
:
187
};
188
#endif
189
190
#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 Tue Sep 26 2023 02:47:40 for HDK by
1.8.6