Project

General

Profile

Task #3561

Add a FOO_MAX enumerator to all public enumerations

Added by Davide Pesavento almost 4 years ago. Updated over 3 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Base
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:

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.

History

#1

Updated by Eric Newberry almost 4 years ago

I propose a CachePolicy::isValid() static function that takes an integer and returns a boolean.

#2

Updated by Eric Newberry almost 4 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.

#3

Updated by Junxiao Shi almost 4 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.

#4

Updated by Davide Pesavento over 3 years ago

Junxiao Shi wrote:

I agree with note-1 idea, but only if there's an automated way to generate such functions.

http://aantron.github.io/better-enums/index.html

Also available in: Atom PDF