Skip to content

Commit

Permalink
[C++] use constexpr to define precedence checks lookup tables
Browse files Browse the repository at this point in the history
  • Loading branch information
nbradac committed Dec 9, 2024
1 parent 68aeb1a commit d3f3bf4
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ public void generate() throws IOException
generateDisplay(sb, msgToken.name(), fields, groups, varData);
sb.append(generateMessageLength(groups, varData, BASE_INDENT));
sb.append("};\n");
generateLookupTableDefinitions(sb, className, fieldPrecedenceModel);
sb.append(CppUtil.closingBraces(namespaces.length)).append("#endif\n");
out.append(sb);
}
Expand Down Expand Up @@ -2975,12 +2974,8 @@ private static CharSequence generateLookupTableDeclarations(final FieldPrecedenc
}

final StringBuilder sb = new StringBuilder();
sb.append(INDENT).append("static const std::string STATE_NAME_LOOKUP[")
.append(fieldPrecedenceModel.stateCount())
.append("];\n");
sb.append(INDENT).append("static const std::string STATE_TRANSITIONS_LOOKUP[")
.append(fieldPrecedenceModel.stateCount())
.append("];\n\n");

generateLookupTableDefinitions(sb, fieldPrecedenceModel);

sb.append(INDENT).append("static std::string codecStateName(CodecState state)\n")
.append(INDENT).append("{\n")
Expand All @@ -2997,27 +2992,24 @@ private static CharSequence generateLookupTableDeclarations(final FieldPrecedenc

private static void generateLookupTableDefinitions(
final StringBuilder sb,
final String className,
final FieldPrecedenceModel fieldPrecedenceModel)
{
if (null == fieldPrecedenceModel)
{
return;
}

sb.append("\n").append("const std::string ").append(className).append("::STATE_NAME_LOOKUP[")
.append(fieldPrecedenceModel.stateCount()).append("] =\n")
.append("{\n");
sb.append(INDENT).append("static constexpr const char *STATE_NAME_LOOKUP[] =\n")
.append(INDENT).append("{\n");
fieldPrecedenceModel.forEachStateOrderedByStateNumber((state) ->
sb.append(INDENT).append("\"").append(state.name()).append("\",\n"));
sb.append("};\n\n");
sb.append(INDENT).append(INDENT).append("\"").append(state.name()).append("\",\n"));
sb.append(INDENT).append("};\n\n");

sb.append("const std::string ").append(className).append("::STATE_TRANSITIONS_LOOKUP[")
.append(fieldPrecedenceModel.stateCount()).append("] =\n")
.append("{\n");
sb.append(INDENT).append("static constexpr const char *STATE_TRANSITIONS_LOOKUP[] =\n")
.append(INDENT).append("{\n");
fieldPrecedenceModel.forEachStateOrderedByStateNumber((state) ->
{
sb.append(INDENT).append("\"");
sb.append(INDENT).append(INDENT).append("\"");
final MutableBoolean isFirst = new MutableBoolean(true);
final Set<String> transitionDescriptions = new HashSet<>();
fieldPrecedenceModel.forEachTransitionFrom(state, (transitionGroup) ->
Expand All @@ -3038,7 +3030,7 @@ private static void generateLookupTableDefinitions(
});
sb.append("\",\n");
});
sb.append("};\n\n");
sb.append(INDENT).append("};\n\n");
}

private static CharSequence qualifiedStateCase(final FieldPrecedenceModel.State state)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,30 @@ void dtosShouldReferenceTypesInDifferentPackages() throws Exception
assertThat(source, containsString("using namespace test::message::schema::common;"));
}
}

@Test
void shouldUseConstexprWhenDefiningPrecedenceChecksLookupTables() throws Exception
{
try (InputStream in = Tests.getLocalResource("code-generation-schema.xml"))
{
final ParserOptions options = ParserOptions.builder().stopOnError(true).build();
final MessageSchema schema = parse(in, options);
final IrGenerator irg = new IrGenerator();
final Ir ir = irg.generate(schema);
final StringWriterOutputManager outputManager = new StringWriterOutputManager();
outputManager.setPackageName(ir.applicableNamespace());

final CppGenerator generator = new CppGenerator(
ir,
false,
PrecedenceChecks.newInstance(new PrecedenceChecks.Context().shouldGeneratePrecedenceChecks(true)),
false,
outputManager);
generator.generate();

final String source = outputManager.getSource("code.generation.test.Car").toString();
assertThat(source, containsString("static constexpr const char *STATE_NAME_LOOKUP[] ="));
assertThat(source, containsString("static constexpr const char *STATE_TRANSITIONS_LOOKUP[] ="));
}
}
}

0 comments on commit d3f3bf4

Please sign in to comment.