diff options
author | Vladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com> | 2019-01-15 00:23:42 +0700 |
---|---|---|
committer | Wouter van Oortmerssen <aardappel@gmail.com> | 2019-01-14 09:23:42 -0800 |
commit | 4fa4d367069748c318bfff041d71184dc1199270 (patch) | |
tree | 63c23e003bbd678e13d07f949676c96ec7ef25b0 /src | |
parent | 46208b1e918cfa7e92abc109264e2bc3b3627711 (diff) | |
download | flatbuffers-4fa4d367069748c318bfff041d71184dc1199270.tar.gz flatbuffers-4fa4d367069748c318bfff041d71184dc1199270.tar.bz2 flatbuffers-4fa4d367069748c318bfff041d71184dc1199270.zip |
Add default NaN/Inf to C#, Java, Python (#5107)
* Add default NaN/Inf to C#, Java, Python
* Python NaN/Inf test added
* Remove MSVC2010/13 dependent code
Diffstat (limited to 'src')
-rw-r--r-- | src/code_generators.cpp | 88 | ||||
-rw-r--r-- | src/idl_gen_cpp.cpp | 45 | ||||
-rw-r--r-- | src/idl_gen_general.cpp | 43 | ||||
-rw-r--r-- | src/idl_gen_python.cpp | 15 |
4 files changed, 133 insertions, 58 deletions
diff --git a/src/code_generators.cpp b/src/code_generators.cpp index b78b5ca1..3b10db7f 100644 --- a/src/code_generators.cpp +++ b/src/code_generators.cpp @@ -188,6 +188,94 @@ std::string FloatConstantGenerator::GenFloatConstant( }; } +TypedFloatConstantGenerator::TypedFloatConstantGenerator( + const char *double_prefix, const char *single_prefix, + const char *nan_number, const char *pos_inf_number, + const char *neg_inf_number) + : double_prefix_(double_prefix), + single_prefix_(single_prefix), + nan_number_(nan_number), + pos_inf_number_(pos_inf_number), + neg_inf_number_(neg_inf_number) {} + +std::string TypedFloatConstantGenerator::MakeNaN( + const std::string &prefix) const { + return prefix + nan_number_; +} +std::string TypedFloatConstantGenerator::MakeInf( + bool neg, const std::string &prefix) const { + if (neg) + return !neg_inf_number_.empty() ? (prefix + neg_inf_number_) + : ("-" + prefix + pos_inf_number_); + else + return prefix + pos_inf_number_; +} + +std::string TypedFloatConstantGenerator::Value(double v, + const std::string &src) const { + (void)v; + return src; +} + +std::string TypedFloatConstantGenerator::Inf(double v) const { + return MakeInf(v < 0, double_prefix_); +} + +std::string TypedFloatConstantGenerator::NaN(double v) const { + (void)v; + return MakeNaN(double_prefix_); +} + +std::string TypedFloatConstantGenerator::Value(float v, + const std::string &src) const { + (void)v; + return src + "f"; +} + +std::string TypedFloatConstantGenerator::Inf(float v) const { + return MakeInf(v < 0, single_prefix_); +} + +std::string TypedFloatConstantGenerator::NaN(float v) const { + (void)v; + return MakeNaN(single_prefix_); +} + +SimpleFloatConstantGenerator::SimpleFloatConstantGenerator( + const char *nan_number, const char *pos_inf_number, + const char *neg_inf_number) + : nan_number_(nan_number), + pos_inf_number_(pos_inf_number), + neg_inf_number_(neg_inf_number) {} + +std::string SimpleFloatConstantGenerator::Value(double v, + const std::string &src) const { + (void)v; + return src; +} + +std::string SimpleFloatConstantGenerator::Inf(double v) const { + return (v < 0) ? neg_inf_number_ : pos_inf_number_; +} + +std::string SimpleFloatConstantGenerator::NaN(double v) const { + (void)v; + return nan_number_; +} + +std::string SimpleFloatConstantGenerator::Value(float v, + const std::string &src) const { + return this->Value(static_cast<double>(v), src); +} + +std::string SimpleFloatConstantGenerator::Inf(float v) const { + return this->Inf(static_cast<double>(v)); +} + +std::string SimpleFloatConstantGenerator::NaN(float v) const { + return this->NaN(static_cast<double>(v)); +} + } // namespace flatbuffers #if defined(_MSC_VER) diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 06896d9c..9884081a 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -34,50 +34,15 @@ static std::string GeneratedFileName(const std::string &path, } namespace cpp { -class CppFloatConstantGenerator : public FloatConstantGenerator { - protected: - std::string Value(double v, - const std::string &src) const FLATBUFFERS_OVERRIDE { - (void)v; - return src; - }; - - std::string Value(float v, - const std::string &src) const FLATBUFFERS_OVERRIDE { - (void)v; - return src + "f"; - } - - std::string NaN(double v) const FLATBUFFERS_OVERRIDE { - (void)v; - return "std::numeric_limits<double>::quiet_NaN()"; - } - std::string NaN(float v) const FLATBUFFERS_OVERRIDE { - (void)v; - return "std::numeric_limits<float>::quiet_NaN()"; - } - - std::string Inf(double v) const FLATBUFFERS_OVERRIDE { - if(v < 0) - return "-std::numeric_limits<double>::infinity()"; - else - return "std::numeric_limits<double>::infinity()"; - } - - std::string Inf(float v) const FLATBUFFERS_OVERRIDE { - if (v < 0) - return "-std::numeric_limits<float>::infinity()"; - else - return "std::numeric_limits<float>::infinity()"; - } -}; - class CppGenerator : public BaseGenerator { public: CppGenerator(const Parser &parser, const std::string &path, const std::string &file_name) : BaseGenerator(parser, path, file_name, "", "::"), - cur_name_space_(nullptr) { + cur_name_space_(nullptr), + float_const_gen_("std::numeric_limits<double>::", + "std::numeric_limits<float>::", "quiet_NaN()", + "infinity()") { static const char * const keywords[] = { "alignas", "alignof", @@ -2785,7 +2750,7 @@ class CppGenerator : public BaseGenerator { cur_name_space_ = ns; } - const CppFloatConstantGenerator float_const_gen_; + const TypedFloatConstantGenerator float_const_gen_; }; } // namespace cpp diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp index 66984da0..7c34ee28 100644 --- a/src/idl_gen_general.cpp +++ b/src/idl_gen_general.cpp @@ -58,9 +58,16 @@ struct LanguageParameters { std::string class_annotation; std::string generated_type_annotation; CommentConfig comment_config; + const FloatConstantGenerator *float_gen; }; const LanguageParameters &GetLangParams(IDLOptions::Language lang) { + static TypedFloatConstantGenerator CSharpFloatGen( + "Double.", "Single.", "NaN", "PositiveInfinity", "NegativeInfinity"); + + static TypedFloatConstantGenerator JavaFloatGen( + "Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY"); + static const LanguageParameters language_parameters[] = { { IDLOptions::kJava, @@ -95,6 +102,7 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) { " *", " */", }, + &JavaFloatGen }, { IDLOptions::kCSharp, @@ -128,6 +136,7 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) { "///", nullptr, }, + &CSharpFloatGen }, }; @@ -429,7 +438,8 @@ class GeneralGenerator : public BaseGenerator { return SourceCastBasic(type, true); } - std::string GenEnumDefaultValue(const Value &value) const { + std::string GenEnumDefaultValue(const FieldDef &field) const { + auto& value = field.value; auto enum_def = value.type.enum_def; auto vec = enum_def->vals.vec; auto default_value = StringToInt(value.constant.c_str()); @@ -446,19 +456,19 @@ class GeneralGenerator : public BaseGenerator { return result; } - std::string GenDefaultValue(const Value &value, bool enableLangOverrides) const { + std::string GenDefaultValue(const FieldDef &field, bool enableLangOverrides) const { + auto& value = field.value; if (enableLangOverrides) { // handles both enum case and vector of enum case if (lang_.language == IDLOptions::kCSharp && value.type.enum_def != nullptr && value.type.base_type != BASE_TYPE_UNION) { - return GenEnumDefaultValue(value); + return GenEnumDefaultValue(field); } } auto longSuffix = lang_.language == IDLOptions::kJava ? "L" : ""; switch (value.type.base_type) { - case BASE_TYPE_FLOAT: return value.constant + "f"; case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true"; case BASE_TYPE_ULONG: { if (lang_.language != IDLOptions::kJava) return value.constant; @@ -468,16 +478,21 @@ class GeneralGenerator : public BaseGenerator { } case BASE_TYPE_UINT: case BASE_TYPE_LONG: return value.constant + longSuffix; - default: return value.constant; + default: + if(IsFloat(value.type.base_type)) + return lang_.float_gen->GenFloatConstant(field); + else + return value.constant; } } - std::string GenDefaultValue(const Value &value) const { - return GenDefaultValue(value, true); + std::string GenDefaultValue(const FieldDef &field) const { + return GenDefaultValue(field, true); } - std::string GenDefaultValueBasic(const Value &value, + std::string GenDefaultValueBasic(const FieldDef &field, bool enableLangOverrides) const { + auto& value = field.value; if (!IsScalar(value.type.base_type)) { if (enableLangOverrides) { if (lang_.language == IDLOptions::kCSharp) { @@ -493,11 +508,11 @@ class GeneralGenerator : public BaseGenerator { } return "0"; } - return GenDefaultValue(value, enableLangOverrides); + return GenDefaultValue(field, enableLangOverrides); } - std::string GenDefaultValueBasic(const Value &value) const { - return GenDefaultValueBasic(value, true); + std::string GenDefaultValueBasic(const FieldDef &field) const { + return GenDefaultValueBasic(field, true); } void GenEnum(EnumDef &enum_def, std::string *code_ptr) const { @@ -956,7 +971,7 @@ class GeneralGenerator : public BaseGenerator { code += offset_prefix + getter; code += "(o + " + lang_.accessor_prefix + "bb_pos)" + dest_mask; code += " : " + default_cast; - code += GenDefaultValue(field.value); + code += GenDefaultValue(field); } } else { switch (field.value.type.base_type) { @@ -1278,7 +1293,7 @@ class GeneralGenerator : public BaseGenerator { // supply all arguments, and thus won't compile when fields are added. if (lang_.language != IDLOptions::kJava) { code += " = "; - code += GenDefaultValueBasic(field.value); + code += GenDefaultValueBasic(field); } } code += ") {\n builder."; @@ -1338,7 +1353,7 @@ class GeneralGenerator : public BaseGenerator { code += ", "; if (lang_.language == IDLOptions::kJava) code += SourceCastBasic(field.value.type); - code += GenDefaultValue(field.value, false); + code += GenDefaultValue(field, false); code += "); }\n"; if (field.value.type.base_type == BASE_TYPE_VECTOR) { auto vector_type = field.value.type.VectorType(); diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp index 11491c00..fbb0805c 100644 --- a/src/idl_gen_python.cpp +++ b/src/idl_gen_python.cpp @@ -36,7 +36,8 @@ class PythonGenerator : public BaseGenerator { PythonGenerator(const Parser &parser, const std::string &path, const std::string &file_name) : BaseGenerator(parser, path, file_name, "" /* not used */, - "" /* not used */){ + "" /* not used */), + float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { static const char * const keywords[] = { "False", "None", @@ -191,7 +192,7 @@ class PythonGenerator : public BaseGenerator { code += "(self):"; code += OffsetPrefix(field); getter += "o + self._tab.Pos)"; - auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL; + auto is_bool = IsBool(field.value.type.base_type); if (is_bool) { getter = "bool(" + getter + ")"; } @@ -200,7 +201,9 @@ class PythonGenerator : public BaseGenerator { if (is_bool) { default_value = field.value.constant == "0" ? "False" : "True"; } else { - default_value = field.value.constant; + default_value = IsFloat(field.value.type.base_type) + ? float_const_gen_.GenFloatConstant(field) + : field.value.constant; } code += Indent + Indent + "return " + default_value + "\n\n"; } @@ -452,7 +455,10 @@ class PythonGenerator : public BaseGenerator { } else { code += MakeCamel(NormalizedName(field), false); } - code += ", " + field.value.constant; + code += ", "; + code += IsFloat(field.value.type.base_type) + ? float_const_gen_.GenFloatConstant(field) + : field.value.constant; code += ")\n"; } @@ -715,6 +721,7 @@ class PythonGenerator : public BaseGenerator { } private: std::unordered_set<std::string> keywords_; + const SimpleFloatConstantGenerator float_const_gen_; }; } // namespace python |