diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 5c7fc11d7..4e8f71d37 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -91,6 +91,20 @@ switch (type) { } */ +// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation +// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed). +// In the above example, only CTYPE is used to generate the code, it can be rewritten: + +/* +switch (type) { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + case BASE_TYPE_ ## ENUM: \ + // do something specific to CTYPE here + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD +} +*/ + #define FLATBUFFERS_GEN_TYPES(TD) \ FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ FLATBUFFERS_GEN_TYPES_POINTER(TD) \ @@ -101,17 +115,15 @@ switch (type) { __extension__ // Stop GCC complaining about trailing comma with -Wpendantic. #endif enum BaseType { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - BASE_TYPE_ ## ENUM, + #define FLATBUFFERS_TD(ENUM, ...) \ + BASE_TYPE_ ## ENUM, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD }; -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ - "define largest_scalar_t as " #CTYPE); +#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ + "define largest_scalar_t as " #CTYPE); FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 706732b0f..214b8c5d9 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -545,11 +545,10 @@ class CppGenerator : public BaseGenerator { std::string GenTypeBasic(const Type &type, bool user_facing_type) const { // clang-format off static const char *const ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - #CTYPE, + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + #CTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD + #undef FLATBUFFERS_TD }; // clang-format on if (user_facing_type) { diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp index 5045bd95d..ca7614847 100644 --- a/src/idl_gen_csharp.cpp +++ b/src/idl_gen_csharp.cpp @@ -119,11 +119,10 @@ class CSharpGenerator : public BaseGenerator { std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const { // clang-format off static const char * const csharp_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, ...) \ #NTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD }; // clang-format on diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp index 4ed1a80b2..7dc56df0d 100644 --- a/src/idl_gen_go.cpp +++ b/src/idl_gen_go.cpp @@ -1162,15 +1162,14 @@ class GoGenerator : public BaseGenerator { } std::string GenTypeBasic(const Type &type) { - static const char *ctypename[] = { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + static const char *ctypename[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, ...) \ #GTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; + // clang-format on return ctypename[type.base_type]; } diff --git a/src/idl_gen_java.cpp b/src/idl_gen_java.cpp index b257111f8..b67438db0 100644 --- a/src/idl_gen_java.cpp +++ b/src/idl_gen_java.cpp @@ -142,15 +142,13 @@ class JavaGenerator : public BaseGenerator { std::string GenTypeBasic(const Type &type) const { // clang-format off - static const char * const java_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + static const char * const java_typename[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, ...) \ #JTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD + }; // clang-format on - return java_typename[type.base_type]; } diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp index b12e554d3..9827ebbac 100644 --- a/src/idl_gen_kotlin.cpp +++ b/src/idl_gen_kotlin.cpp @@ -139,14 +139,14 @@ class KotlinGenerator : public BaseGenerator { static std::string GenTypeBasic(const BaseType &type) { // clang-format off - static const char * const kotlin_typename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - #KTYPE, + static const char * const kotlin_typename[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ + CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #KTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // clang-format on + #undef FLATBUFFERS_TD }; + // clang-format on return kotlin_typename[type]; } diff --git a/src/idl_gen_lobster.cpp b/src/idl_gen_lobster.cpp index d5c99f7ee..3a0e321a0 100644 --- a/src/idl_gen_lobster.cpp +++ b/src/idl_gen_lobster.cpp @@ -83,15 +83,15 @@ class LobsterGenerator : public BaseGenerator { // This uses Python names for now.. std::string GenTypeBasic(const Type &type) { - static const char *ctypename[] = { // clang-format off + static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ #PTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; + // clang-format on return ctypename[type.base_type]; } diff --git a/src/idl_gen_lua.cpp b/src/idl_gen_lua.cpp index 6ae7dd4cd..6be806b9d 100644 --- a/src/idl_gen_lua.cpp +++ b/src/idl_gen_lua.cpp @@ -595,15 +595,15 @@ class LuaGenerator : public BaseGenerator { } std::string GenTypeBasic(const Type &type) { - static const char *ctypename[] = { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - #PTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // clang-format on + static const char *ctypename[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ + CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ + #PTYPE, + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD }; + // clang-format on return ctypename[type.base_type]; } diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp index 16e47816c..d1e3550cb 100644 --- a/src/idl_gen_php.cpp +++ b/src/idl_gen_php.cpp @@ -860,15 +860,15 @@ class PhpGenerator : public BaseGenerator { } static std::string GenTypeBasic(const Type &type) { - static const char *ctypename[] = { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - #NTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - // clang-format on + static const char *ctypename[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ + CTYPE, JTYPE, GTYPE, NTYPE, ...) \ + #NTYPE, + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD }; + // clang-format on return ctypename[type.base_type]; } diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index bff0d8492..58d0e0fbe 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -667,15 +667,15 @@ class PythonGenerator : public BaseGenerator { } std::string GenTypeBasic(const Type &type) { - static const char *ctypename[] = { // clang-format off + static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \ #PTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; + // clang-format on return ctypename[IsArray(type) ? type.VectorType().base_type : type.base_type]; } diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp index 3c23f2f9d..fdf58e345 100644 --- a/src/idl_gen_rust.cpp +++ b/src/idl_gen_rust.cpp @@ -457,12 +457,12 @@ class RustGenerator : public BaseGenerator { // clang-format off static const char * const ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - #RTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + RTYPE, ...) \ + #RTYPE, + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; + // clang-format on if (type.enum_def) { return WrapInNameSpace(*type.enum_def); } return ctypename[type.base_type]; @@ -476,15 +476,15 @@ class RustGenerator : public BaseGenerator { FLATBUFFERS_ASSERT(false && "precondition failed in GetEnumTypeForDecl"); } - static const char *ctypename[] = { // clang-format off + static const char *ctypename[] = { #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ - #RTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + RTYPE, ...) \ + #RTYPE, + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; + // clang-format on // Enums can be bools, but their Rust representation must be a u8, as used // in the repr attribute (#[repr(bool)] is an invalid attribute). diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp index 1d0a3caaf..4c00472df 100644 --- a/src/idl_gen_text.cpp +++ b/src/idl_gen_text.cpp @@ -167,8 +167,7 @@ bool Print(const void *val, Type type, int indent, // Call PrintVector above specifically for each element type: // clang-format off switch (vec_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_ ## ENUM: \ if (!PrintVector( \ *reinterpret_cast *>(val), \ @@ -187,8 +186,7 @@ bool Print(const void *val, Type type, int indent, // Call PrintArray above specifically for each element type: // clang-format off switch (vec_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_ ## ENUM: \ if (!PrintArray( \ *reinterpret_cast *>(val), \ @@ -198,6 +196,7 @@ bool Print(const void *val, Type type, int indent, } \ break; FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) + // Arrays of scalars or structs are only possible. FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) #undef FLATBUFFERS_TD case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0); @@ -286,19 +285,17 @@ static bool GenStruct(const StructDef &struct_def, const Table *table, text += " "; switch (fd.value.type.base_type) { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - case BASE_TYPE_ ## ENUM: \ - if (!GenField(fd, table, struct_def.fixed, \ - opts, indent + Indent(opts), _text)) { \ - return false; \ - } \ - break; + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + case BASE_TYPE_ ## ENUM: \ + if (!GenField(fd, table, struct_def.fixed, \ + opts, indent + Indent(opts), _text)) { \ + return false; \ + } \ + break; FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) #undef FLATBUFFERS_TD // Generate drop-thru case statements for all pointer types: - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, ...) \ case BASE_TYPE_ ## ENUM: FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD) diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 56b1547ca..163d111b3 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -37,26 +37,22 @@ const char *FLATBUFFERS_VERSION() { const double kPi = 3.14159265358979323846; -const char *const kTypeNames[] = { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ +const char *const kTypeNames[] = { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ IDLTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on nullptr }; const char kTypeSizes[] = { -// clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - sizeof(CTYPE), + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + sizeof(CTYPE), FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - // clang-format on }; +// clang-format on // The enums in the reflection schema should match the ones we use internally. // Compare the last element to check if these go out of sync. @@ -222,8 +218,7 @@ static std::string TokenToString(int t) { #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING, FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) #undef FLATBUFFERS_TOKEN - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ IDLTYPE, FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #undef FLATBUFFERS_TD @@ -1179,8 +1174,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, size == SizeOf(field_value.type.base_type)) { switch (field_value.type.base_type) { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_ ## ENUM: \ builder_.Pad(field->padding); \ if (struct_def.fixed) { \ @@ -1194,10 +1188,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, builder_.AddElement(field_value.offset, val, valdef); \ } \ break; - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); + FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) #undef FLATBUFFERS_TD - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_ ## ENUM: \ builder_.Pad(field->padding); \ if (IsStruct(field->value.type)) { \ @@ -1208,7 +1201,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, builder_.AddOffset(field_value.offset, val); \ } \ break; - FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD); + FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) #undef FLATBUFFERS_TD case BASE_TYPE_ARRAY: builder_.Pad(field->padding); @@ -1258,8 +1251,7 @@ CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) { static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) { switch (ftype) { -#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ - RTYPE, KTYPE) \ +#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_##ENUM: return ReadScalar(a) < ReadScalar(b); FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) #undef FLATBUFFERS_TD @@ -1314,8 +1306,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue, auto &val = field_stack_.back().first; switch (val.type.base_type) { // clang-format off - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \ case BASE_TYPE_ ## ENUM: \ if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \ else { \ @@ -1429,8 +1420,7 @@ CheckedError Parser::ParseArray(Value &array) { auto &val = *it; // clang-format off switch (val.type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_ ## ENUM: \ if (IsStruct(val.type)) { \ SerializeStruct(builder, *val.type.struct_def, val); \ @@ -1782,14 +1772,13 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, if (check_now && IsScalar(match_type)) { // clang-format off switch (match_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, \ - CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ - case BASE_TYPE_ ## ENUM: {\ - CTYPE val; \ - ECHECK(atot(e.constant.c_str(), *this, &val)); \ - SingleValueRepack(e, val); \ - break; } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + case BASE_TYPE_ ## ENUM: {\ + CTYPE val; \ + ECHECK(atot(e.constant.c_str(), *this, &val)); \ + SingleValueRepack(e, val); \ + break; } + FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) #undef FLATBUFFERS_TD default: break; } @@ -2018,13 +2007,12 @@ struct EnumValBuilder { FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) { // clang-format off switch (enum_def.underlying_type.base_type) { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \ - PTYPE, RTYPE, KTYPE) \ + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ case BASE_TYPE_##ENUM: { \ if (!IsInteger(BASE_TYPE_##ENUM)) break; \ return ValidateImpl(ev, next ? 1 : 0); \ } - FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); + FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) #undef FLATBUFFERS_TD default: break; }