oatpp icon indicating copy to clipboard operation
oatpp copied to clipboard

Enumerator : The initializer contains too many elements

Open clabnet opened this issue 2 years ago • 9 comments

Hi, creating an enum with +63 entries, we can't initialize it. The message is : The initializer contains too many elements. Four help on testing , below my enumerator code. The problem arise after the entry "eInvalidEmailAddress" and successive.

    ENUM(LicMgrApiEErrorCode, v_int32,
               VALUE(eNoError, 0, "eNoError", "eNoError"),
		VALUE(eProductIdMissing, 1, "eProductIdMissing", "eProductIdMissing"),
		VALUE(eSerialNumberMissing, 2, "eSerialNumberMissing", "eSerialNumberMissing"),
		VALUE(eInvalidDeviceId, 3, "eInvalidDeviceId", "eInvalidDeviceId"),
		VALUE(eDeviceIdOrDateMissing, 4, "eDeviceIdOrDateMissing", "eDeviceIdOrDateMissing"),
		VALUE(eLicenseKeySizeError, 5, "eLicenseKeySizeError", "eLicenseKeySizeError"),
		VALUE(eLicenseKeyGenerationError, 6, "eLicenseKeyGenerationError", "eLicenseKeyGenerationError"),
		VALUE(eDateSyntaxError, 7, "eDateSyntaxError", "eDateSyntaxError"),
		VALUE(eNoLicenseCheckedOut, 101, "eNoLicenseCheckedOut", "eNoLicenseCheckedOut"),
		VALUE(eNoLicenseFile, 102, "eNoLicenseFile", "eNoLicenseFile"),
		VALUE(eLicenseFileProductIdMissing, 103, "eLicenseFileProductIdMissing", "eLicenseFileProductIdMissing"),
		VALUE(eLicenseFileSerialNumberMissing, 104, "eLicenseFileSerialNumberMissing", "eLicenseFileSerialNumberMissing"),
		VALUE(eLicenseFileLicenseKeyMissing, 105, "eLicenseFileLicenseKeyMissing", "eLicenseFileLicenseKeyMissing"),
		VALUE(eLicenseKeyMismatch, 106, "eLicenseKeyMismatch", "eLicenseKeyMismatch"),
		VALUE(eLicenseWriteError, 107, "eLicenseWriteError", "eLicenseWriteError"),
		VALUE(eLicenseKeyError, 108, "eLicenseKeyError", "eLicenseKeyError"),
		VALUE(eNoProductLicense, 109, "eNoProductLicense", "eNoProductLicense"),
		VALUE(eProductVersionMismatch, 110, "eProductVersionMismatch", "eProductVersionMismatch"),
		VALUE(e2ndLicenseNotFound, 111, "e2ndLicenseNotFound", "e2ndLicenseNotFound"),
		VALUE(eLicenseValidationFailed, 112, "eLicenseValidationFailed", "eLicenseValidationFailed"),
		VALUE(eLicenseDeviceIdMismatch, 113, "eLicenseDeviceIdMismatch", "eLicenseDeviceIdMismatch"),
		VALUE(eCountedLicenseExpected, 114, "eCountedLicenseExpected", "eCountedLicenseExpected"),
		VALUE(eUncountedLicenseExpected, 115, "eUncountedLicenseExpected", "eUncountedLicenseExpected"),
		VALUE(eCurrentDateError, 116, "eCurrentDateError", "eCurrentDateError"),
		VALUE(eLicenseExpired, 117, "eLicenseExpired", "eLicenseExpired"),
		VALUE(eNetworkCardError, 118, "eNetworkCardError", "eNetworkCardError"),
		VALUE(eDongleError, 119, "eDongleError", "eDongleError"),
		VALUE(eComputerSidError, 120, "eComputerSidError", "eComputerSidError"),
		VALUE(eUsbSerialNumberError, 121, "eUsbSerialNumberError", "eUsbSerialNumberError"),
		VALUE(eDeviceIdIndexError, 122, "eDeviceIdIndexError", "eDeviceIdIndexError"),
		VALUE(eNoModuleLicense, 123, "eNoModuleLicense", "eNoModuleLicense"),
		VALUE(eModuleLicenseExpired, 124, "eModuleLicenseExpired", "eModuleLicenseExpired"),
		VALUE(eInvalidModuleId, 125, "eInvalidModuleId", "eInvalidModuleId"),
		VALUE(eDeactivationError, 126, "eDeactivationError", "eDeactivationError"),
		VALUE(eGetSiteUrlError, 127, "eGetSiteUrlError", "eGetSiteUrlError"),
		VALUE(eNoLoginError, 128, "eNoLoginError", "eNoLoginError"),
		VALUE(eNonAsciiError, 129, "eNonAsciiError", "eNonAsciiError"),
		VALUE(eCreateConnectionFailed, 130, "eCreateConnectionFailed", "eCreateConnectionFailed"),
		VALUE(eLicenseNotValidated, 131, "eLicenseNotValidated", "eLicenseNotValidated"),
		VALUE(eOfflineLicenseNotValidated, 132, "eOfflineLicenseNotValidated", "eOfflineLicenseNotValidated"),
		VALUE(eLicenseValidationExpired, 133, "eLicenseValidationExpired", "eLicenseValidationExpired"),
    VALUE(eUnknowLicenseServerError, 201, "eUnknowLicenseServerError", "eUnknowLicenseServerError"),
		VALUE(eUnknowErrorFromLicenseServer, 202, "eUnknowErrorFromLicenseServer", "eUnknowErrorFromLicenseServer"),
		VALUE(eUnknowErrorAtLicenseServer, 203, "eUnknowErrorAtLicenseServer", "eUnknowErrorAtLicenseServer"),
		VALUE(eLicenseCountExceeded, 204, "eLicenseCountExceeded", "eLicenseCountExceeded"),
		VALUE(eLicenseAlreadyCheckedOut, 205, "eLicenseAlreadyCheckedOut", "eLicenseAlreadyCheckedOut"),
		VALUE(eLicenseNotCheckedOut, 206, "eLicenseNotCheckedOut", "eLicenseNotCheckedOut"),
		VALUE(eLicenseAlreadyBorrowed, 207, "eLicenseAlreadyBorrowed", "eLicenseAlreadyBorrowed"),
		VALUE(eLicenseNotBorrowed, 208, "eLicenseNotBorrowed", "eLicenseNotBorrowed"),
		VALUE(eUnknownLicenseServerRequest, 209, "eUnknownLicenseServerRequest", "eUnknownLicenseServerRequest"),
		VALUE(eUnknownLicenseServerResponse, 210, "eUnknownLicenseServerResponse", "eUnknownLicenseServerResponse"),
		VALUE(eInvalidLicenseHandleAtServer, 211, "eInvalidLicenseHandleAtServer", "eInvalidLicenseHandleAtServer"),
		VALUE(eProductNotLicensedAtServer, 212, "eProductNotLicensedAtServer", "eProductNotLicensedAtServer"),
		VALUE(eInvalidLicenseKeyFromServer, 213, "eInvalidLicenseKeyFromServer", "eInvalidLicenseKeyFromServer"),
		VALUE(eLicenseServerCommunicationError, 214, "eLicenseServerCommunicationError", "eLicenseServerCommunicationError"),
		VALUE(eFailedToConnectWithLicenseServer, 215, "eFailedToConnectWithLicenseServer", "eFailedToConnectWithLicenseServer"),
		VALUE(eInvalidUserName, 301, "eInvalidUserName", "eInvalidUserName"),
		VALUE(eInvalidPassword, 302, "eInvalidPassword", "eInvalidPassword"),
		VALUE(eInvalidNewPassword, 303, "eInvalidNewPassword", "eInvalidNewPassword"),
		VALUE(eUserNameExists, 304, "eUserNameExists", "eUserNameExists"),
		VALUE(eUserNameNotFound, 305, "eUserNameNotFound", "eUserNameNotFound"),
		VALUE(ePasswordChangeRequired, 306, "ePasswordChangeRequired", "ePasswordChangeRequired"),
		VALUE(eInvalidEmailAddress, 307, "eInvalidEmailAddress", "eInvalidEmailAddress"),
		VALUE(eIllegalCheckInOfflineLicenseErrorCode, 308, "eIllegalCheckInOfflineLicenseErrorCode", "eIllegalCheckInOfflineLicenseErrorCode"),
		VALUE(eOutOfMemory, 309, "eOutOfMemory", "eOutOfMemory"), // Out of memory
		VALUE(eLicenseIsNotNetwork, 310, "eLicenseIsNotNetwork", "eLicenseIsNotNetwork"),
		VALUE(eInvalidActivationType, 311, "eInvalidActivationType", "eInvalidActivationType"),
		VALUE(eUserAgreementIsNotAccepted, 312, "eUserAgreementIsNotAccepted", "eUserAgreementIsNotAccepted"),
		VALUE(eDuplicateLicenseDetected, 313, "eDuplicateLicenseDetected", "eDuplicateLicenseDetected"),
		VALUE(eLicenseNotFound, 314, "eLicenseNotFound", "eLicenseNotFound"),
		VALUE(eNumberOfErrorCodes, 315, "eNumberOfErrorCodes", "eNumberOfErrorCodes")
);

clabnet avatar Sep 07 '21 14:09 clabnet

Hey @clabnet thanks for the bug report!

So the core problem is in the macro-mechanic not being able to count further:

https://github.com/oatpp/oatpp/blob/777617321d9fbff5c48c58da55f282cd99bcec47/src/oatpp/core/macro/basic.hpp#L37 https://github.com/oatpp/oatpp/blob/777617321d9fbff5c48c58da55f282cd99bcec47/src/oatpp/core/macro/basic.hpp#L39 https://github.com/oatpp/oatpp/blob/777617321d9fbff5c48c58da55f282cd99bcec47/src/oatpp/core/macro/basic.hpp#L41

@lganzzzo Should we just increase the macro to i.E. 128?

bamkrs avatar Sep 07 '21 16:09 bamkrs

@clabnet As a workaround until we find a more appropriate solution you have to fix your local Oat++ installation by replacing src/oatpp/core/macro/basic.hpp lines 37 to 41 with the following code:

#define OATPP_MACRO__NUM_ARGS(x72, x71, X70, X69, X68, X67, X66, X65, X64, X63, X62, X61, X60, X59, X58, X57, X56, X55, X54, X53, X52, X51, X50, X49, X48, X47, X46, X45, X44, X43, X42, X41, X40, X39, X38, X37, X36, X35, X34, X33, X32, X31, X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, X16, X15, X14, X13, X12, X11, X10, X9, X8, X7, X6, X5, X4, X3, X2, X1, N, ...)   N

#define OATPP_MACRO_NUM_ARGS(...) OATPP_MACRO_EXPAND(OATPP_MACRO__NUM_ARGS(__VA_ARGS__, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))

#define OATPP_MACRO_HAS_ARGS_ARR(...) OATPP_MACRO_EXPAND(OATPP_MACRO__NUM_ARGS(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0))

bamkrs avatar Sep 07 '21 16:09 bamkrs

Hi Benedikt-Alexander, thank you for your fast reply.

I have changed the code, rebuild all, and double checked it. Unfortunately it seems do not work, it is the same error.

The error arise always on building phase. This is a snippet of the build output on VS 2019:

... 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(104,1): error C2065: 'OATPP_MACRO_DTO_ENUM_VALUE': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2065: 'eIllegalCheckInOfflineLicenseErrorCode': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(104,1): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2440: 'initializing': cannot convert from 'initializer list' to 'int' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): message : The initializer contains too many elements (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2059: syntax error: '(' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'MyEErrorCode': is not a member of 'licmgrapi' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(17): message : see declaration of 'licmgrapi' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2065: 'MyEErrorCode': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2923: 'oatpp::data::mapping::type::DTO::Enum': 'MyEErrorCode' is not a valid template type argument for parameter 'T' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24): message : see declaration of 'MyEErrorCode' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24): error C2062: type 'unknown-type' unexpected (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'AsString': is not a member of 'global namespace'' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2334: unexpected token(s) preceding '{'; skipping apparent function body (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C3646: 'errorCode': unknown override specifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'errorCode': is not a member of 'licmgrapi::ResultDto' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(20): message : see declaration of 'licmgrapi::ResultDto' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C3536: 'ptr': cannot be used before it is initialized (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'Class': is not a member of 'global namespace'' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C3083: 'AsString': the symbol to the left of a '::' must be a type (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C3083: 'Class': the symbol to the left of a '::' must be a type (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'getType': is not a member of '`global namespace'' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\service\license_service.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(104,1): error C2065: 'OATPP_MACRO_DTO_ENUM_VALUE': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2065: 'eIllegalCheckInOfflineLicenseErrorCode': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(104,1): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2440: 'initializing': cannot convert from 'initializer list' to 'int' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): message : The initializer contains too many elements (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/misc/enums.h(16,1): error C2059: syntax error: '(' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2039: 'MyEErrorCode': is not a member of 'licmgrapi' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(17): message : see declaration of 'licmgrapi' (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) 1>D:\TIERRA\collagesitelicensing\licmgrapi/src/dto/DTOs.h(24,9): error C2065: 'MyEErrorCode': undeclared identifier (compiling source file D:\TIERRA\collagesitelicensing\licmgrapi\src\web\license_controller.cpp) ...

Thanks and regards,

Claudio

------ Messaggio originale ------ Da: "Benedikt-Alexander Mokroß" @.> A: "oatpp/oatpp" @.> Cc: "Claudio Barca" @.>; "Mention" @.> Inviato: 07/09/2021 18:56:58 Oggetto: Re: [oatpp/oatpp] Enumerator : The initializer contains too many elements (#478)

@.*** https://github.com/clabnet As a workaround until we find a

more appropriate solution you have to fix your local Oat++ installation by replacing src/oatpp/core/macro/basic.hpp lines 37 to 41 with the following code:

#define OATPP_MACRO__NUM_ARGS(x72, x71, X70, X69, X68, X67, X66, X65, X64, X63, X62, X61, X60, X59, X58, X57, X56, X55, X54, X53, X52, X51, X50, X49, X48, X47, X46, X45, X44, X43, X42, X41, X40, X39, X38, X37, X36, X35, X34, X33, X32, X31, X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17, X16, X15, X14, X13, X12, X11, X10, X9, X8, X7, X6, X5, X4, X3, X2, X1, N, ...) N

#define OATPP_MACRO_NUM_ARGS(...) OATPP_MACRO_EXPAND(OATPP_MACRO__NUM_ARGS(VA_ARGS, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1))

#define OATPP_MACRO_HAS_ARGS_ARR(...) OATPP_MACRO_EXPAND(OATPP_MACRO__NUM_ARGS(VA_ARGS, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0))

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/oatpp/oatpp/issues/478#issuecomment-914469681, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABOJLGQHR6PRYOK5SNLBX63UAY75VANCNFSM5DSQQXIQ. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

clabnet avatar Sep 07 '21 21:09 clabnet

It seems to be the MSVC issue - the max allowed number of parameters in one macro is 127 And the way OATPP_MACRO_NUM_ARGS is implemented we can count only half of that number.

At the moment I doubt whether there is a straightforward solution for MSVC

@bamkrs , @clabnet

lganzzzo avatar Sep 07 '21 23:09 lganzzzo

As a workaround, to add a large number of enum values - you can manually add enum metadata. For this, you can do the following:

Instead of

ENUM(MyEnum0, v_int32,
  VALUE(VAL_1, 1),
  VALUE(VAL_2, 2),
  VALUE(VAL_3, 3)
  ...
)

Do the following:

/* create enum */
enum class MyEnum : v_int32 {
    VAL_1 = 1,
    VAL_2 = 2,
    VAL_3 = 3
    ...
};

/* create enum metadata */
class MyEnumMeta : public oatpp::data::mapping::type::EnumMeta<MyEnum> {
private:

  static void addEntry(oatpp::data::mapping::type::EnumInfo<EnumType>& info, MyEnum val, const char* name) {
    oatpp::data::mapping::type::EnumValueInfo<EnumType> entry =
      {val, (v_int32) info.byIndex.size(),name,nullptr};

    info.byName.insert({entry.name, entry});
    info.byValue.insert({(v_uint64) entry.value, entry});
    info.byIndex.push_back(entry);
  }

public:

  static bool initializer(){

    auto& info = *EnumMeta<MyEnum>::getInfo();
    info.nameQualifier="MyEnum";

    addEntry(info, EnumType::VAL_1, "VAL_1");
    addEntry(info, EnumType::VAL_2, "VAL_2");
    addEntry(info, EnumType::VAL_3, "VAL_3");
    ... // TODO - add more values

    return true;
  }

};

static bool myEnumMetaInit = MyEnumMeta::initializer();

Also, I think, the addEntry method can be moved to superclass

lganzzzo avatar Sep 08 '21 00:09 lganzzzo

It seems to be the MSVC issue - the max allowed number of parameters in one macro is 127 And the way OATPP_MACRO_NUM_ARGS is implemented we can count only half of that number.

At the moment I doubt whether there is a straightforward solution for MSVC

@bamkrs , @clabnet

I have to contradict you on 127 and MSVC. I can reproduce a similar Issue on Debian 11. It caps out around 63, too. Inflating the macro as in my snippet fixes this for me.

bamkrs avatar Sep 08 '21 03:09 bamkrs

@bamkrs

My last comment was a bit confusing. Here is the more detailed explanation:

Currently, the OATPP_MACRO_NUM_ARGS macro is limited to the max 63 parameters - on all platforms. But why it's limited - because on MSVC max possible params in the macro is 127, and the way OATPP_MACRO_NUM_ARGS works we have only half that number - 63.

Yes, inflating that macro will fix this issue when using gcc and clang. Why can't we increase that number on all platforms? - because inflating that macro to more than 63 values will actually reduce the max possible params number that we can pass to that macro on MSVC which will be 127 - X (where X is the number of placeholders in OATPP_MACRO_NUM_ARGS).

Yes, we can use ifdefs to make it work better on gcc and clang. However, we can't increase this limit on MSVC

lganzzzo avatar Sep 08 '21 11:09 lganzzzo

Thank you @all for your effort. I have solved the problem using https://github.com/Neargye/magic_enum to describe automatically the enum entry.

clabnet avatar Sep 10 '21 09:09 clabnet

Another workaround

As mentioned, MSVC caps out at 127 parameters, allowing for no more than 63 enums. This limit, however, only applies to the legacy preprocessor of MSVC.

In order to improve standards conformance (C++ standard requires compilers to accept at least 256 parameters), Microsoft introduced a new, conforming preprocessor: https://learn.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-170

This can be enabled on Visual Studio 2019 and later via /Zc:preprocessor in the project options.

Proposal

When compiling with /Zc:preprocessor, MSVC can process the extended macros as suggested by @bamkrs above. Oat++ could even detect this situation via the _MSVC_TRADITIONAL macro:

#if !defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL
// Use the current enum macro that caps out at 63 values
#else
// Use a new enum macro that caps out at 127 values (as guaranteed by the C++ standard)
#endif

Users on Clang/GCC/etc would then be free of this limitation, and users on MSVC could be pointed towards the /Zc:preprocessor switch.

nitrexcm avatar Dec 08 '23 12:12 nitrexcm