Skip to content

Commit

Permalink
Support NamedEnum constructor from string when names are not ordered
Browse files Browse the repository at this point in the history
  • Loading branch information
dc42 committed Dec 13, 2021
1 parent 947b130 commit c191b73
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 19 deletions.
21 changes: 4 additions & 17 deletions src/General/NamedEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,12 @@
// Function to search the table of names for a match. Returns numNames if not found.
unsigned int NamedEnumLookup(const char *_ecv_array s, const char *_ecv_array const names[], size_t numNames) noexcept
{
unsigned int low = 0, high = numNames;
while (high > low)
unsigned int i = 0;
while (i < numNames && strcmp(s, SkipLeadingUnderscore(names[i])) != 0)
{
const size_t mid = (high - low)/2 + low;
const int t = strcmp(s, SkipLeadingUnderscore(names[mid]));
if (t == 0)
{
return mid;
}
if (t > 0)
{
low = mid + 1u;
}
else
{
high = mid;
}
++i;
}
return (low < numNames && strcmp(s, SkipLeadingUnderscore(names[low])) == 0) ? low : numNames;
return i;
}

// End
3 changes: 1 addition & 2 deletions src/General/NamedEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ static inline const char * _ecv_array SkipLeadingUnderscore(const char * _ecv_ar
// printf("%s", myCar.ToString());
//
// If any of the names is a C++ reserved word or starts with a digit, prefix it with a single underscore
// IMPORTANT! If the constructor from string is used then the names must be in alphabetical order (ignoring the leading underscore) because it uses a binary search
// BaseType must be unsigned for IsValid and ToString to work correctly.

#define NamedEnum(_typename, _baseType, _v1, ...) \
Expand All @@ -104,7 +103,7 @@ public: \
static constexpr unsigned int NumValues = VA_SIZE(__VA_ARGS__) + 1; /* count of members */ \
_typename(RawType arg) noexcept { v = arg; } /* constructor - cannot be declared 'explicit' because we need the conversion */ \
explicit _typename(BaseType arg) noexcept { v = static_cast<RawType>(arg); } /* constructor */ \
explicit _typename(const char * _ecv_array s) noexcept { v = static_cast<RawType>(NamedEnumLookup(s, _names, NumValues)); } /* constructor from string - NAMES MUST BE ORDERED when using this */ \
explicit _typename(const char * _ecv_array s) noexcept { v = static_cast<RawType>(NamedEnumLookup(s, _names, NumValues)); } /* constructor from string */ \
_typename(const _typename& arg) noexcept { v = arg.v; } /* copy constructor */ \
bool operator==(_typename arg) const noexcept { return v == arg.v; } /* equality operator */ \
bool operator!=(_typename arg) const noexcept { return v != arg.v; } /* inequality operator */ \
Expand Down

0 comments on commit c191b73

Please sign in to comment.