mirror of
https://github.com/aantron/better-enums.git
synced 2025-12-06 16:56:42 +08:00
Eliminated dynamic allocation.
When compile-time stringized constant name trimming is disabled (off by default), trimming happens "lazily" - the first time the user calls a function such as _to_string, the function allocates space for trimmed constant names and trims them there. With this change, space is reserved statically in a writeable char array, and trimming happens in that array instead.
This commit is contained in:
parent
98232ee4fb
commit
74b3a66284
40
enum.h
40
enum.h
@ -436,17 +436,20 @@ _namesMatchNocase(const char *stringizedName, const char *referenceName,
|
||||
}
|
||||
|
||||
inline void _trim_names(const char * const *raw_names,
|
||||
const char **trimmed_names, std::size_t count)
|
||||
const char **trimmed_names,
|
||||
char *storage, std::size_t count)
|
||||
{
|
||||
std::size_t offset = 0;
|
||||
|
||||
for (std::size_t index = 0; index < count; ++index) {
|
||||
std::size_t length =
|
||||
trimmed_names[index] = storage + offset;
|
||||
|
||||
std::size_t trimmed_length =
|
||||
std::strcspn(raw_names[index], BETTER_ENUMS__NAME_ENDERS);
|
||||
char *trimmed = new char[length + 1];
|
||||
storage[offset + trimmed_length] = '\0';
|
||||
|
||||
std::strncpy(trimmed, raw_names[index], length);
|
||||
trimmed[length] = '\0';
|
||||
|
||||
trimmed_names[index] = trimmed;
|
||||
std::size_t raw_length = std::strlen(raw_names[index]);
|
||||
offset += raw_length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -554,6 +557,14 @@ constexpr const char *_final_ ## index = \
|
||||
BETTER_ENUMS__PP_MAP( \
|
||||
BETTER_ENUMS__STRINGIZE_SINGLE, ignored, __VA_ARGS__))
|
||||
|
||||
#define BETTER_ENUMS__RESERVE_STORAGE_SINGLE(ignored, index, expression) \
|
||||
#expression ","
|
||||
|
||||
#define BETTER_ENUMS__RESERVE_STORAGE(...) \
|
||||
BETTER_ENUMS__ID( \
|
||||
BETTER_ENUMS__PP_MAP( \
|
||||
BETTER_ENUMS__RESERVE_STORAGE_SINGLE, ignored, __VA_ARGS__))
|
||||
|
||||
|
||||
|
||||
// TODO Convert integral to underlying only at the last possible moment, if the
|
||||
@ -902,6 +913,13 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
||||
return value; \
|
||||
} \
|
||||
\
|
||||
inline char* name_storage() \
|
||||
{ \
|
||||
static char storage[] = \
|
||||
BETTER_ENUMS__ID(BETTER_ENUMS__RESERVE_STORAGE(__VA_ARGS__)); \
|
||||
return storage; \
|
||||
} \
|
||||
\
|
||||
inline const char** name_array() \
|
||||
{ \
|
||||
static const char *value[Enum::_size]; \
|
||||
@ -924,6 +942,13 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
||||
return the_raw_names; \
|
||||
} \
|
||||
\
|
||||
inline char* name_storage() \
|
||||
{ \
|
||||
static char storage[] = \
|
||||
BETTER_ENUMS__ID(BETTER_ENUMS__RESERVE_STORAGE(__VA_ARGS__)); \
|
||||
return storage; \
|
||||
} \
|
||||
\
|
||||
inline const char** name_array() \
|
||||
{ \
|
||||
static const char *value[Enum::_size]; \
|
||||
@ -976,6 +1001,7 @@ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \
|
||||
\
|
||||
::better_enums::_trim_names(BETTER_ENUMS__NS(Enum)::raw_names(), \
|
||||
BETTER_ENUMS__NS(Enum)::name_array(), \
|
||||
BETTER_ENUMS__NS(Enum)::name_storage(), \
|
||||
_size); \
|
||||
\
|
||||
BETTER_ENUMS__NS(Enum)::initialized() = true; \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user