summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVladimir Glavnyy <31897320+vglavnyy@users.noreply.github.com>2019-01-15 00:23:42 +0700
committerWouter van Oortmerssen <aardappel@gmail.com>2019-01-14 09:23:42 -0800
commit4fa4d367069748c318bfff041d71184dc1199270 (patch)
tree63c23e003bbd678e13d07f949676c96ec7ef25b0 /src
parent46208b1e918cfa7e92abc109264e2bc3b3627711 (diff)
downloadflatbuffers-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.cpp88
-rw-r--r--src/idl_gen_cpp.cpp45
-rw-r--r--src/idl_gen_general.cpp43
-rw-r--r--src/idl_gen_python.cpp15
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