From 22ec06ad75f682100be178e0806861a5969ad1ef Mon Sep 17 00:00:00 2001 From: jferreyra Date: Fri, 15 Dec 2023 17:47:01 -0800 Subject: [PATCH 1/2] Adding the option for customs consexpr string constants --- src/source/CppGenerator.scala | 37 +++++++++++++++++++++++------------ src/source/CppMarshal.scala | 7 +++++-- src/source/Main.scala | 8 ++++++++ src/source/generator.scala | 2 ++ 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index 1426d598..c7b6ceee 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -39,13 +39,13 @@ class CppGenerator(spec: Spec) extends Generator(spec) { var hppFwds = mutable.TreeSet[String]() var cpp = mutable.TreeSet[String]() - def find(ty: TypeRef, forwardDeclareOnly: Boolean) { find(ty.resolved, forwardDeclareOnly) } - def find(tm: MExpr, forwardDeclareOnly: Boolean) { - tm.args.foreach((x) => find(x, forwardDeclareOnly)) - find(tm.base, forwardDeclareOnly) + def find(ty: TypeRef, forwardDeclareOnly: Boolean, constants: Boolean) { find(ty.resolved, forwardDeclareOnly, constants) } + def find(tm: MExpr, forwardDeclareOnly: Boolean, constants: Boolean) { + tm.args.foreach((x) => find(x, forwardDeclareOnly, constants)) + find(tm.base, forwardDeclareOnly, constants) } - def find(m: Meta, forwardDeclareOnly : Boolean) = { - for(r <- marshal.hppReferences(m, name, forwardDeclareOnly)) r match { + def find(m: Meta, forwardDeclareOnly : Boolean, constants: Boolean) = { + for(r <- marshal.hppReferences(m, name, forwardDeclareOnly, constants)) r match { case ImportRef(arg) => hpp.add("#include " + arg) case DeclRef(decl, Some(spec.cppNamespace)) => hppFwds.add(decl) case DeclRef(_, _) => @@ -129,26 +129,37 @@ class CppGenerator(spec: Spec) extends Generator(spec) { // Make sure we don't constexpr optionals as some might not support it val canConstexpr = c.ty.resolved.base match { case p: MPrimitive if c.ty.resolved.base != MOptional => true + // if we have defined a constexpr string + case MString => spec.cppStringConstexpr.isDefined case _ => false } canConstexpr } + // Gets the type of the constant to be used in the header file + // If the type is a string and we have defined constexpr string we use that one. + def generateHppConstantType(constexpr: Boolean, field_type: String) : String = { + val ft = if(constexpr && field_type == "std::string") spec.cppStringConstexpr.get else field_type + if (constexpr) s"constexpr ${ft}" else s"${ft} const" + } + def generateHppConstants(w: IndentWriter, consts: Seq[Const]) = { for (c <- consts) { // set value in header if can constexpr (only primitives) var constexpr = shouldConstexpr(c) var constValue = ";" + var field_type = marshal.fieldType(c.ty) if (constexpr) { constValue = c.value match { case l: Long => " = " + l.toString + ";" - case d: Double if marshal.fieldType(c.ty) == "float" => " = " + d.toString + "f;" + case d: Double if field_type == "float" => " = " + d.toString + "f;" case d: Double => " = " + d.toString + ";" case b: Boolean => if (b) " = true;" else " = false;" + case s: String => " = " + s + ";" case _ => ";" } } - val constFieldType = if (constexpr) s"constexpr ${marshal.fieldType(c.ty)}" else s"${marshal.fieldType(c.ty)} const" + val constFieldType = generateHppConstantType(constexpr, field_type) // Write code to the header file w.wl @@ -197,8 +208,8 @@ class CppGenerator(spec: Spec) extends Generator(spec) { override def generateRecord(origin: String, ident: Ident, doc: Doc, params: Seq[TypeParam], r: Record) { val refs = new CppRefs(ident.name) - r.fields.foreach(f => refs.find(f.ty, false)) - r.consts.foreach(c => refs.find(c.ty, false)) + r.fields.foreach(f => refs.find(f.ty, false, false)) + r.consts.foreach(c => refs.find(c.ty, false, true)) refs.hpp.add("#include ") // Add for std::move val self = marshal.typename(ident, r) @@ -329,11 +340,11 @@ class CppGenerator(spec: Spec) extends Generator(spec) { override def generateInterface(origin: String, ident: Ident, doc: Doc, typeParams: Seq[TypeParam], i: Interface) { val refs = new CppRefs(ident.name) i.methods.map(m => { - m.params.map(p => refs.find(p.ty, true)) - m.ret.foreach((x)=>refs.find(x, true)) + m.params.map(p => refs.find(p.ty, true, false)) + m.ret.foreach((x)=>refs.find(x, true, false)) }) i.consts.map(c => { - refs.find(c.ty, true) + refs.find(c.ty, true, true) }) val self = marshal.typename(ident, i) diff --git a/src/source/CppMarshal.scala b/src/source/CppMarshal.scala index d4876555..408eb058 100644 --- a/src/source/CppMarshal.scala +++ b/src/source/CppMarshal.scala @@ -67,12 +67,15 @@ class CppMarshal(spec: Spec) extends Marshal(spec) { override def toCpp(tm: MExpr, expr: String): String = throw new AssertionError("cpp to cpp conversion") override def fromCpp(tm: MExpr, expr: String): String = throw new AssertionError("cpp to cpp conversion") - def hppReferences(m: Meta, exclude: String, forwardDeclareOnly: Boolean): Seq[SymbolReference] = m match { + def hppReferences(m: Meta, exclude: String, forwardDeclareOnly: Boolean, constant: Boolean): Seq[SymbolReference] = m match { case p: MPrimitive => p.idlName match { case "i8" | "i16" | "i32" | "i64" => List(ImportRef("")) case _ => List() } - case MString => List(ImportRef("")) + case MString => + if( constant && spec.cppStringConstexpr.isDefined ) { + if( spec.cppStringConstexprHeader.isDefined ) List(ImportRef(spec.cppStringConstexprHeader.get)) else List() + } else List(ImportRef("")) case MDate => List(ImportRef("")) case MBinary => List(ImportRef(""), ImportRef("")) case MOptional => List(ImportRef(spec.cppOptionalHeader)) diff --git a/src/source/Main.scala b/src/source/Main.scala index eb40c8c4..be53a973 100644 --- a/src/source/Main.scala +++ b/src/source/Main.scala @@ -29,6 +29,8 @@ object Main { var idlIncludePaths: List[String] = List("") var cppOutFolder: Option[File] = None var cppNamespace: String = "" + var cppStringConstexpr: Option[String] = None + var cppStringConstexprHeader: Option[String] = None var cppIncludePrefix: String = "" var cppExtendedRecordIncludePrefix: String = "" var cppFileIdentStyle: IdentConverter = IdentStyle.underLower @@ -154,6 +156,10 @@ object Main { .text("The C++ base library's include path, relative to the C++ classes.") opt[String]("cpp-namespace").valueName("...").foreach(x => cppNamespace = x) .text("The namespace name to use for generated C++ classes.") + opt[String]("cpp-string-constexpr").valueName("").foreach(x => cppStringConstexpr = Some(x)) + .text("The type for string constants for generated C++ classes.") + opt[String]("cpp-string-constexpr-header").valueName("
>").foreach(x => cppStringConstexprHeader = Some(x)) + .text("The header file to be included for string constants for generated C++ classes.") opt[String]("cpp-ext").valueName("").foreach(cppExt = _) .text("The filename extension for C++ files (default: \"cpp\").") opt[String]("hpp-ext").valueName("").foreach(cppHeaderExt = _) @@ -382,6 +388,8 @@ object Main { cppIncludePrefix, cppExtendedRecordIncludePrefix, cppNamespace, + cppStringConstexpr, + cppStringConstexprHeader, cppIdentStyle, cppFileIdentStyle, cppBaseLibIncludePrefix, diff --git a/src/source/generator.scala b/src/source/generator.scala index 907041d4..804ffac3 100644 --- a/src/source/generator.scala +++ b/src/source/generator.scala @@ -47,6 +47,8 @@ package object generatorTools { cppIncludePrefix: String, cppExtendedRecordIncludePrefix: String, cppNamespace: String, + cppStringConstexpr: Option[String], + cppStringConstexprHeader: Option[String], cppIdentStyle: CppIdentStyle, cppFileIdentStyle: IdentConverter, cppBaseLibIncludePrefix: String, From 10b8a562028c770ca13b1c1b6d9f3b233dc81ffe Mon Sep 17 00:00:00 2001 From: jferreyra Date: Fri, 15 Dec 2023 17:51:12 -0800 Subject: [PATCH 2/2] Added modification to readme.doc --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 83290c6f..4486dea3 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ verify the build and binary from the command line. - DataView for copy free data passing - DateRef for copy free data passing with ownership - Generating string names for C++ enums + - Support for custom constexpr strings such as "string_view" and "const char*" - Bug fixes ## Using new features