Task #3561
openAdd a FOO_MAX enumerator to all public enumerations
0%
Description
It is not currently possible to know if an arbitrary integer number is a valid value for a given enumeration. In some cases, even a simple static_cast
of the integer to the enumeration type can invoke undefined behavior, so the "upper bound" of the enum must be known in advance. Having a _MAX
enumerator also helps in validating user input.
Updated by Eric Newberry over 8 years ago
I propose a CachePolicy::isValid() static function that takes an integer and returns a boolean.
Updated by Eric Newberry over 8 years ago
Eric Newberry wrote:
I propose a CachePolicy::isValid() static function that takes an integer and returns a boolean.
Or a similar solution for all enumerations.
Updated by Junxiao Shi over 8 years ago
I agree with note-1 idea, but only if there's an automated way to generate such functions.
I hope there's a macro that can be used like:
NDN_CXX_DECLARE_ENUM(MyEnum, MY_ENUM, A, 1, B, 2)
NDN_CXX_DECLARE_ENUM_FLAGS(MyFlags, MY_FLAGS, A, 0, B, 1)
NDN_CXX_DECLARE_ENUM_CLASS(MyEnumClass, A, 1, B, 2)
which generates:
enum MyEnum {
MY_ENUM_NONE = 0,
MY_ENUM_A = 1,
MY_ENUM_B = 2,
MY_ENUM_MAX = 3
};
template<typename I>
std::enable_if<std::is_integral<I>::value, bool>::type
isValid<MyEnum>(I value);
// returns true if value is 0, 1, or 2, otherwise false
const char*
toString<MyEnum>(MyEnum value);
// requires isValid(value)
// returns "NONE", "A", or "B"
MyEnum
fromString<MyEnum>(const char* str, size_t len);
// accepts "A", and "B"
// otherwise returns MY_ENUM_NONE
enum MyFlags {
MY_FLAGS_NONE = 0,
MY_FLAGS_A = 1 << 0,
MY_FLAGS_B = 1 << 1,
MY_FLAGS_MAX = 1 << 2
};
template<typename I>
std::enable_if<std::is_integral<I>::value, bool>::type
isValid<MyFlags>(I value);
// returns true if value is 0 or bitwise OR'ed with declared bits, otherwise false
template<typename I>
std::enable_if<std::is_integral<I>::value, const char*>::type
toString<MyFlags>(I value);
// requires isValid(value)
// returns "NONE", "A", "B", or "A|B"
std::underlying_type<MyFlags>::type
fromString<MyFlags>(const char* str, size_t len);
// accepts "A", "B", "A|B"
// otherwise returns MY_FLAGS_NONE
enum class MyEnumClass {
NONE = 0,
A = 1,
B = 2,
MAX = 3
};
template<typename I>
std::enable_if<std::is_integral<I>::value, bool>::type
isValid<MyEnumClass>(I value);
// returns true if value is 0, 1, or 2, otherwise false
const char*
toString<MyEnumClass>(MyEnumClass value);
// requires isValid(value)
// returns "NONE", "A", or "B"
MyEnum
fromString<MyEnumClass>(const char* str, size_t len);
// accepts "A", and "B"
// otherwise returns MyEnumClass::NONE
Another approach is to use a custom compiler that converts from a "enum declaration file" to a C++ header and implementation, similar to what protobuf-compiler does.
Updated by Davide Pesavento over 8 years ago
Junxiao Shi wrote:
I agree with note-1 idea, but only if there's an automated way to generate such functions.