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