Commit 4fa4d367 authored by Vladimir Glavnyy's avatar Vladimir Glavnyy Committed by Wouter van Oortmerssen

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
parent 46208b1e
......@@ -136,27 +136,68 @@ class FloatConstantGenerator {
std::string GenFloatConstant(const FieldDef &field) const;
private:
virtual std::string Value(double v, const std::string &src) const = 0;
virtual std::string Inf(double v) const = 0;
virtual std::string NaN(double v) const = 0;
virtual std::string Value(double v, const std::string &src) const {
(void)v;
return src;
}
virtual std::string Inf(float v) const {
return this->Inf(static_cast<double>(v));
}
virtual std::string NaN(float v) const {
return this->NaN(static_cast<double>(v));
}
virtual std::string Value(float v, const std::string &src) const {
return this->Value(static_cast<double>(v), src);
}
virtual std::string Value(float v, const std::string &src) const = 0;
virtual std::string Inf(float v) const = 0;
virtual std::string NaN(float v) const = 0;
template<typename T>
std::string GenFloatConstantImpl(const FieldDef &field) const;
};
class SimpleFloatConstantGenerator : public FloatConstantGenerator {
public:
SimpleFloatConstantGenerator(const char *nan_number,
const char *pos_inf_number,
const char *neg_inf_number);
private:
std::string Value(double v,
const std::string &src) const FLATBUFFERS_OVERRIDE;
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
const std::string nan_number_;
const std::string pos_inf_number_;
const std::string neg_inf_number_;
};
// C++, C#, Java like generator.
class TypedFloatConstantGenerator : public FloatConstantGenerator {
public:
TypedFloatConstantGenerator(const char *double_prefix,
const char *single_prefix, const char *nan_number,
const char *pos_inf_number,
const char *neg_inf_number = "");
private:
std::string Value(double v,
const std::string &src) const FLATBUFFERS_OVERRIDE;
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
std::string MakeNaN(const std::string &prefix) const;
std::string MakeInf(bool neg, const std::string &prefix) const;
const std::string double_prefix_;
const std::string single_prefix_;
const std::string nan_number_;
const std::string pos_inf_number_;
const std::string neg_inf_number_;
};
} // namespace flatbuffers
#endif // FLATBUFFERS_CODE_GENERATORS_H_
......@@ -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)
......
......@@ -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
......
......@@ -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();
......
......@@ -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
......
......@@ -24,6 +24,7 @@ import NamespaceA.NamespaceB.*;
import com.google.flatbuffers.ByteBufferUtil;
import static com.google.flatbuffers.Constants.*;
import com.google.flatbuffers.FlatBufferBuilder;
import MyGame.MonsterExtra;
class JavaTest {
public static void main(String[] args) {
......
// <auto-generated>
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
namespace MyGame
{
using global::System;
using global::FlatBuffers;
public struct MonsterExtra : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float TestfNan { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
public bool MutateTestfNan(float testf_nan) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_nan); return true; } else { return false; } }
public float TestfPinf { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
public bool MutateTestfPinf(float testf_pinf) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_pinf); return true; } else { return false; } }
public float TestfNinf { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
public bool MutateTestfNinf(float testf_ninf) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_ninf); return true; } else { return false; } }
public double TestdNan { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
public bool MutateTestdNan(double testd_nan) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_nan); return true; } else { return false; } }
public double TestdPinf { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
public bool MutateTestdPinf(double testd_pinf) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_pinf); return true; } else { return false; } }
public double TestdNinf { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
public bool MutateTestdNinf(double testd_ninf) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_ninf); return true; } else { return false; } }
public static Offset<MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
float testf_nan = Single.NaN,
float testf_pinf = Single.PositiveInfinity,
float testf_ninf = Single.NegativeInfinity,
double testd_nan = Double.NaN,
double testd_pinf = Double.PositiveInfinity,
double testd_ninf = Double.NegativeInfinity) {
builder.StartObject(6);
MonsterExtra.AddTestdNinf(builder, testd_ninf);
MonsterExtra.AddTestdPinf(builder, testd_pinf);
MonsterExtra.AddTestdNan(builder, testd_nan);
MonsterExtra.AddTestfNinf(builder, testf_ninf);
MonsterExtra.AddTestfPinf(builder, testf_pinf);
MonsterExtra.AddTestfNan(builder, testf_nan);
return MonsterExtra.EndMonsterExtra(builder);
}
public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartObject(6); }
public static void AddTestfNan(FlatBufferBuilder builder, float testfNan) { builder.AddFloat(0, testfNan, Single.NaN); }
public static void AddTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.AddFloat(1, testfPinf, Single.PositiveInfinity); }
public static void AddTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.AddFloat(2, testfNinf, Single.NegativeInfinity); }
public static void AddTestdNan(FlatBufferBuilder builder, double testdNan) { builder.AddDouble(3, testdNan, Double.NaN); }
public static void AddTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.AddDouble(4, testdPinf, Double.PositiveInfinity); }
public static void AddTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.AddDouble(5, testdNinf, Double.NegativeInfinity); }
public static Offset<MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
int o = builder.EndObject();
return new Offset<MonsterExtra>(o);
}
};
}
// automatically generated by the FlatBuffers compiler, do not modify
package MyGame;
import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;
@SuppressWarnings("unused")public final class MonsterExtra extends Table {
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float testfNan() { int o = __offset(4); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
public boolean mutateTestfNan(float testf_nan) { int o = __offset(4); if (o != 0) { bb.putFloat(o + bb_pos, testf_nan); return true; } else { return false; } }
public float testfPinf() { int o = __offset(6); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
public boolean mutateTestfPinf(float testf_pinf) { int o = __offset(6); if (o != 0) { bb.putFloat(o + bb_pos, testf_pinf); return true; } else { return false; } }
public float testfNinf() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
public boolean mutateTestfNinf(float testf_ninf) { int o = __offset(8); if (o != 0) { bb.putFloat(o + bb_pos, testf_ninf); return true; } else { return false; } }
public double testdNan() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
public boolean mutateTestdNan(double testd_nan) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, testd_nan); return true; } else { return false; } }
public double testdPinf() { int o = __offset(12); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
public boolean mutateTestdPinf(double testd_pinf) { int o = __offset(12); if (o != 0) { bb.putDouble(o + bb_pos, testd_pinf); return true; } else { return false; } }
public double testdNinf() { int o = __offset(14); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
public boolean mutateTestdNinf(double testd_ninf) { int o = __offset(14); if (o != 0) { bb.putDouble(o + bb_pos, testd_ninf); return true; } else { return false; } }
public static int createMonsterExtra(FlatBufferBuilder builder,
float testf_nan,
float testf_pinf,
float testf_ninf,
double testd_nan,
double testd_pinf,
double testd_ninf) {
builder.startObject(6);
MonsterExtra.addTestdNinf(builder, testd_ninf);
MonsterExtra.addTestdPinf(builder, testd_pinf);
MonsterExtra.addTestdNan(builder, testd_nan);
MonsterExtra.addTestfNinf(builder, testf_ninf);
MonsterExtra.addTestfPinf(builder, testf_pinf);
MonsterExtra.addTestfNan(builder, testf_nan);
return MonsterExtra.endMonsterExtra(builder);
}
public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startObject(6); }
public static void addTestfNan(FlatBufferBuilder builder, float testfNan) { builder.addFloat(0, testfNan, Float.NaN); }
public static void addTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.addFloat(1, testfPinf, Float.POSITIVE_INFINITY); }
public static void addTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.addFloat(2, testfNinf, Float.NEGATIVE_INFINITY); }
public static void addTestdNan(FlatBufferBuilder builder, double testdNan) { builder.addDouble(3, testdNan, Double.NaN); }
public static void addTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.addDouble(4, testdPinf, Double.POSITIVE_INFINITY); }
public static void addTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.addDouble(5, testdNinf, Double.NEGATIVE_INFINITY); }
public static int endMonsterExtra(FlatBufferBuilder builder) {
int o = builder.endObject();
return o;
}
}
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: MyGame
import flatbuffers
class MonsterExtra(object):
__slots__ = ['_tab']
@classmethod
def GetRootAsMonsterExtra(cls, buf, offset):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = MonsterExtra()
x.Init(buf, n + offset)
return x
# MonsterExtra
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# MonsterExtra
def TestfNan(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return float('nan')
# MonsterExtra
def TestfPinf(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return float('inf')
# MonsterExtra
def TestfNinf(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return float('-inf')
# MonsterExtra
def TestdNan(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('nan')
# MonsterExtra
def TestdPinf(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('inf')
# MonsterExtra
def TestdNinf(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('-inf')
def MonsterExtraStart(builder): builder.StartObject(6)
def MonsterExtraAddTestfNan(builder, testfNan): builder.PrependFloat32Slot(0, testfNan, float('nan'))
def MonsterExtraAddTestfPinf(builder, testfPinf): builder.PrependFloat32Slot(1, testfPinf, float('inf'))
def MonsterExtraAddTestfNinf(builder, testfNinf): builder.PrependFloat32Slot(2, testfNinf, float('-inf'))
def MonsterExtraAddTestdNan(builder, testdNan): builder.PrependFloat64Slot(3, testdNan, float('nan'))
def MonsterExtraAddTestdPinf(builder, testdPinf): builder.PrependFloat64Slot(4, testdPinf, float('inf'))
def MonsterExtraAddTestdNinf(builder, testdNinf): builder.PrependFloat64Slot(5, testdNinf, float('-inf'))
def MonsterExtraEnd(builder): return builder.EndObject()
......@@ -23,7 +23,7 @@ if "%1"=="-b" set buildtype=%2
IF NOT "%MONSTER_EXTRA%"=="skip" (
@echo Generate MosterExtra
..\%buildtype%\flatc.exe --cpp --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
) else (
@echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
)
......
......@@ -20,7 +20,7 @@ set -e
../flatc --cpp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs
../flatc --jsonschema --schema -I include_test monster_test.fbs
../flatc --cpp --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
cd ../samples
../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins monster.fbs
......
namespace MyGame;
// Not all programmining languages support this extra table.
table MonsterExra {
table MonsterExtra {
// Float-point values with NaN and Inf defaults.
testf_nan:float = nan;
testf_pinf:float = +inf;
......
......@@ -8,22 +8,22 @@
namespace MyGame {
struct MonsterExra;
struct MonsterExraT;
struct MonsterExtra;
struct MonsterExtraT;
bool operator==(const MonsterExraT &lhs, const MonsterExraT &rhs);
bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
inline const flatbuffers::TypeTable *MonsterExraTypeTable();
inline const flatbuffers::TypeTable *MonsterExtraTypeTable();
struct MonsterExraT : public flatbuffers::NativeTable {
typedef MonsterExra TableType;
struct MonsterExtraT : public flatbuffers::NativeTable {
typedef MonsterExtra TableType;
float testf_nan;
float testf_pinf;
float testf_ninf;
double testd_nan;
double testd_pinf;
double testd_ninf;
MonsterExraT()
MonsterExtraT()
: testf_nan(std::numeric_limits<float>::quiet_NaN()),
testf_pinf(std::numeric_limits<float>::infinity()),
testf_ninf(-std::numeric_limits<float>::infinity()),
......@@ -33,7 +33,7 @@ struct MonsterExraT : public flatbuffers::NativeTable {
}
};
inline bool operator==(const MonsterExraT &lhs, const MonsterExraT &rhs) {
inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
return
(lhs.testf_nan == rhs.testf_nan) &&
(lhs.testf_pinf == rhs.testf_pinf) &&
......@@ -43,10 +43,10 @@ inline bool operator==(const MonsterExraT &lhs, const MonsterExraT &rhs) {
(lhs.testd_ninf == rhs.testd_ninf);
}
struct MonsterExra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterExraT NativeTableType;
struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterExtraT NativeTableType;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterExraTypeTable();
return MonsterExtraTypeTable();
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_TESTF_NAN = 4,
......@@ -102,45 +102,45 @@ struct MonsterExra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<double>(verifier, VT_TESTD_NINF) &&
verifier.EndTable();
}
MonsterExraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MonsterExraT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<MonsterExra> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExraT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<MonsterExtra> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct MonsterExraBuilder {
struct MonsterExtraBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_testf_nan(float testf_nan) {
fbb_.AddElement<float>(MonsterExra::VT_TESTF_NAN, testf_nan, std::numeric_limits<float>::quiet_NaN());
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NAN, testf_nan, std::numeric_limits<float>::quiet_NaN());
}
void add_testf_pinf(float testf_pinf) {
fbb_.AddElement<float>(MonsterExra::VT_TESTF_PINF, testf_pinf, std::numeric_limits<float>::infinity());
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_PINF, testf_pinf, std::numeric_limits<float>::infinity());
}
void add_testf_ninf(float testf_ninf) {
fbb_.AddElement<float>(MonsterExra::VT_TESTF_NINF, testf_ninf, -std::numeric_limits<float>::infinity());
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NINF, testf_ninf, -std::numeric_limits<float>::infinity());
}
void add_testd_nan(double testd_nan) {
fbb_.AddElement<double>(MonsterExra::VT_TESTD_NAN, testd_nan, std::numeric_limits<double>::quiet_NaN());
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NAN, testd_nan, std::numeric_limits<double>::quiet_NaN());
}
void add_testd_pinf(double testd_pinf) {
fbb_.AddElement<double>(MonsterExra::VT_TESTD_PINF, testd_pinf, std::numeric_limits<double>::infinity());
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_PINF, testd_pinf, std::numeric_limits<double>::infinity());
}
void add_testd_ninf(double testd_ninf) {
fbb_.AddElement<double>(MonsterExra::VT_TESTD_NINF, testd_ninf, -std::numeric_limits<double>::infinity());
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NINF, testd_ninf, -std::numeric_limits<double>::infinity());
}
explicit MonsterExraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
MonsterExraBuilder &operator=(const MonsterExraBuilder &);
flatbuffers::Offset<MonsterExra> Finish() {
MonsterExtraBuilder &operator=(const MonsterExtraBuilder &);
flatbuffers::Offset<MonsterExtra> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<MonsterExra>(end);
auto o = flatbuffers::Offset<MonsterExtra>(end);
return o;
}
};
inline flatbuffers::Offset<MonsterExra> CreateMonsterExra(
inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(
flatbuffers::FlatBufferBuilder &_fbb,
float testf_nan = std::numeric_limits<float>::quiet_NaN(),
float testf_pinf = std::numeric_limits<float>::infinity(),
......@@ -148,7 +148,7 @@ inline flatbuffers::Offset<MonsterExra> CreateMonsterExra(
double testd_nan = std::numeric_limits<double>::quiet_NaN(),
double testd_pinf = std::numeric_limits<double>::infinity(),
double testd_ninf = -std::numeric_limits<double>::infinity()) {
MonsterExraBuilder builder_(_fbb);
MonsterExtraBuilder builder_(_fbb);
builder_.add_testd_ninf(testd_ninf);
builder_.add_testd_pinf(testd_pinf);
builder_.add_testd_nan(testd_nan);
......@@ -158,15 +158,15 @@ inline flatbuffers::Offset<MonsterExra> CreateMonsterExra(
return builder_.Finish();
}
flatbuffers::Offset<MonsterExra> CreateMonsterExra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline MonsterExraT *MonsterExra::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new MonsterExraT();
inline MonsterExtraT *MonsterExtra::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = new MonsterExtraT();
UnPackTo(_o, _resolver);
return _o;
}
inline void MonsterExra::UnPackTo(MonsterExraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = testf_nan(); _o->testf_nan = _e; };
......@@ -177,21 +177,21 @@ inline void MonsterExra::UnPackTo(MonsterExraT *_o, const flatbuffers::resolver_
{ auto _e = testd_ninf(); _o->testd_ninf = _e; };
}
inline flatbuffers::Offset<MonsterExra> MonsterExra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateMonsterExra(_fbb, _o, _rehasher);
inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateMonsterExtra(_fbb, _o, _rehasher);
}
inline flatbuffers::Offset<MonsterExra> CreateMonsterExra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExraT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExtraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _testf_nan = _o->testf_nan;
auto _testf_pinf = _o->testf_pinf;
auto _testf_ninf = _o->testf_ninf;
auto _testd_nan = _o->testd_nan;
auto _testd_pinf = _o->testd_pinf;
auto _testd_ninf = _o->testd_ninf;
return MyGame::CreateMonsterExra(
return MyGame::CreateMonsterExtra(
_fbb,
_testf_nan,
_testf_pinf,
......@@ -201,7 +201,7 @@ inline flatbuffers::Offset<MonsterExra> CreateMonsterExra(flatbuffers::FlatBuffe
_testd_ninf);
}
inline const flatbuffers::TypeTable *MonsterExraTypeTable() {
inline const flatbuffers::TypeTable *MonsterExtraTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
......
......@@ -20,10 +20,10 @@ PY_VERSION = sys.version_info[:2]
import ctypes
from collections import defaultdict
import math
import timeit
import unittest
from flatbuffers import compat
from flatbuffers import util
from flatbuffers.compat import range_func as compat_range
......@@ -40,6 +40,7 @@ import MyGame.Example.Monster # refers to generated code
import MyGame.Example.Test # refers to generated code
import MyGame.Example.Stat # refers to generated code
import MyGame.Example.Vec3 # refers to generated code
import MyGame.MonsterExtra # refers to generated code
def assertRaises(test_case, fn, exception_class):
......@@ -1395,6 +1396,27 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
self.assertEqual(12345, stat2.Count())
class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
def setUp(self, *args, **kwargs):
super(TestAllCodePathsOfMonsterExtraSchema, self).setUp(*args, **kwargs)
b = flatbuffers.Builder(0)
MyGame.MonsterExtra.MonsterExtraStart(b)
gen_mon = MyGame.MonsterExtra.MonsterExtraEnd(b)
b.Finish(gen_mon)
self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
def test_default_nan_inf(self):
self.assertTrue(math.isnan(self.mon.TestfNan()))
self.assertEqual(self.mon.TestfPinf(), float("inf"))
self.assertEqual(self.mon.TestfNinf(), float("-inf"))
self.assertTrue(math.isnan(self.mon.TestdNan()))
self.assertEqual(self.mon.TestdPinf(), float("inf"))
self.assertEqual(self.mon.TestdNinf(), float("-inf"))
class TestVtableDeduplication(unittest.TestCase):
''' TestVtableDeduplication verifies that vtables are deduplicated. '''
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment