SGL
gstatic.h
1 /*
2  * File: static.h
3  * --------------
4  * This file provides several macros for declaring static variables and functions
5  * in ways that are safe for usage during the C++ static initiialization phase.
6  * These macros should be used to declare all not-inside-function static data
7  * used by the library, since a lot of library code runs during the
8  * static initialization phase.
9  *
10  * @version 2017/10/05
11  * - added STATIC_VARIABLE_NAMESPACE
12  */
13 
14 #ifndef _static_h
15 #define _static_h
16 
17 // macros for concatenating two macros
18 #ifndef CONCAT_IMPL
19 #define MACRO_CONCAT(a, ...) PRIMITIVE_CONCAT(a, __VA_ARGS__)
20 #define PRIMITIVE_CONCAT(a, ...) a ## __VA_ARGS__
21 #define MACRO_IDENT(x) x
22 #endif // CONCAT_IMPL
23 
24 // declare static var/func and assign it the given value
25 #define STATIC_VARIABLE_DECLARE(type, name, value) \
26  static type & s_##name() { \
27  static type __##name = (value); \
28  return __##name; \
29  }
30 
31 // declare but don't assign a value (use type's default value)
32 #define STATIC_VARIABLE_DECLARE_BLANK(type, name) \
33  static type & s_##name() { \
34  static type __##name; \
35  return __##name; \
36  }
37 
38 // declare static const var/func and assign it the given value
39 #define STATIC_CONST_VARIABLE_DECLARE(type, name, value) \
40  static const type & s_##name() { \
41  static const type __##name = (value); \
42  return __##name; \
43  }
44 
45 // declare static var/func collection and assign it the given elements
46 // (these seem to not work for multi-template collections like Map<K, V> :-/
47 // but they work for single-template collections like Vector<E>)
48 #define STATIC_VARIABLE_DECLARE_COLLECTION(type, name, ...) \
49  static type & s_##name() { \
50  static type __##name = { __VA_ARGS__ }; \
51  return __##name; \
52  }
53 
54 // declare static var/func collection and leave it empty
55 #define STATIC_VARIABLE_DECLARE_COLLECTION_EMPTY(type, name) \
56  static type & s_##name() { \
57  static type __##name; \
58  return __##name; \
59  }
60 
61 #define STATIC_VARIABLE_DECLARE_MAP_EMPTY(maptype, keytype, valuetype, name) \
62  static maptype < keytype , valuetype > & s_##name() { \
63  static maptype < keytype , valuetype > __##name; \
64  return __##name; \
65  }
66 
67 // declare static const var/func collection and assign it the given elements
68 #define STATIC_CONST_VARIABLE_DECLARE_COLLECTION(type, name, ...) \
69  static const type & s_##name() { \
70  static const type __##name { __VA_ARGS__ }; \
71  return __##name; \
72  }
73 
74 // look up the value of the given static variable (by calling its static s_ function)
75 #define STATIC_VARIABLE(name) \
76  (s_##name())
77 
78 // look up the value of the given static variable in another namespace
79 #define STATIC_VARIABLE_NAMESPACE(namespacename, name) \
80  (namespacename::s_##name())
81 
82 #endif // _static_h