From 24ac1fc25e875b39f30e31bbba6657bbc672289c Mon Sep 17 00:00:00 2001 From: k_lyashkevich Date: Wed, 23 Oct 2019 15:38:53 +0300 Subject: [PATCH] added generation of c++ enum serializer functions. Added flag cpp-enum-serializers to enable serializing enums in c++; When this flag is turned on - serialize function declaration will be generated in enum's header and c++ function definition will be generated to similar cpp file. --- src/source/CppGenerator.scala | 24 ++++++++++++++++++++++++ src/source/Main.scala | 3 +++ src/source/generator.scala | 1 + test-suite/Makefile | 2 +- test-suite/run_djinni.sh | 1 + 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index 09f3be3e1..fcafe23cd 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -63,10 +63,16 @@ class CppGenerator(spec: Spec) extends Generator(spec) { refs.hpp.add("#include ") // needed for std::hash } + val stringExpr = MExpr(MString, Seq.empty[MExpr]) + refs.find(stringExpr, false) + val flagsType = "unsigned" val enumType = "int" val underlyingType = if(e.flags) flagsType else enumType + val stringRetType = marshal.typename(stringExpr) + val toStringFunctionName = idCpp.method(s"${self}_to_string") + writeHppFile(ident, origin, refs.hpp, refs.hppFwds, w => { w.w(s"enum class $self : $underlyingType").bracedSemi { writeEnumOptionNone(w, e, idCpp.enum) @@ -92,6 +98,9 @@ class CppGenerator(spec: Spec) extends Generator(spec) { w.wl(s"return static_cast<$self>(~static_cast<$flagsType>(x));") } } + if(spec.cppEnumSerializers) { + w.wl.wl(s"$stringRetType $toStringFunctionName(${withCppNs(self)} arg);") + } }, w => { // std::hash specialization has to go *outside* of the wrapNs @@ -110,6 +119,21 @@ class CppGenerator(spec: Spec) extends Generator(spec) { ) } }) + if(spec.cppEnumSerializers) { + writeCppFile(ident, origin, refs.cpp, + w => { + w.w(s"$stringRetType $toStringFunctionName(${withCppNs(self)} arg)").braced { + w.w("switch(arg)").braced { + for (o <- normalEnumOptions(e)) { + val enumItem = withCppNs(s"$self::${idCpp.enum(o.ident.name)}") + w.wl(s"case $enumItem: return ${q(enumItem)};") + } + val convertValToString = (if (spec.cppUseWideStrings) "std::to_wstring" else "std::to_string") + s"(static_cast<${underlyingType}>(arg))" + w.wl(s"default: return $stringRetType(${q(s"$toStringFunctionName: not supported enum value: ")}) + $convertValToString;") + } + } + }) + } } def shouldConstexpr(c: Const) = { diff --git a/src/source/Main.scala b/src/source/Main.scala index fd083c5e5..e3fc16700 100644 --- a/src/source/Main.scala +++ b/src/source/Main.scala @@ -59,6 +59,7 @@ object Main { var cppHeaderOutFolderOptional: Option[File] = None var cppExt: String = "cpp" var cppHeaderExt: String = "hpp" + var cppEnumSerializers = false var javaIdentStyle = IdentStyle.javaDefault var cppIdentStyle = IdentStyle.cppDefault var cppTypeEnumIdentStyle: IdentConverter = null @@ -136,6 +137,7 @@ object Main { .text("The filename extension for C++ files (default: \"cpp\").") opt[String]("hpp-ext").valueName("").foreach(cppHeaderExt = _) .text("The filename extension for C++ header files (default: \"hpp\").") + opt[Boolean]("cpp-enum-serializers").valueName("").foreach(x => cppEnumSerializers = x) opt[String]("cpp-optional-template").valueName("