summaryrefslogtreecommitdiff
path: root/Client/ThirdParty/StaticConstructor/include/StaticConstructor.h
blob: 22310bd921cc676bee11e52853c0efaff544b7cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//////////////////////////////////////////////////////////////////////////////
// AUTHOR:      Hugo González Castro
// TITLE:       Static Constructor in C++
// DESCRIPTION: An easy way to implement static constructors and
//              static destructors in standard C++.
// VERSION:     v1.2 - 2011/11/27
// LICENSE:     CPOL (Code Project Open License).
//              Please, do not remove nor modify this header.
// URL:         http://www.codeproject.com/KB/cpp/StaticConstructor.aspx
//////////////////////////////////////////////////////////////////////////////
#ifndef _STATIC_CONSTRUCTOR_H_
#define _STATIC_CONSTRUCTOR_H_



//////////////////////////////////////////////////////////////////////////////
// DECLARATIONS (macros to use):
//////////////////////////////////////////////////////////////////////////////


// REQUIRED macro to invoke the static constructor/destructor of a class:
// place the call to this macro out of the definition of the class, in a .CPP file
// (avoid using it in .H files unless they are included only once).
// Make sure you put this AFTER the initialization of the static data members!
// For templates, should be called with alias (typedef) for the template instaces.
//////////////////////////////////////////////////////////////////////////////
#define INVOKE_STATIC_CONSTRUCTOR(ClassName) \
		INVOKE_STATIC_CONSTRUCTOR_EXPANDED(ClassName)


// OPTIONAL macros to help to declare the header of the static constructor/destructor:
// place the calls to these macros inside the definition of the class/template, in a .H file
//////////////////////////////////////////////////////////////////////////////
#define STATIC_CONSTRUCTOR()  static void StaticConstructor()
#define STATIC_DESTRUCTOR()   static void StaticDestructor()


// OPTIONAL macro to declare static Data-Function members with inline initialization:
// place the call to this macro inside the definition of the class/template.
//////////////////////////////////////////////////////////////////////////////
// STATIC DF MEMBER (static Data-Function member):
// "a static function member with a static local (data) variable declared inside".
// The TypeName can be or not a CONST type.
//////////////////////////////////////////////////////////////////////////////
#define STATIC_DF_MEMBER(TypeName, DFMemberName, InitValue) \
		STATIC_DF_MEMBER_EXPANDED(TypeName, DFMemberName, InitValue)


// OPTIONAL macros to run code at startup and finishup. Place outside classes.
// Place the static code inside {} after one of these macros.
//////////////////////////////////////////////////////////////////////////////
#define STATIC_STARTUP_CODE()   STATIC_STARTUP_CODE_EXPANDED()
#define STATIC_FINISHUP_CODE()  STATIC_FINISHUP_CODE_EXPANDED()



//////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION (do not directly use these macros):
//////////////////////////////////////////////////////////////////////////////


// Definition of special class to invoke
// the static constructor/destructor from
// its own non-static constructor/destructor.
template<typename ClassName>
class StaticInvoker
{
public:
	// Default Constructor:
	StaticInvoker()
	{
		// Call to the static constructor of ClassName:
		ClassName::StaticConstructor();
	}

	// Destructor:
	virtual ~StaticInvoker()
	{
		// Call to the static destructor of ClassName:
		ClassName::StaticDestructor();
	}
};


// Macro with expanded name:
#define INVOKE_STATIC_CONSTRUCTOR_EXPANDED(ClassName) \
		/* Single instance of this invoker class, so its constructor is called only once */ \
		StaticInvoker<ClassName> staticInvokerOf_##ClassName;


// STATIC DF MEMBER (static Data-Function member):
// "a static function member with a static local (data) variable declared inside".
// The TypeName can be or not a CONST type.
#define STATIC_DF_MEMBER_EXPANDED(TypeName, DFMemberName, InitValue) \
		static TypeName& DFMemberName() \
		{ \
			static TypeName DFMemberName(InitValue); \
			return DFMemberName; \
		}


// Expanded macro to run code at startup.
#define STATIC_STARTUP_CODE_EXPANDED() \
		class StartUpCode \
		{ \
		public: \
			StartUpCode(); \
		}; \
		StartUpCode myStartUpCode; \
		StartUpCode::StartUpCode()


// Expanded macro to run code at finishup.
#define STATIC_FINISHUP_CODE_EXPANDED() \
		class FinishUpCode \
		{ \
		public: \
			FinishUpCode() {}; \
			virtual ~FinishUpCode(); \
		}; \
		FinishUpCode myFinishUpCode; \
		FinishUpCode::~FinishUpCode()



#endif // _STATIC_CONSTRUCTOR_H_