mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-07 01:06:42 +08:00
Initialization now always completed before main.
Before this change, in C++98 and C++11 "fast" mode, initializer trimming was done "lazily" the first time _to_string or _names was called. To make performance more "predictable", an object with static storage is now used to force initializaton during program start-up, when static object constructors are called. The benefit of this change is very debatable. I had to give the static object static linkage to avoid duplicate symbols, so there is a copy now in each translation unit. I hope this does not increase code size too much in realistic scenarios. Lazy initialization checks are still performed and cannot be removed, because other objects with static storage may try to use an enum from their constructors before the enum's initialization is forced.
This commit is contained in:
parent
fc609e58aa
commit
a493e90ac4
20
enum.h
20
enum.h
@ -510,6 +510,14 @@ struct underlying_traits {
|
|||||||
are_equal(const T& u, const T& v) { return u == v; }
|
are_equal(const T& u, const T& v) { return u == v; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Eager initialization.
|
||||||
|
template <typename Enum>
|
||||||
|
struct _initialize_at_program_start {
|
||||||
|
_initialize_at_program_start() { Enum::initialize(); }
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace better_enums
|
} // namespace better_enums
|
||||||
|
|
||||||
|
|
||||||
@ -708,11 +716,16 @@ class Enum { \
|
|||||||
_from_string_loop(const char *name, std::size_t index = 0); \
|
_from_string_loop(const char *name, std::size_t index = 0); \
|
||||||
BETTER_ENUMS__CONSTEXPR static _optional_index \
|
BETTER_ENUMS__CONSTEXPR static _optional_index \
|
||||||
_from_string_nocase_loop(const char *name, std::size_t index = 0); \
|
_from_string_nocase_loop(const char *name, std::size_t index = 0); \
|
||||||
|
\
|
||||||
|
friend struct ::better_enums::_initialize_at_program_start<Enum>; \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
namespace better_enums { \
|
namespace better_enums { \
|
||||||
namespace _data_ ## Enum { \
|
namespace _data_ ## Enum { \
|
||||||
\
|
\
|
||||||
|
static ::better_enums::_initialize_at_program_start<Enum> \
|
||||||
|
force_initialization; \
|
||||||
|
\
|
||||||
enum PutNamesInThisScopeAlso { __VA_ARGS__ }; \
|
enum PutNamesInThisScopeAlso { __VA_ARGS__ }; \
|
||||||
\
|
\
|
||||||
BETTER_ENUMS__CONSTEXPR const Enum value_array[] = \
|
BETTER_ENUMS__CONSTEXPR const Enum value_array[] = \
|
||||||
@ -1015,7 +1028,8 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
|||||||
static int initialize();
|
static int initialize();
|
||||||
|
|
||||||
// C++11 slow all-constexpr version
|
// C++11 slow all-constexpr version
|
||||||
#define BETTER_ENUMS__DO_NOT_DECLARE_INITIALIZE
|
#define BETTER_ENUMS__DECLARE_EMPTY_INITIALIZE \
|
||||||
|
static int initialize() { return 0; }
|
||||||
|
|
||||||
// C++98, C++11 fast version
|
// C++98, C++11 fast version
|
||||||
#define BETTER_ENUMS__DO_DEFINE_INITIALIZE(Enum) \
|
#define BETTER_ENUMS__DO_DEFINE_INITIALIZE(Enum) \
|
||||||
@ -1071,7 +1085,7 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
|||||||
# define BETTER_ENUMS__DEFAULT_TO_STRING_KEYWORD \
|
# define BETTER_ENUMS__DEFAULT_TO_STRING_KEYWORD \
|
||||||
BETTER_ENUMS__CONSTEXPR_TO_STRING_KEYWORD
|
BETTER_ENUMS__CONSTEXPR_TO_STRING_KEYWORD
|
||||||
# define BETTER_ENUMS__DEFAULT_DECLARE_INITIALIZE \
|
# define BETTER_ENUMS__DEFAULT_DECLARE_INITIALIZE \
|
||||||
BETTER_ENUMS__DO_NOT_DECLARE_INITIALIZE
|
BETTER_ENUMS__DECLARE_EMPTY_INITIALIZE
|
||||||
# define BETTER_ENUMS__DEFAULT_DEFINE_INITIALIZE \
|
# define BETTER_ENUMS__DEFAULT_DEFINE_INITIALIZE \
|
||||||
BETTER_ENUMS__DO_NOT_DEFINE_INITIALIZE
|
BETTER_ENUMS__DO_NOT_DEFINE_INITIALIZE
|
||||||
# define BETTER_ENUMS__DEFAULT_CALL_INITIALIZE \
|
# define BETTER_ENUMS__DEFAULT_CALL_INITIALIZE \
|
||||||
@ -1112,7 +1126,7 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
|||||||
BETTER_ENUMS__DEFAULT_SWITCH_TYPE_GENERATE, \
|
BETTER_ENUMS__DEFAULT_SWITCH_TYPE_GENERATE, \
|
||||||
BETTER_ENUMS__CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \
|
BETTER_ENUMS__CXX11_FULL_CONSTEXPR_TRIM_STRINGS_ARRAYS, \
|
||||||
BETTER_ENUMS__CONSTEXPR_TO_STRING_KEYWORD, \
|
BETTER_ENUMS__CONSTEXPR_TO_STRING_KEYWORD, \
|
||||||
BETTER_ENUMS__DO_NOT_DECLARE_INITIALIZE, \
|
BETTER_ENUMS__DECLARE_EMPTY_INITIALIZE, \
|
||||||
BETTER_ENUMS__DO_NOT_DEFINE_INITIALIZE, \
|
BETTER_ENUMS__DO_NOT_DEFINE_INITIALIZE, \
|
||||||
BETTER_ENUMS__DO_NOT_CALL_INITIALIZE, \
|
BETTER_ENUMS__DO_NOT_CALL_INITIALIZE, \
|
||||||
Enum, Underlying, __VA_ARGS__))
|
Enum, Underlying, __VA_ARGS__))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user