diff --git a/src/source/CppGenerator.scala b/src/source/CppGenerator.scala index 119636fd7..159b8c0de 100644 --- a/src/source/CppGenerator.scala +++ b/src/source/CppGenerator.scala @@ -91,11 +91,34 @@ class CppGenerator(spec: Spec) extends Generator(spec) { } def generateHppConstants(w: IndentWriter, consts: Seq[Const]) = { + var needsCppGen = false + for (c <- consts) { + var isConstExpr = true + val constValue = c.value match { + case l: Long => " = { " + l.toString + " };" + case d: Double if marshal.fieldType(c.ty) == "float" => " = { " + d.toString + "f };" + case d: Double => " = { " + d.toString + " };" + case b: Boolean => if (b) " = { true };" else " = { false };" + case e: EnumValue => " = " + marshal.typename(c.ty) + "::" + idCpp.enum(e.ty.name + "_" + e.name) + ";" + case _ => { + needsCppGen = true; + isConstExpr = false; + ";" + } + } + w.wl writeDoc(w, c.doc) - w.wl(s"static ${marshal.fieldType(c.ty)} const ${idCpp.const(c.ident)};") + w.w(s"static ${if (isConstExpr) "constexpr" else "" } const ${marshal.fieldType(c.ty)} ${idCpp.const(c.ident)}${constValue}") } + + if (!consts.isEmpty) { + w.wl + w.wl + } + + needsCppGen } def generateCppConstants(w: IndentWriter, consts: Seq[Const], selfName: String) = { @@ -127,10 +150,20 @@ class CppGenerator(spec: Spec) extends Generator(spec) { val skipFirst = SkipFirst() for (c <- consts) { - skipFirst{ w.wl } - w.w(s"${marshal.fieldType(c.ty)} const $selfName::${idCpp.const(c.ident)} = ") - writeCppConst(w, c.ty, c.value) - w.wl(";") + val isConstExpr = c.value match { + case l: Long => true + case d: Double => true + case b: Boolean => true + case e: EnumValue => true + case _ => false + } + + if (!isConstExpr) { + skipFirst{ w.wl } + w.w(s"${marshal.fieldType(c.ty)} const $selfName::${idCpp.const(c.ident)} = ") + writeCppConst(w, c.ty, c.value) + w.wl(";") + } } } @@ -149,6 +182,8 @@ class CppGenerator(spec: Spec) extends Generator(spec) { refs.cpp.add("#include "+q(spec.cppExtendedRecordIncludePrefix + spec.cppFileIdentStyle(ident) + "." + spec.cppHeaderExt)) } + var constantsRequireCpp = false; + // C++ Header def writeCppPrototype(w: IndentWriter) { if (r.ext.cpp) { @@ -159,7 +194,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { writeDoc(w, doc) writeCppTypeParams(w, params) w.w("struct " + actualSelf + cppFinal).bracedSemi { - generateHppConstants(w, r.consts) + constantsRequireCpp = generateHppConstants(w, r.consts) // Field definitions. for (f <- r.fields) { writeDoc(w, f.doc) @@ -210,7 +245,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { writeHppFile(cppName, origin, refs.hpp, refs.hppFwds, writeCppPrototype) - if (r.consts.nonEmpty || r.derivingTypes.nonEmpty) { + if (constantsRequireCpp || r.derivingTypes.nonEmpty) { writeCppFile(cppName, origin, refs.cpp, w => { generateCppConstants(w, r.consts, actualSelf) @@ -274,6 +309,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { val self = marshal.typename(ident, i) val methodNamesInScope = i.methods.map(m => idCpp.method(m.ident)) + var generateCppFile = false; writeHppFile(ident, origin, refs.hpp, refs.hppFwds, w => { writeDoc(w, doc) @@ -283,7 +319,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { // Destructor w.wl(s"virtual ~$self() {}") // Constants - generateHppConstants(w, i.consts) + generateCppFile = generateHppConstants(w, i.consts) // Methods for (m <- i.methods) { w.wl @@ -301,7 +337,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) { }) // Cpp only generated in need of Constants - if (i.consts.nonEmpty) { + if (generateCppFile) { writeCppFile(ident, origin, refs.cpp, w => { generateCppConstants(w, i.consts, self) }) diff --git a/test-suite/generated-src/cpp/constants.cpp b/test-suite/generated-src/cpp/constants.cpp index db05286d6..c0dc19b2a 100644 --- a/test-suite/generated-src/cpp/constants.cpp +++ b/test-suite/generated-src/cpp/constants.cpp @@ -5,34 +5,6 @@ namespace testsuite { -bool const Constants::BOOL_CONSTANT = true; - -int8_t const Constants::I8_CONSTANT = 1; - -int16_t const Constants::I16_CONSTANT = 2; - -int32_t const Constants::I32_CONSTANT = 3; - -int64_t const Constants::I64_CONSTANT = 4; - -float const Constants::F32_CONSTANT = 5.0f; - -double const Constants::F64_CONSTANT = 5.0; - -std::experimental::optional const Constants::OPT_BOOL_CONSTANT = true; - -std::experimental::optional const Constants::OPT_I8_CONSTANT = 1; - -std::experimental::optional const Constants::OPT_I16_CONSTANT = 2; - -std::experimental::optional const Constants::OPT_I32_CONSTANT = 3; - -std::experimental::optional const Constants::OPT_I64_CONSTANT = 4; - -std::experimental::optional const Constants::OPT_F32_CONSTANT = 5.0; - -std::experimental::optional const Constants::OPT_F64_CONSTANT = 5.0; - std::string const Constants::STRING_CONSTANT = {"string-constant"}; std::experimental::optional const Constants::OPT_STRING_CONSTANT = {"string-constant"}; @@ -41,6 +13,4 @@ ConstantRecord const Constants::OBJECT_CONSTANT = ConstantRecord( Constants::I32_CONSTANT /* some_integer */ , Constants::STRING_CONSTANT /* some_string */ ); -bool const Constants::DUMMY = false; - } // namespace testsuite diff --git a/test-suite/generated-src/cpp/constants.hpp b/test-suite/generated-src/cpp/constants.hpp index 32b1a0283..43f7eba33 100644 --- a/test-suite/generated-src/cpp/constants.hpp +++ b/test-suite/generated-src/cpp/constants.hpp @@ -15,57 +15,41 @@ namespace testsuite { struct Constants final { /** bool_constant has documentation. */ - static bool const BOOL_CONSTANT; - - static int8_t const I8_CONSTANT; - - static int16_t const I16_CONSTANT; - - static int32_t const I32_CONSTANT; - - static int64_t const I64_CONSTANT; - - static float const F32_CONSTANT; - + static constexpr const bool BOOL_CONSTANT = { true }; + static constexpr const int8_t I8_CONSTANT = { 1 }; + static constexpr const int16_t I16_CONSTANT = { 2 }; + static constexpr const int32_t I32_CONSTANT = { 3 }; + static constexpr const int64_t I64_CONSTANT = { 4 }; + static constexpr const float F32_CONSTANT = { 5.0f }; /** * f64_constant has long documentation. * (Second line of multi-line documentation. * Indented third line of multi-line documentation.) */ - static double const F64_CONSTANT; - - static std::experimental::optional const OPT_BOOL_CONSTANT; - - static std::experimental::optional const OPT_I8_CONSTANT; - + static constexpr const double F64_CONSTANT = { 5.0 }; + static constexpr const std::experimental::optional OPT_BOOL_CONSTANT = { true }; + static constexpr const std::experimental::optional OPT_I8_CONSTANT = { 1 }; /** opt_i16_constant has documentation. */ - static std::experimental::optional const OPT_I16_CONSTANT; - - static std::experimental::optional const OPT_I32_CONSTANT; - - static std::experimental::optional const OPT_I64_CONSTANT; - + static constexpr const std::experimental::optional OPT_I16_CONSTANT = { 2 }; + static constexpr const std::experimental::optional OPT_I32_CONSTANT = { 3 }; + static constexpr const std::experimental::optional OPT_I64_CONSTANT = { 4 }; /** * opt_f32_constant has long documentation. * (Second line of multi-line documentation. * Indented third line of multi-line documentation.) */ - static std::experimental::optional const OPT_F32_CONSTANT; - - static std::experimental::optional const OPT_F64_CONSTANT; - - static std::string const STRING_CONSTANT; - - static std::experimental::optional const OPT_STRING_CONSTANT; - - static ConstantRecord const OBJECT_CONSTANT; - + static constexpr const std::experimental::optional OPT_F32_CONSTANT = { 5.0 }; + static constexpr const std::experimental::optional OPT_F64_CONSTANT = { 5.0 }; + static const std::string STRING_CONSTANT; + static const std::experimental::optional OPT_STRING_CONSTANT; + static const ConstantRecord OBJECT_CONSTANT; /** * No support for null optional constants * No support for optional constant records * No support for constant binary, list, set, map */ - static bool const DUMMY; + static constexpr const bool DUMMY = { false }; + }; } // namespace testsuite diff --git a/test-suite/generated-src/cpp/constants_interface.cpp b/test-suite/generated-src/cpp/constants_interface.cpp index b24932e9f..0ae3b96a5 100644 --- a/test-suite/generated-src/cpp/constants_interface.cpp +++ b/test-suite/generated-src/cpp/constants_interface.cpp @@ -6,34 +6,6 @@ namespace testsuite { -bool const ConstantsInterface::BOOL_CONSTANT = true; - -int8_t const ConstantsInterface::I8_CONSTANT = 1; - -int16_t const ConstantsInterface::I16_CONSTANT = 2; - -int32_t const ConstantsInterface::I32_CONSTANT = 3; - -int64_t const ConstantsInterface::I64_CONSTANT = 4; - -float const ConstantsInterface::F32_CONSTANT = 5.0f; - -double const ConstantsInterface::F64_CONSTANT = 5.0; - -std::experimental::optional const ConstantsInterface::OPT_BOOL_CONSTANT = true; - -std::experimental::optional const ConstantsInterface::OPT_I8_CONSTANT = 1; - -std::experimental::optional const ConstantsInterface::OPT_I16_CONSTANT = 2; - -std::experimental::optional const ConstantsInterface::OPT_I32_CONSTANT = 3; - -std::experimental::optional const ConstantsInterface::OPT_I64_CONSTANT = 4; - -std::experimental::optional const ConstantsInterface::OPT_F32_CONSTANT = 5.0; - -std::experimental::optional const ConstantsInterface::OPT_F64_CONSTANT = 5.0; - std::string const ConstantsInterface::STRING_CONSTANT = {"string-constant"}; std::experimental::optional const ConstantsInterface::OPT_STRING_CONSTANT = {"string-constant"}; diff --git a/test-suite/generated-src/cpp/constants_interface.hpp b/test-suite/generated-src/cpp/constants_interface.hpp index 54a7d6c8c..759a232e6 100644 --- a/test-suite/generated-src/cpp/constants_interface.hpp +++ b/test-suite/generated-src/cpp/constants_interface.hpp @@ -16,51 +16,36 @@ class ConstantsInterface { public: virtual ~ConstantsInterface() {} - static bool const BOOL_CONSTANT; - - static int8_t const I8_CONSTANT; - - static int16_t const I16_CONSTANT; - + static constexpr const bool BOOL_CONSTANT = { true }; + static constexpr const int8_t I8_CONSTANT = { 1 }; + static constexpr const int16_t I16_CONSTANT = { 2 }; /** i32_constant has documentation. */ - static int32_t const I32_CONSTANT; - + static constexpr const int32_t I32_CONSTANT = { 3 }; /** * i64_constant has long documentation. * (Second line of multi-line documentation. * Indented third line of multi-line documentation.) */ - static int64_t const I64_CONSTANT; - - static float const F32_CONSTANT; - - static double const F64_CONSTANT; - - static std::experimental::optional const OPT_BOOL_CONSTANT; - - static std::experimental::optional const OPT_I8_CONSTANT; - + static constexpr const int64_t I64_CONSTANT = { 4 }; + static constexpr const float F32_CONSTANT = { 5.0f }; + static constexpr const double F64_CONSTANT = { 5.0 }; + static constexpr const std::experimental::optional OPT_BOOL_CONSTANT = { true }; + static constexpr const std::experimental::optional OPT_I8_CONSTANT = { 1 }; /** opt_i16_constant has documentation. */ - static std::experimental::optional const OPT_I16_CONSTANT; - - static std::experimental::optional const OPT_I32_CONSTANT; - - static std::experimental::optional const OPT_I64_CONSTANT; - + static constexpr const std::experimental::optional OPT_I16_CONSTANT = { 2 }; + static constexpr const std::experimental::optional OPT_I32_CONSTANT = { 3 }; + static constexpr const std::experimental::optional OPT_I64_CONSTANT = { 4 }; /** * opt_f32_constant has long documentation. * (Second line of multi-line documentation. * Indented third line of multi-line documentation.) */ - static std::experimental::optional const OPT_F32_CONSTANT; - - static std::experimental::optional const OPT_F64_CONSTANT; - - static std::string const STRING_CONSTANT; - - static std::experimental::optional const OPT_STRING_CONSTANT; + static constexpr const std::experimental::optional OPT_F32_CONSTANT = { 5.0 }; + static constexpr const std::experimental::optional OPT_F64_CONSTANT = { 5.0 }; + static const std::string STRING_CONSTANT; + static const std::experimental::optional OPT_STRING_CONSTANT; + static const ConstantRecord OBJECT_CONSTANT; - static ConstantRecord const OBJECT_CONSTANT; /** * No support for null optional constants diff --git a/test-suite/generated-src/cpp/extended_record_base.hpp b/test-suite/generated-src/cpp/extended_record_base.hpp index 88659bac2..7fb31331f 100644 --- a/test-suite/generated-src/cpp/extended_record_base.hpp +++ b/test-suite/generated-src/cpp/extended_record_base.hpp @@ -12,7 +12,8 @@ struct ExtendedRecord; // Requiring extended class /** Extended record */ struct ExtendedRecordBase { - static ExtendedRecord const EXTENDED_RECORD_CONST; + static const ExtendedRecord EXTENDED_RECORD_CONST; + bool foo; ExtendedRecordBase(bool foo_) diff --git a/test-suite/generated-src/cpp/interface_using_extended_record.hpp b/test-suite/generated-src/cpp/interface_using_extended_record.hpp index 043d23ef2..a1966f48e 100644 --- a/test-suite/generated-src/cpp/interface_using_extended_record.hpp +++ b/test-suite/generated-src/cpp/interface_using_extended_record.hpp @@ -12,7 +12,8 @@ class InterfaceUsingExtendedRecord { public: virtual ~InterfaceUsingExtendedRecord() {} - static RecordUsingExtendedRecord const CR; + static const RecordUsingExtendedRecord CR; + virtual ExtendedRecord meth(const ExtendedRecord & er) = 0; }; diff --git a/test-suite/generated-src/cpp/record_using_extended_record.hpp b/test-suite/generated-src/cpp/record_using_extended_record.hpp index fb9b35ff4..bcf19409c 100644 --- a/test-suite/generated-src/cpp/record_using_extended_record.hpp +++ b/test-suite/generated-src/cpp/record_using_extended_record.hpp @@ -10,7 +10,8 @@ namespace testsuite { struct RecordUsingExtendedRecord final { - static RecordUsingExtendedRecord const CR; + static const RecordUsingExtendedRecord CR; + ExtendedRecord er; RecordUsingExtendedRecord(ExtendedRecord er_)