Extend the test of MonsterExtra (#5428)

* Extend the test of MonsterExtra

- Extend C++ test of MonsterExtra
- Add conversion of fbs/json NaNs to unsigned quiet-NaN
- Update documentation (cross-platform interoperability)

* Fix declaration of infinity constants int the test
This commit is contained in:
Vladimir Glavnyy 2019-07-09 01:22:56 +07:00 committed by Wouter van Oortmerssen
parent 47c7aa0361
commit e304f8c115
13 changed files with 654 additions and 409 deletions

View File

@ -35,7 +35,7 @@ The test code itself is located in
[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp). [test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
This test file is built alongside `flatc`. To review how to build the project, This test file is built alongside `flatc`. To review how to build the project,
please read the [Building](@ref flatbuffers_guide_building) documenation. please read the [Building](@ref flatbuffers_guide_building) documentation.
To run the tests, execute `flattests` from the root `flatbuffers/` directory. To run the tests, execute `flattests` from the root `flatbuffers/` directory.
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
@ -546,21 +546,63 @@ locale-independent or locale-narrow functions `strtof_l`, `strtod_l`,
These functions use specified locale rather than the global or per-thread These functions use specified locale rather than the global or per-thread
locale instead. They are part of POSIX-2008 but not part of the C/C++ locale instead. They are part of POSIX-2008 but not part of the C/C++
standard library, therefore, may be missing on some platforms. standard library, therefore, may be missing on some platforms.
The Flatbuffers library try to detect these functions at configuration and The Flatbuffers library try to detect these functions at configuration and
compile time: compile time:
- `_MSC_VER >= 1900`: check MSVC2012 or higher for MSVC buid - CMake `"CMakeLists.txt"`:
- `_XOPEN_SOURCE>=700`: check POSIX-2008 for GCC/Clang build - Check existence of `strtol_l` and `strtod_l` in the `<stdlib.h>`.
- `check_cxx_symbol_exists(strtof_l stdlib.h)`: CMake check of `strtod_f` - Compile-time `"/include/base.h"`:
- `_MSC_VER >= 1900`: MSVC2012 or higher if build with MSVC.
- `_XOPEN_SOURCE>=700`: POSIX-2008 if build with GCC/Clang.
After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
set to `0` or `1`. set to `0` or `1`.
To override or stop this detection use CMake `-DFLATBUFFERS_LOCALE_INDEPENDENT={0|1}`
or predefine `FLATBUFFERS_LOCALE_INDEPENDENT` symbol.
It is possible to test the compatibility of the Flatbuffers library with To test the compatibility of the Flatbuffers library with
a specific locale using the environment variable `FLATBUFFERS_TEST_LOCALE`: a specific locale use the environment variable `FLATBUFFERS_TEST_LOCALE`:
```sh ```sh
>FLATBUFFERS_TEST_LOCALE="" ./flattests >FLATBUFFERS_TEST_LOCALE="" ./flattests
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests >FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
``` ```
## Support of floating-point numbers
The Flatbuffers library assumes that a C++ compiler and a CPU are
compatible with the `IEEE-754` floating-point standard.
The schema and json parser may fail if `fast-math` or `/fp:fast` mode is active.
### Support of hexadecimal and special floating-point numbers
According to the [grammar](@ref flatbuffers_grammar) `fbs` and `json` files
may use hexadecimal and special (`NaN`, `Inf`) floating-point literals.
The Flatbuffers uses `strtof` and `strtod` functions to parse floating-point
literals. The Flatbuffers library has a code to detect a compiler compatibility
with the literals. If necessary conditions are met the preprocessor constant
`FLATBUFFERS_HAS_NEW_STRTOD` will be set to `1`.
The support of floating-point literals will be limited at compile time
if `FLATBUFFERS_HAS_NEW_STRTOD` constant is less than `1`.
In this case, schemas with hexadecimal or special literals cannot be used.
### Comparison of floating-point NaN values
The floating-point `NaN` (`not a number`) is special value which
representing an undefined or unrepresentable value.
`NaN` may be explicitly assigned to variables, typically as a representation
for missing values or may be a result of a mathematical operation.
The `IEEE-754` defines two kind of `NaNs`:
- Quiet NaNs, or `qNaNs`.
- Signaling NaNs, or `sNaNs`.
According to the `IEEE-754`, a comparison with `NaN` always returns
an unordered result even when compared with itself. As a result, a whole
Flatbuffers object will be not equal to itself if has one or more `NaN`.
Flatbuffers scalar fields that have the default value are not actually stored
in the serialized data but are generated in code (see [Writing a schema](@ref flatbuffers_guide_writing_schema)).
Scalar fields with `NaN` defaults break this behavior.
If a schema has a lot of `NaN` defaults the Flatbuffers can override
the unordered comparison by the ordered: `(NaN==NaN)->true`.
This ordered comparison is enabled when compiling a program with the symbol
`FLATBUFFERS_NAN_DEFAULTS` defined.
Additional computations added by `FLATBUFFERS_NAN_DEFAULTS` are very cheap
if GCC or Clang used. These compilers have a compile-time implementation
of `isnan` checking which MSVC does not.
<br> <br>

View File

@ -15,6 +15,12 @@ all commonly used CPUs today. FlatBuffers will also work on big-endian
machines, but will be slightly slower because of additional machines, but will be slightly slower because of additional
byte-swap intrinsics. byte-swap intrinsics.
It is assumed that the following conditions are met, to ensure
cross-platform interoperability:
- The binary `IEEE-754` format is used for floating-point numbers.
- The `two's complemented` representation is used for signed integers.
- The endianness is the same for floating-point numbers as for integers.
On purpose, the format leaves a lot of details about where exactly On purpose, the format leaves a lot of details about where exactly
things live in memory undefined, e.g. fields in a table can have any things live in memory undefined, e.g. fields in a table can have any
order, and objects to some extent can be stored in many orders. This is order, and objects to some extent can be stored in many orders. This is

View File

@ -439,14 +439,19 @@ numerical literals:
For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals. For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
- The format of float-point numbers is fully compatible with C/C++ format. - The format of float-point numbers is fully compatible with C/C++ format.
If a modern C++ compiler is used the parser accepts hexadecimal and special If a modern C++ compiler is used the parser accepts hexadecimal and special
float-point literals as well: floating-point literals as well:
`[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`. `[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
The exponent suffix of hexadecimal float-point number is mandatory.
Extended float-point support was tested with: The following conventions for floating-point numbers are used:
- The exponent suffix of hexadecimal floating-point number is mandatory.
- Parsed `NaN` converted to unsigned IEEE-754 `quiet-NaN` value.
Extended floating-point support was tested with:
- x64 Windows: `MSVC2015` and higher. - x64 Windows: `MSVC2015` and higher.
- x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher. - x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
For details, see [Use in C++](@ref flatbuffers_guide_use_cpp) section.
- For compatibility with a JSON lint tool all numeric literals of scalar - For compatibility with a JSON lint tool all numeric literals of scalar
fields can be wrapped to quoted string: fields can be wrapped to quoted string:
`"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`. `"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.

View File

@ -25,16 +25,21 @@
namespace flatbuffers { namespace flatbuffers {
// Generic 'operator==' with conditional specialisations. // Generic 'operator==' with conditional specialisations.
// T e - new value of a scalar field.
// T def - default of scalar (is known at compile-time).
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; } template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \ #if defined(FLATBUFFERS_NAN_DEFAULTS) && \
(!defined(_MSC_VER) || _MSC_VER >= 1800) defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Like `operator==(e, def)` with weak NaN if T=(float|double). // Like `operator==(e, def)` with weak NaN if T=(float|double).
template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
return (e == def) || ((def != def) && (e != e));
}
template<> inline bool IsTheSameAs<float>(float e, float def) { template<> inline bool IsTheSameAs<float>(float e, float def) {
return (e == def) || (std::isnan(def) && std::isnan(e)); return IsFloatTheSameAs(e, def);
} }
template<> inline bool IsTheSameAs<double>(double e, double def) { template<> inline bool IsTheSameAs<double>(double e, double def) {
return (e == def) || (std::isnan(def) && std::isnan(e)); return IsFloatTheSameAs(e, def);
} }
#endif #endif

View File

@ -19,7 +19,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <math.h> #include <cmath>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
@ -1525,6 +1525,21 @@ CheckedError Parser::TokenError() {
return Error("cannot parse value starting with: " + TokenToStringId(token_)); return Error("cannot parse value starting with: " + TokenToStringId(token_));
} }
// Re-pack helper (ParseSingleValue) to normalize defaults of scalars.
template<typename T> inline void SingleValueRepack(Value &e, T val) {
// Remove leading zeros.
if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); }
}
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Normilaze defaults NaN to unsigned quiet-NaN(0).
static inline void SingleValueRepack(Value& e, float val) {
if (val != val) e.constant = "nan";
}
static inline void SingleValueRepack(Value& e, double val) {
if (val != val) e.constant = "nan";
}
#endif
CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
bool check_now) { bool check_now) {
// First see if this could be a conversion function: // First see if this could be a conversion function:
@ -1569,96 +1584,94 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
} }
auto match = false; auto match = false;
const auto in_type = e.type.base_type;
// clang-format off // clang-format off
#define TRY_ECHECK(force, dtoken, check, req) \ #define IF_ECHECK_(force, dtoken, check, req) \
if (!match && ((check) || IsConstTrue(force))) \ if (!match && ((check) || IsConstTrue(force))) \
ECHECK(TryTypedValue(name, dtoken, check, e, req, &match)) ECHECK(TryTypedValue(name, dtoken, check, e, req, &match))
#define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req)
#define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req)
// clang-format on // clang-format on
if (token_ == kTokenStringConstant || token_ == kTokenIdentifier) { if (token_ == kTokenStringConstant || token_ == kTokenIdentifier) {
const auto kTokenStringOrIdent = token_; const auto kTokenStringOrIdent = token_;
// The string type is a most probable type, check it first. // The string type is a most probable type, check it first.
TRY_ECHECK(false, kTokenStringConstant, TRY_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
e.type.base_type == BASE_TYPE_STRING, BASE_TYPE_STRING); BASE_TYPE_STRING);
// avoid escaped and non-ascii in the string // avoid escaped and non-ascii in the string
if ((token_ == kTokenStringConstant) && IsScalar(e.type.base_type) && if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type) &&
!attr_is_trivial_ascii_string_) { !attr_is_trivial_ascii_string_) {
return Error( return Error(
std::string("type mismatch or invalid value, an initializer of " std::string("type mismatch or invalid value, an initializer of "
"non-string field must be trivial ASCII string: type: ") + "non-string field must be trivial ASCII string: type: ") +
kTypeNames[e.type.base_type] + ", name: " + (name ? *name : "") + kTypeNames[in_type] + ", name: " + (name ? *name : "") +
", value: " + attribute_); ", value: " + attribute_);
} }
// A boolean as true/false. Boolean as Integer check below. // A boolean as true/false. Boolean as Integer check below.
if (!match && IsBool(e.type.base_type)) { if (!match && IsBool(in_type)) {
auto is_true = attribute_ == "true"; auto is_true = attribute_ == "true";
if (is_true || attribute_ == "false") { if (is_true || attribute_ == "false") {
attribute_ = is_true ? "1" : "0"; attribute_ = is_true ? "1" : "0";
// accepts both kTokenStringConstant and kTokenIdentifier // accepts both kTokenStringConstant and kTokenIdentifier
TRY_ECHECK(false, kTokenStringOrIdent, IsBool(e.type.base_type), TRY_ECHECK(kTokenStringOrIdent, IsBool(in_type), BASE_TYPE_BOOL);
BASE_TYPE_BOOL);
} }
} }
// Check if this could be a string/identifier enum value. // Check if this could be a string/identifier enum value.
// Enum can have only true integer base type. // Enum can have only true integer base type.
if (!match && IsInteger(e.type.base_type) && !IsBool(e.type.base_type) && if (!match && IsInteger(in_type) && !IsBool(in_type) &&
IsIdentifierStart(*attribute_.c_str())) { IsIdentifierStart(*attribute_.c_str())) {
ECHECK(ParseEnumFromString(e.type, &e.constant)); ECHECK(ParseEnumFromString(e.type, &e.constant));
NEXT(); NEXT();
match = true; match = true;
} }
// float/integer number in string // Parse a float/integer number from the string.
if ((token_ == kTokenStringConstant) && IsScalar(e.type.base_type)) { if (!match) check_now = true; // Re-pack if parsed from string literal.
if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type)) {
// remove trailing whitespaces from attribute_ // remove trailing whitespaces from attribute_
auto last = attribute_.find_last_not_of(' '); auto last = attribute_.find_last_not_of(' ');
if (std::string::npos != last) // has non-whitespace if (std::string::npos != last) // has non-whitespace
attribute_.resize(last + 1); attribute_.resize(last + 1);
} }
// Float numbers or nan, inf, pi, etc. // Float numbers or nan, inf, pi, etc.
TRY_ECHECK(false, kTokenStringOrIdent, IsFloat(e.type.base_type), TRY_ECHECK(kTokenStringOrIdent, IsFloat(in_type), BASE_TYPE_FLOAT);
BASE_TYPE_FLOAT);
// An integer constant in string. // An integer constant in string.
TRY_ECHECK(false, kTokenStringOrIdent, IsInteger(e.type.base_type), TRY_ECHECK(kTokenStringOrIdent, IsInteger(in_type), BASE_TYPE_INT);
BASE_TYPE_INT);
// Unknown tokens will be interpreted as string type. // Unknown tokens will be interpreted as string type.
TRY_ECHECK(true, kTokenStringConstant, e.type.base_type == BASE_TYPE_STRING, FORCE_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
BASE_TYPE_STRING); BASE_TYPE_STRING);
} else { } else {
// Try a float number. // Try a float number.
TRY_ECHECK(false, kTokenFloatConstant, IsFloat(e.type.base_type), TRY_ECHECK(kTokenFloatConstant, IsFloat(in_type), BASE_TYPE_FLOAT);
BASE_TYPE_FLOAT);
// Integer token can init any scalar (integer of float). // Integer token can init any scalar (integer of float).
TRY_ECHECK(true, kTokenIntegerConstant, IsScalar(e.type.base_type), FORCE_ECHECK(kTokenIntegerConstant, IsScalar(in_type), BASE_TYPE_INT);
BASE_TYPE_INT);
} }
#undef TRY_ECHECK #undef FORCE_ECHECK
#undef TRY_ECHECK
#undef IF_ECHECK_
if (!match) return TokenError(); if (!match) return TokenError();
const auto match_type = e.type.base_type; // may differ from in_type
// The check_now flag must be true when parse a fbs-schema. // The check_now flag must be true when parse a fbs-schema.
// This flag forces to check default scalar values or metadata of field. // This flag forces to check default scalar values or metadata of field.
// For JSON parser the flag should be false. // For JSON parser the flag should be false.
// If it is set for JSON each value will be checked twice (see ParseTable). // If it is set for JSON each value will be checked twice (see ParseTable).
if (check_now && IsScalar(e.type.base_type)) { if (check_now && IsScalar(match_type)) {
// "re-pack" an integer scalar to remove any ambiguities like leading zeros
// which can be treated as octal-literal (idl_gen_cpp/GenDefaultConstant).
const auto repack = IsInteger(e.type.base_type);
switch (e.type.base_type) {
// clang-format off // clang-format off
switch (match_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
case BASE_TYPE_ ## ENUM: {\ case BASE_TYPE_ ## ENUM: {\
CTYPE val; \ CTYPE val; \
ECHECK(atot(e.constant.c_str(), *this, &val)); \ ECHECK(atot(e.constant.c_str(), *this, &val)); \
if(repack) e.constant = NumToString(val); \ SingleValueRepack(e, val); \
break; } break; }
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
default: break; default: break;
// clang-format on
} }
// clang-format on
} }
return NoError(); return NoError();
} }
@ -3031,7 +3044,7 @@ static Namespace *GetNamespace(
for (;;) { for (;;) {
dot = qualified_name.find('.', pos); dot = qualified_name.find('.', pos);
if (dot == std::string::npos) { break; } if (dot == std::string::npos) { break; }
ns->components.push_back(qualified_name.substr(pos, dot-pos)); ns->components.push_back(qualified_name.substr(pos, dot - pos));
pos = dot + 1; pos = dot + 1;
} }
} }

View File

@ -19,73 +19,83 @@ public struct MonsterExtra : IFlatbufferObject
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } 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 double D0 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.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 bool MutateD0(double d0) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d0); 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 double D1 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
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 bool MutateD1(double d1) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d1); 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 double D2 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
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 bool MutateD2(double d2) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d2); 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 double D3 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
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 bool MutateD3(double d3) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d3); 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 float F0 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
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 bool MutateF0(float f0) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f0); 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 float F1 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
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 bool MutateF1(float f1) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f1); return true; } else { return false; } }
public float TestfVec(int j) { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; } public float F2 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
public int TestfVecLength { get { int o = __p.__offset(16); return o != 0 ? __p.__vector_len(o) : 0; } } public bool MutateF2(float f2) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f2); return true; } else { return false; } }
public float F3 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
public bool MutateF3(float f3) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f3); return true; } else { return false; } }
public double Dvec(int j) { int o = __p.__offset(20); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
public int DvecLength { get { int o = __p.__offset(20); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T
public Span<byte> GetTestfVecBytes() { return __p.__vector_as_span(16); } public Span<byte> GetDvecBytes() { return __p.__vector_as_span(20); }
#else #else
public ArraySegment<byte>? GetTestfVecBytes() { return __p.__vector_as_arraysegment(16); } public ArraySegment<byte>? GetDvecBytes() { return __p.__vector_as_arraysegment(20); }
#endif #endif
public float[] GetTestfVecArray() { return __p.__vector_as_array<float>(16); } public double[] GetDvecArray() { return __p.__vector_as_array<double>(20); }
public bool MutateTestfVec(int j, float testf_vec) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, testf_vec); return true; } else { return false; } } public bool MutateDvec(int j, double dvec) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, dvec); return true; } else { return false; } }
public double TestdVec(int j) { int o = __p.__offset(18); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; } public float Fvec(int j) { int o = __p.__offset(22); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; }
public int TestdVecLength { get { int o = __p.__offset(18); return o != 0 ? __p.__vector_len(o) : 0; } } public int FvecLength { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T #if ENABLE_SPAN_T
public Span<byte> GetTestdVecBytes() { return __p.__vector_as_span(18); } public Span<byte> GetFvecBytes() { return __p.__vector_as_span(22); }
#else #else
public ArraySegment<byte>? GetTestdVecBytes() { return __p.__vector_as_arraysegment(18); } public ArraySegment<byte>? GetFvecBytes() { return __p.__vector_as_arraysegment(22); }
#endif #endif
public double[] GetTestdVecArray() { return __p.__vector_as_array<double>(18); } public float[] GetFvecArray() { return __p.__vector_as_array<float>(22); }
public bool MutateTestdVec(int j, double testd_vec) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, testd_vec); return true; } else { return false; } } public bool MutateFvec(int j, float fvec) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, fvec); return true; } else { return false; } }
public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder, public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
float testf_nan = Single.NaN, double d0 = Double.NaN,
float testf_pinf = Single.PositiveInfinity, double d1 = Double.NaN,
float testf_ninf = Single.NegativeInfinity, double d2 = Double.PositiveInfinity,
double testd_nan = Double.NaN, double d3 = Double.NegativeInfinity,
double testd_pinf = Double.PositiveInfinity, float f0 = Single.NaN,
double testd_ninf = Double.NegativeInfinity, float f1 = Single.NaN,
VectorOffset testf_vecOffset = default(VectorOffset), float f2 = Single.PositiveInfinity,
VectorOffset testd_vecOffset = default(VectorOffset)) { float f3 = Single.NegativeInfinity,
builder.StartTable(8); VectorOffset dvecOffset = default(VectorOffset),
MonsterExtra.AddTestdNinf(builder, testd_ninf); VectorOffset fvecOffset = default(VectorOffset)) {
MonsterExtra.AddTestdPinf(builder, testd_pinf); builder.StartTable(10);
MonsterExtra.AddTestdNan(builder, testd_nan); MonsterExtra.AddD3(builder, d3);
MonsterExtra.AddTestdVec(builder, testd_vecOffset); MonsterExtra.AddD2(builder, d2);
MonsterExtra.AddTestfVec(builder, testf_vecOffset); MonsterExtra.AddD1(builder, d1);
MonsterExtra.AddTestfNinf(builder, testf_ninf); MonsterExtra.AddD0(builder, d0);
MonsterExtra.AddTestfPinf(builder, testf_pinf); MonsterExtra.AddFvec(builder, fvecOffset);
MonsterExtra.AddTestfNan(builder, testf_nan); MonsterExtra.AddDvec(builder, dvecOffset);
MonsterExtra.AddF3(builder, f3);
MonsterExtra.AddF2(builder, f2);
MonsterExtra.AddF1(builder, f1);
MonsterExtra.AddF0(builder, f0);
return MonsterExtra.EndMonsterExtra(builder); return MonsterExtra.EndMonsterExtra(builder);
} }
public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(8); } public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(10); }
public static void AddTestfNan(FlatBufferBuilder builder, float testfNan) { builder.AddFloat(0, testfNan, Single.NaN); } public static void AddD0(FlatBufferBuilder builder, double d0) { builder.AddDouble(0, d0, Double.NaN); }
public static void AddTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.AddFloat(1, testfPinf, Single.PositiveInfinity); } public static void AddD1(FlatBufferBuilder builder, double d1) { builder.AddDouble(1, d1, Double.NaN); }
public static void AddTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.AddFloat(2, testfNinf, Single.NegativeInfinity); } public static void AddD2(FlatBufferBuilder builder, double d2) { builder.AddDouble(2, d2, Double.PositiveInfinity); }
public static void AddTestdNan(FlatBufferBuilder builder, double testdNan) { builder.AddDouble(3, testdNan, Double.NaN); } public static void AddD3(FlatBufferBuilder builder, double d3) { builder.AddDouble(3, d3, Double.NegativeInfinity); }
public static void AddTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.AddDouble(4, testdPinf, Double.PositiveInfinity); } public static void AddF0(FlatBufferBuilder builder, float f0) { builder.AddFloat(4, f0, Single.NaN); }
public static void AddTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.AddDouble(5, testdNinf, Double.NegativeInfinity); } public static void AddF1(FlatBufferBuilder builder, float f1) { builder.AddFloat(5, f1, Single.NaN); }
public static void AddTestfVec(FlatBufferBuilder builder, VectorOffset testfVecOffset) { builder.AddOffset(6, testfVecOffset.Value, 0); } public static void AddF2(FlatBufferBuilder builder, float f2) { builder.AddFloat(6, f2, Single.PositiveInfinity); }
public static VectorOffset CreateTestfVecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); } public static void AddF3(FlatBufferBuilder builder, float f3) { builder.AddFloat(7, f3, Single.NegativeInfinity); }
public static VectorOffset CreateTestfVecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); } public static void AddDvec(FlatBufferBuilder builder, VectorOffset dvecOffset) { builder.AddOffset(8, dvecOffset.Value, 0); }
public static void StartTestfVecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); } public static VectorOffset CreateDvecVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
public static void AddTestdVec(FlatBufferBuilder builder, VectorOffset testdVecOffset) { builder.AddOffset(7, testdVecOffset.Value, 0); } public static VectorOffset CreateDvecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
public static VectorOffset CreateTestdVecVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); } public static void StartDvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
public static VectorOffset CreateTestdVecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); } public static void AddFvec(FlatBufferBuilder builder, VectorOffset fvecOffset) { builder.AddOffset(9, fvecOffset.Value, 0); }
public static void StartTestdVecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); } public static VectorOffset CreateFvecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); }
public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartFvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) { public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
int o = builder.EndTable(); int o = builder.EndTable();
return new Offset<MyGame.MonsterExtra>(o); return new Offset<MyGame.MonsterExtra>(o);

View File

@ -16,63 +16,73 @@ public final class MonsterExtra extends Table {
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } 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 double d0() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : Double.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 boolean mutateD0(double d0) { int o = __offset(4); if (o != 0) { bb.putDouble(o + bb_pos, d0); return true; } else { return false; } }
public float testfPinf() { int o = __offset(6); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; } public double d1() { int o = __offset(6); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
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 boolean mutateD1(double d1) { int o = __offset(6); if (o != 0) { bb.putDouble(o + bb_pos, d1); return true; } else { return false; } }
public float testfNinf() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; } public double d2() { int o = __offset(8); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_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 boolean mutateD2(double d2) { int o = __offset(8); if (o != 0) { bb.putDouble(o + bb_pos, d2); return true; } else { return false; } }
public double testdNan() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; } public double d3() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
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 boolean mutateD3(double d3) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, d3); return true; } else { return false; } }
public double testdPinf() { int o = __offset(12); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; } public float f0() { int o = __offset(12); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
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 boolean mutateF0(float f0) { int o = __offset(12); if (o != 0) { bb.putFloat(o + bb_pos, f0); return true; } else { return false; } }
public double testdNinf() { int o = __offset(14); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; } public float f1() { int o = __offset(14); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
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 boolean mutateF1(float f1) { int o = __offset(14); if (o != 0) { bb.putFloat(o + bb_pos, f1); return true; } else { return false; } }
public float testfVec(int j) { int o = __offset(16); return o != 0 ? bb.getFloat(__vector(o) + j * 4) : 0; } public float f2() { int o = __offset(16); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
public int testfVecLength() { int o = __offset(16); return o != 0 ? __vector_len(o) : 0; } public boolean mutateF2(float f2) { int o = __offset(16); if (o != 0) { bb.putFloat(o + bb_pos, f2); return true; } else { return false; } }
public ByteBuffer testfVecAsByteBuffer() { return __vector_as_bytebuffer(16, 4); } public float f3() { int o = __offset(18); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
public ByteBuffer testfVecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 16, 4); } public boolean mutateF3(float f3) { int o = __offset(18); if (o != 0) { bb.putFloat(o + bb_pos, f3); return true; } else { return false; } }
public boolean mutateTestfVec(int j, float testf_vec) { int o = __offset(16); if (o != 0) { bb.putFloat(__vector(o) + j * 4, testf_vec); return true; } else { return false; } } public double dvec(int j) { int o = __offset(20); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
public double testdVec(int j) { int o = __offset(18); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; } public int dvecLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; }
public int testdVecLength() { int o = __offset(18); return o != 0 ? __vector_len(o) : 0; } public ByteBuffer dvecAsByteBuffer() { return __vector_as_bytebuffer(20, 8); }
public ByteBuffer testdVecAsByteBuffer() { return __vector_as_bytebuffer(18, 8); } public ByteBuffer dvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 8); }
public ByteBuffer testdVecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 18, 8); } public boolean mutateDvec(int j, double dvec) { int o = __offset(20); if (o != 0) { bb.putDouble(__vector(o) + j * 8, dvec); return true; } else { return false; } }
public boolean mutateTestdVec(int j, double testd_vec) { int o = __offset(18); if (o != 0) { bb.putDouble(__vector(o) + j * 8, testd_vec); return true; } else { return false; } } public float fvec(int j) { int o = __offset(22); return o != 0 ? bb.getFloat(__vector(o) + j * 4) : 0; }
public int fvecLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
public ByteBuffer fvecAsByteBuffer() { return __vector_as_bytebuffer(22, 4); }
public ByteBuffer fvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); }
public boolean mutateFvec(int j, float fvec) { int o = __offset(22); if (o != 0) { bb.putFloat(__vector(o) + j * 4, fvec); return true; } else { return false; } }
public static int createMonsterExtra(FlatBufferBuilder builder, public static int createMonsterExtra(FlatBufferBuilder builder,
float testf_nan, double d0,
float testf_pinf, double d1,
float testf_ninf, double d2,
double testd_nan, double d3,
double testd_pinf, float f0,
double testd_ninf, float f1,
int testf_vecOffset, float f2,
int testd_vecOffset) { float f3,
builder.startTable(8); int dvecOffset,
MonsterExtra.addTestdNinf(builder, testd_ninf); int fvecOffset) {
MonsterExtra.addTestdPinf(builder, testd_pinf); builder.startTable(10);
MonsterExtra.addTestdNan(builder, testd_nan); MonsterExtra.addD3(builder, d3);
MonsterExtra.addTestdVec(builder, testd_vecOffset); MonsterExtra.addD2(builder, d2);
MonsterExtra.addTestfVec(builder, testf_vecOffset); MonsterExtra.addD1(builder, d1);
MonsterExtra.addTestfNinf(builder, testf_ninf); MonsterExtra.addD0(builder, d0);
MonsterExtra.addTestfPinf(builder, testf_pinf); MonsterExtra.addFvec(builder, fvecOffset);
MonsterExtra.addTestfNan(builder, testf_nan); MonsterExtra.addDvec(builder, dvecOffset);
MonsterExtra.addF3(builder, f3);
MonsterExtra.addF2(builder, f2);
MonsterExtra.addF1(builder, f1);
MonsterExtra.addF0(builder, f0);
return MonsterExtra.endMonsterExtra(builder); return MonsterExtra.endMonsterExtra(builder);
} }
public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startTable(8); } public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startTable(10); }
public static void addTestfNan(FlatBufferBuilder builder, float testfNan) { builder.addFloat(0, testfNan, Float.NaN); } public static void addD0(FlatBufferBuilder builder, double d0) { builder.addDouble(0, d0, Double.NaN); }
public static void addTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.addFloat(1, testfPinf, Float.POSITIVE_INFINITY); } public static void addD1(FlatBufferBuilder builder, double d1) { builder.addDouble(1, d1, Double.NaN); }
public static void addTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.addFloat(2, testfNinf, Float.NEGATIVE_INFINITY); } public static void addD2(FlatBufferBuilder builder, double d2) { builder.addDouble(2, d2, Double.POSITIVE_INFINITY); }
public static void addTestdNan(FlatBufferBuilder builder, double testdNan) { builder.addDouble(3, testdNan, Double.NaN); } public static void addD3(FlatBufferBuilder builder, double d3) { builder.addDouble(3, d3, Double.NEGATIVE_INFINITY); }
public static void addTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.addDouble(4, testdPinf, Double.POSITIVE_INFINITY); } public static void addF0(FlatBufferBuilder builder, float f0) { builder.addFloat(4, f0, Float.NaN); }
public static void addTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.addDouble(5, testdNinf, Double.NEGATIVE_INFINITY); } public static void addF1(FlatBufferBuilder builder, float f1) { builder.addFloat(5, f1, Float.NaN); }
public static void addTestfVec(FlatBufferBuilder builder, int testfVecOffset) { builder.addOffset(6, testfVecOffset, 0); } public static void addF2(FlatBufferBuilder builder, float f2) { builder.addFloat(6, f2, Float.POSITIVE_INFINITY); }
public static int createTestfVecVector(FlatBufferBuilder builder, float[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addFloat(data[i]); return builder.endVector(); } public static void addF3(FlatBufferBuilder builder, float f3) { builder.addFloat(7, f3, Float.NEGATIVE_INFINITY); }
public static void startTestfVecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); } public static void addDvec(FlatBufferBuilder builder, int dvecOffset) { builder.addOffset(8, dvecOffset, 0); }
public static void addTestdVec(FlatBufferBuilder builder, int testdVecOffset) { builder.addOffset(7, testdVecOffset, 0); } public static int createDvecVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
public static int createTestdVecVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); } public static void startDvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
public static void startTestdVecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); } public static void addFvec(FlatBufferBuilder builder, int fvecOffset) { builder.addOffset(9, fvecOffset, 0); }
public static int createFvecVector(FlatBufferBuilder builder, float[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addFloat(data[i]); return builder.endVector(); }
public static void startFvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endMonsterExtra(FlatBufferBuilder builder) { public static int endMonsterExtra(FlatBufferBuilder builder) {
int o = builder.endTable(); int o = builder.endTable();
return o; return o;

View File

@ -19,100 +19,116 @@ class MonsterExtra(object):
self._tab = flatbuffers.table.Table(buf, pos) self._tab = flatbuffers.table.Table(buf, pos)
# MonsterExtra # MonsterExtra
def TestfNan(self): def D0(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0: if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos) return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('nan') return float('nan')
# MonsterExtra # MonsterExtra
def TestfPinf(self): def D1(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0: if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos) return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('nan')
# MonsterExtra
def D2(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('inf') return float('inf')
# MonsterExtra # MonsterExtra
def TestfNinf(self): def D3(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)) 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: if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos) return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('-inf') return float('-inf')
# MonsterExtra # MonsterExtra
def TestfVec(self, j): def F0(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0: if o != 0:
a = self._tab.Vector(o) return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4)) return float('nan')
return 0
# MonsterExtra # MonsterExtra
def TestfVecAsNumpy(self): def F1(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0: if o != 0:
return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o) return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return 0 return float('nan')
# MonsterExtra # MonsterExtra
def TestfVecLength(self): def F2(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0: if o != 0:
return self._tab.VectorLen(o) return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return 0 return float('inf')
# MonsterExtra # MonsterExtra
def TestdVec(self, j): def F3(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return float('-inf')
# MonsterExtra
def Dvec(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
if o != 0: if o != 0:
a = self._tab.Vector(o) a = self._tab.Vector(o)
return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8)) return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
return 0 return 0
# MonsterExtra # MonsterExtra
def TestdVecAsNumpy(self): def DvecAsNumpy(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
if o != 0: if o != 0:
return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o) return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
return 0 return 0
# MonsterExtra # MonsterExtra
def TestdVecLength(self): def DvecLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18)) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
if o != 0: if o != 0:
return self._tab.VectorLen(o) return self._tab.VectorLen(o)
return 0 return 0
def MonsterExtraStart(builder): builder.StartObject(8) # MonsterExtra
def MonsterExtraAddTestfNan(builder, testfNan): builder.PrependFloat32Slot(0, testfNan, float('nan')) def Fvec(self, j):
def MonsterExtraAddTestfPinf(builder, testfPinf): builder.PrependFloat32Slot(1, testfPinf, float('inf')) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
def MonsterExtraAddTestfNinf(builder, testfNinf): builder.PrependFloat32Slot(2, testfNinf, float('-inf')) if o != 0:
def MonsterExtraAddTestdNan(builder, testdNan): builder.PrependFloat64Slot(3, testdNan, float('nan')) a = self._tab.Vector(o)
def MonsterExtraAddTestdPinf(builder, testdPinf): builder.PrependFloat64Slot(4, testdPinf, float('inf')) return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
def MonsterExtraAddTestdNinf(builder, testdNinf): builder.PrependFloat64Slot(5, testdNinf, float('-inf')) return 0
def MonsterExtraAddTestfVec(builder, testfVec): builder.PrependUOffsetTRelativeSlot(6, flatbuffers.number_types.UOffsetTFlags.py_type(testfVec), 0)
def MonsterExtraStartTestfVecVector(builder, numElems): return builder.StartVector(4, numElems, 4) # MonsterExtra
def MonsterExtraAddTestdVec(builder, testdVec): builder.PrependUOffsetTRelativeSlot(7, flatbuffers.number_types.UOffsetTFlags.py_type(testdVec), 0) def FvecAsNumpy(self):
def MonsterExtraStartTestdVecVector(builder, numElems): return builder.StartVector(8, numElems, 8) o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
if o != 0:
return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
return 0
# MonsterExtra
def FvecLength(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
if o != 0:
return self._tab.VectorLen(o)
return 0
def MonsterExtraStart(builder): builder.StartObject(10)
def MonsterExtraAddD0(builder, d0): builder.PrependFloat64Slot(0, d0, float('nan'))
def MonsterExtraAddD1(builder, d1): builder.PrependFloat64Slot(1, d1, float('nan'))
def MonsterExtraAddD2(builder, d2): builder.PrependFloat64Slot(2, d2, float('inf'))
def MonsterExtraAddD3(builder, d3): builder.PrependFloat64Slot(3, d3, float('-inf'))
def MonsterExtraAddF0(builder, f0): builder.PrependFloat32Slot(4, f0, float('nan'))
def MonsterExtraAddF1(builder, f1): builder.PrependFloat32Slot(5, f1, float('nan'))
def MonsterExtraAddF2(builder, f2): builder.PrependFloat32Slot(6, f2, float('inf'))
def MonsterExtraAddF3(builder, f3): builder.PrependFloat32Slot(7, f3, float('-inf'))
def MonsterExtraAddDvec(builder, dvec): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(dvec), 0)
def MonsterExtraStartDvecVector(builder, numElems): return builder.StartVector(8, numElems, 8)
def MonsterExtraAddFvec(builder, fvec): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)
def MonsterExtraStartFvecVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def MonsterExtraEnd(builder): return builder.EndObject() def MonsterExtraEnd(builder): return builder.EndObject()

View File

@ -3,14 +3,16 @@ namespace MyGame;
// Not all programming languages support this extra table. // Not all programming languages support this extra table.
table MonsterExtra { table MonsterExtra {
// Float-point values with NaN and Inf defaults. // Float-point values with NaN and Inf defaults.
testf_nan:float = nan; d0:double = nan;
testf_pinf:float = +inf; d1:double = -nan; // parser must ignore sign of NaN
testf_ninf:float = -inf; d2:double = +inf;
testd_nan:double = nan; d3:double = -inf;
testd_pinf:double = +inf; f0:float = -nan; // parser must ignore sign of NaN
testd_ninf:double = -inf; f1:float = +nan;
testf_vec : [float]; f2:float = +inf;
testd_vec : [double]; f3:float = -inf;
dvec : [double];
fvec : [float];
} }
root_type MonsterExtra; root_type MonsterExtra;

View File

@ -18,34 +18,40 @@ inline const flatbuffers::TypeTable *MonsterExtraTypeTable();
struct MonsterExtraT : public flatbuffers::NativeTable { struct MonsterExtraT : public flatbuffers::NativeTable {
typedef MonsterExtra TableType; typedef MonsterExtra TableType;
float testf_nan; double d0;
float testf_pinf; double d1;
float testf_ninf; double d2;
double testd_nan; double d3;
double testd_pinf; float f0;
double testd_ninf; float f1;
std::vector<float> testf_vec; float f2;
std::vector<double> testd_vec; float f3;
std::vector<double> dvec;
std::vector<float> fvec;
MonsterExtraT() MonsterExtraT()
: testf_nan(std::numeric_limits<float>::quiet_NaN()), : d0(std::numeric_limits<double>::quiet_NaN()),
testf_pinf(std::numeric_limits<float>::infinity()), d1(std::numeric_limits<double>::quiet_NaN()),
testf_ninf(-std::numeric_limits<float>::infinity()), d2(std::numeric_limits<double>::infinity()),
testd_nan(std::numeric_limits<double>::quiet_NaN()), d3(-std::numeric_limits<double>::infinity()),
testd_pinf(std::numeric_limits<double>::infinity()), f0(std::numeric_limits<float>::quiet_NaN()),
testd_ninf(-std::numeric_limits<double>::infinity()) { f1(std::numeric_limits<float>::quiet_NaN()),
f2(std::numeric_limits<float>::infinity()),
f3(-std::numeric_limits<float>::infinity()) {
} }
}; };
inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) { inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
return return
(lhs.testf_nan == rhs.testf_nan) && (lhs.d0 == rhs.d0) &&
(lhs.testf_pinf == rhs.testf_pinf) && (lhs.d1 == rhs.d1) &&
(lhs.testf_ninf == rhs.testf_ninf) && (lhs.d2 == rhs.d2) &&
(lhs.testd_nan == rhs.testd_nan) && (lhs.d3 == rhs.d3) &&
(lhs.testd_pinf == rhs.testd_pinf) && (lhs.f0 == rhs.f0) &&
(lhs.testd_ninf == rhs.testd_ninf) && (lhs.f1 == rhs.f1) &&
(lhs.testf_vec == rhs.testf_vec) && (lhs.f2 == rhs.f2) &&
(lhs.testd_vec == rhs.testd_vec); (lhs.f3 == rhs.f3) &&
(lhs.dvec == rhs.dvec) &&
(lhs.fvec == rhs.fvec);
} }
inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) { inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
@ -59,75 +65,91 @@ struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
return MonsterExtraTypeTable(); return MonsterExtraTypeTable();
} }
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_TESTF_NAN = 4, VT_D0 = 4,
VT_TESTF_PINF = 6, VT_D1 = 6,
VT_TESTF_NINF = 8, VT_D2 = 8,
VT_TESTD_NAN = 10, VT_D3 = 10,
VT_TESTD_PINF = 12, VT_F0 = 12,
VT_TESTD_NINF = 14, VT_F1 = 14,
VT_TESTF_VEC = 16, VT_F2 = 16,
VT_TESTD_VEC = 18 VT_F3 = 18,
VT_DVEC = 20,
VT_FVEC = 22
}; };
float testf_nan() const { double d0() const {
return GetField<float>(VT_TESTF_NAN, std::numeric_limits<float>::quiet_NaN()); return GetField<double>(VT_D0, std::numeric_limits<double>::quiet_NaN());
} }
bool mutate_testf_nan(float _testf_nan) { bool mutate_d0(double _d0) {
return SetField<float>(VT_TESTF_NAN, _testf_nan, std::numeric_limits<float>::quiet_NaN()); return SetField<double>(VT_D0, _d0, std::numeric_limits<double>::quiet_NaN());
} }
float testf_pinf() const { double d1() const {
return GetField<float>(VT_TESTF_PINF, std::numeric_limits<float>::infinity()); return GetField<double>(VT_D1, std::numeric_limits<double>::quiet_NaN());
} }
bool mutate_testf_pinf(float _testf_pinf) { bool mutate_d1(double _d1) {
return SetField<float>(VT_TESTF_PINF, _testf_pinf, std::numeric_limits<float>::infinity()); return SetField<double>(VT_D1, _d1, std::numeric_limits<double>::quiet_NaN());
} }
float testf_ninf() const { double d2() const {
return GetField<float>(VT_TESTF_NINF, -std::numeric_limits<float>::infinity()); return GetField<double>(VT_D2, std::numeric_limits<double>::infinity());
} }
bool mutate_testf_ninf(float _testf_ninf) { bool mutate_d2(double _d2) {
return SetField<float>(VT_TESTF_NINF, _testf_ninf, -std::numeric_limits<float>::infinity()); return SetField<double>(VT_D2, _d2, std::numeric_limits<double>::infinity());
} }
double testd_nan() const { double d3() const {
return GetField<double>(VT_TESTD_NAN, std::numeric_limits<double>::quiet_NaN()); return GetField<double>(VT_D3, -std::numeric_limits<double>::infinity());
} }
bool mutate_testd_nan(double _testd_nan) { bool mutate_d3(double _d3) {
return SetField<double>(VT_TESTD_NAN, _testd_nan, std::numeric_limits<double>::quiet_NaN()); return SetField<double>(VT_D3, _d3, -std::numeric_limits<double>::infinity());
} }
double testd_pinf() const { float f0() const {
return GetField<double>(VT_TESTD_PINF, std::numeric_limits<double>::infinity()); return GetField<float>(VT_F0, std::numeric_limits<float>::quiet_NaN());
} }
bool mutate_testd_pinf(double _testd_pinf) { bool mutate_f0(float _f0) {
return SetField<double>(VT_TESTD_PINF, _testd_pinf, std::numeric_limits<double>::infinity()); return SetField<float>(VT_F0, _f0, std::numeric_limits<float>::quiet_NaN());
} }
double testd_ninf() const { float f1() const {
return GetField<double>(VT_TESTD_NINF, -std::numeric_limits<double>::infinity()); return GetField<float>(VT_F1, std::numeric_limits<float>::quiet_NaN());
} }
bool mutate_testd_ninf(double _testd_ninf) { bool mutate_f1(float _f1) {
return SetField<double>(VT_TESTD_NINF, _testd_ninf, -std::numeric_limits<double>::infinity()); return SetField<float>(VT_F1, _f1, std::numeric_limits<float>::quiet_NaN());
} }
const flatbuffers::Vector<float> *testf_vec() const { float f2() const {
return GetPointer<const flatbuffers::Vector<float> *>(VT_TESTF_VEC); return GetField<float>(VT_F2, std::numeric_limits<float>::infinity());
} }
flatbuffers::Vector<float> *mutable_testf_vec() { bool mutate_f2(float _f2) {
return GetPointer<flatbuffers::Vector<float> *>(VT_TESTF_VEC); return SetField<float>(VT_F2, _f2, std::numeric_limits<float>::infinity());
} }
const flatbuffers::Vector<double> *testd_vec() const { float f3() const {
return GetPointer<const flatbuffers::Vector<double> *>(VT_TESTD_VEC); return GetField<float>(VT_F3, -std::numeric_limits<float>::infinity());
} }
flatbuffers::Vector<double> *mutable_testd_vec() { bool mutate_f3(float _f3) {
return GetPointer<flatbuffers::Vector<double> *>(VT_TESTD_VEC); return SetField<float>(VT_F3, _f3, -std::numeric_limits<float>::infinity());
}
const flatbuffers::Vector<double> *dvec() const {
return GetPointer<const flatbuffers::Vector<double> *>(VT_DVEC);
}
flatbuffers::Vector<double> *mutable_dvec() {
return GetPointer<flatbuffers::Vector<double> *>(VT_DVEC);
}
const flatbuffers::Vector<float> *fvec() const {
return GetPointer<const flatbuffers::Vector<float> *>(VT_FVEC);
}
flatbuffers::Vector<float> *mutable_fvec() {
return GetPointer<flatbuffers::Vector<float> *>(VT_FVEC);
} }
bool Verify(flatbuffers::Verifier &verifier) const { bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyField<float>(verifier, VT_TESTF_NAN) && VerifyField<double>(verifier, VT_D0) &&
VerifyField<float>(verifier, VT_TESTF_PINF) && VerifyField<double>(verifier, VT_D1) &&
VerifyField<float>(verifier, VT_TESTF_NINF) && VerifyField<double>(verifier, VT_D2) &&
VerifyField<double>(verifier, VT_TESTD_NAN) && VerifyField<double>(verifier, VT_D3) &&
VerifyField<double>(verifier, VT_TESTD_PINF) && VerifyField<float>(verifier, VT_F0) &&
VerifyField<double>(verifier, VT_TESTD_NINF) && VerifyField<float>(verifier, VT_F1) &&
VerifyOffset(verifier, VT_TESTF_VEC) && VerifyField<float>(verifier, VT_F2) &&
verifier.VerifyVector(testf_vec()) && VerifyField<float>(verifier, VT_F3) &&
VerifyOffset(verifier, VT_TESTD_VEC) && VerifyOffset(verifier, VT_DVEC) &&
verifier.VerifyVector(testd_vec()) && verifier.VerifyVector(dvec()) &&
VerifyOffset(verifier, VT_FVEC) &&
verifier.VerifyVector(fvec()) &&
verifier.EndTable(); verifier.EndTable();
} }
MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@ -138,29 +160,35 @@ struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
struct MonsterExtraBuilder { struct MonsterExtraBuilder {
flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_; flatbuffers::uoffset_t start_;
void add_testf_nan(float testf_nan) { void add_d0(double d0) {
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NAN, testf_nan, std::numeric_limits<float>::quiet_NaN()); fbb_.AddElement<double>(MonsterExtra::VT_D0, d0, std::numeric_limits<double>::quiet_NaN());
} }
void add_testf_pinf(float testf_pinf) { void add_d1(double d1) {
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_PINF, testf_pinf, std::numeric_limits<float>::infinity()); fbb_.AddElement<double>(MonsterExtra::VT_D1, d1, std::numeric_limits<double>::quiet_NaN());
} }
void add_testf_ninf(float testf_ninf) { void add_d2(double d2) {
fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NINF, testf_ninf, -std::numeric_limits<float>::infinity()); fbb_.AddElement<double>(MonsterExtra::VT_D2, d2, std::numeric_limits<double>::infinity());
} }
void add_testd_nan(double testd_nan) { void add_d3(double d3) {
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NAN, testd_nan, std::numeric_limits<double>::quiet_NaN()); fbb_.AddElement<double>(MonsterExtra::VT_D3, d3, -std::numeric_limits<double>::infinity());
} }
void add_testd_pinf(double testd_pinf) { void add_f0(float f0) {
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_PINF, testd_pinf, std::numeric_limits<double>::infinity()); fbb_.AddElement<float>(MonsterExtra::VT_F0, f0, std::numeric_limits<float>::quiet_NaN());
} }
void add_testd_ninf(double testd_ninf) { void add_f1(float f1) {
fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NINF, testd_ninf, -std::numeric_limits<double>::infinity()); fbb_.AddElement<float>(MonsterExtra::VT_F1, f1, std::numeric_limits<float>::quiet_NaN());
} }
void add_testf_vec(flatbuffers::Offset<flatbuffers::Vector<float>> testf_vec) { void add_f2(float f2) {
fbb_.AddOffset(MonsterExtra::VT_TESTF_VEC, testf_vec); fbb_.AddElement<float>(MonsterExtra::VT_F2, f2, std::numeric_limits<float>::infinity());
} }
void add_testd_vec(flatbuffers::Offset<flatbuffers::Vector<double>> testd_vec) { void add_f3(float f3) {
fbb_.AddOffset(MonsterExtra::VT_TESTD_VEC, testd_vec); fbb_.AddElement<float>(MonsterExtra::VT_F3, f3, -std::numeric_limits<float>::infinity());
}
void add_dvec(flatbuffers::Offset<flatbuffers::Vector<double>> dvec) {
fbb_.AddOffset(MonsterExtra::VT_DVEC, dvec);
}
void add_fvec(flatbuffers::Offset<flatbuffers::Vector<float>> fvec) {
fbb_.AddOffset(MonsterExtra::VT_FVEC, fvec);
} }
explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
@ -176,48 +204,56 @@ struct MonsterExtraBuilder {
inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra( inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
float testf_nan = std::numeric_limits<float>::quiet_NaN(), double d0 = std::numeric_limits<double>::quiet_NaN(),
float testf_pinf = std::numeric_limits<float>::infinity(), double d1 = std::numeric_limits<double>::quiet_NaN(),
float testf_ninf = -std::numeric_limits<float>::infinity(), double d2 = std::numeric_limits<double>::infinity(),
double testd_nan = std::numeric_limits<double>::quiet_NaN(), double d3 = -std::numeric_limits<double>::infinity(),
double testd_pinf = std::numeric_limits<double>::infinity(), float f0 = std::numeric_limits<float>::quiet_NaN(),
double testd_ninf = -std::numeric_limits<double>::infinity(), float f1 = std::numeric_limits<float>::quiet_NaN(),
flatbuffers::Offset<flatbuffers::Vector<float>> testf_vec = 0, float f2 = std::numeric_limits<float>::infinity(),
flatbuffers::Offset<flatbuffers::Vector<double>> testd_vec = 0) { float f3 = -std::numeric_limits<float>::infinity(),
flatbuffers::Offset<flatbuffers::Vector<double>> dvec = 0,
flatbuffers::Offset<flatbuffers::Vector<float>> fvec = 0) {
MonsterExtraBuilder builder_(_fbb); MonsterExtraBuilder builder_(_fbb);
builder_.add_testd_ninf(testd_ninf); builder_.add_d3(d3);
builder_.add_testd_pinf(testd_pinf); builder_.add_d2(d2);
builder_.add_testd_nan(testd_nan); builder_.add_d1(d1);
builder_.add_testd_vec(testd_vec); builder_.add_d0(d0);
builder_.add_testf_vec(testf_vec); builder_.add_fvec(fvec);
builder_.add_testf_ninf(testf_ninf); builder_.add_dvec(dvec);
builder_.add_testf_pinf(testf_pinf); builder_.add_f3(f3);
builder_.add_testf_nan(testf_nan); builder_.add_f2(f2);
builder_.add_f1(f1);
builder_.add_f0(f0);
return builder_.Finish(); return builder_.Finish();
} }
inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtraDirect( inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtraDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder &_fbb,
float testf_nan = std::numeric_limits<float>::quiet_NaN(), double d0 = std::numeric_limits<double>::quiet_NaN(),
float testf_pinf = std::numeric_limits<float>::infinity(), double d1 = std::numeric_limits<double>::quiet_NaN(),
float testf_ninf = -std::numeric_limits<float>::infinity(), double d2 = std::numeric_limits<double>::infinity(),
double testd_nan = std::numeric_limits<double>::quiet_NaN(), double d3 = -std::numeric_limits<double>::infinity(),
double testd_pinf = std::numeric_limits<double>::infinity(), float f0 = std::numeric_limits<float>::quiet_NaN(),
double testd_ninf = -std::numeric_limits<double>::infinity(), float f1 = std::numeric_limits<float>::quiet_NaN(),
const std::vector<float> *testf_vec = nullptr, float f2 = std::numeric_limits<float>::infinity(),
const std::vector<double> *testd_vec = nullptr) { float f3 = -std::numeric_limits<float>::infinity(),
auto testf_vec__ = testf_vec ? _fbb.CreateVector<float>(*testf_vec) : 0; const std::vector<double> *dvec = nullptr,
auto testd_vec__ = testd_vec ? _fbb.CreateVector<double>(*testd_vec) : 0; const std::vector<float> *fvec = nullptr) {
auto dvec__ = dvec ? _fbb.CreateVector<double>(*dvec) : 0;
auto fvec__ = fvec ? _fbb.CreateVector<float>(*fvec) : 0;
return MyGame::CreateMonsterExtra( return MyGame::CreateMonsterExtra(
_fbb, _fbb,
testf_nan, d0,
testf_pinf, d1,
testf_ninf, d2,
testd_nan, d3,
testd_pinf, f0,
testd_ninf, f1,
testf_vec__, f2,
testd_vec__); f3,
dvec__,
fvec__);
} }
flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_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);
@ -231,14 +267,16 @@ inline MonsterExtraT *MonsterExtra::UnPack(const flatbuffers::resolver_function_
inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const { inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o; (void)_o;
(void)_resolver; (void)_resolver;
{ auto _e = testf_nan(); _o->testf_nan = _e; }; { auto _e = d0(); _o->d0 = _e; };
{ auto _e = testf_pinf(); _o->testf_pinf = _e; }; { auto _e = d1(); _o->d1 = _e; };
{ auto _e = testf_ninf(); _o->testf_ninf = _e; }; { auto _e = d2(); _o->d2 = _e; };
{ auto _e = testd_nan(); _o->testd_nan = _e; }; { auto _e = d3(); _o->d3 = _e; };
{ auto _e = testd_pinf(); _o->testd_pinf = _e; }; { auto _e = f0(); _o->f0 = _e; };
{ auto _e = testd_ninf(); _o->testd_ninf = _e; }; { auto _e = f1(); _o->f1 = _e; };
{ auto _e = testf_vec(); if (_e) { _o->testf_vec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testf_vec[_i] = _e->Get(_i); } } }; { auto _e = f2(); _o->f2 = _e; };
{ auto _e = testd_vec(); if (_e) { _o->testd_vec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testd_vec[_i] = _e->Get(_i); } } }; { auto _e = f3(); _o->f3 = _e; };
{ auto _e = dvec(); if (_e) { _o->dvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->dvec[_i] = _e->Get(_i); } } };
{ auto _e = fvec(); if (_e) { _o->fvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fvec[_i] = _e->Get(_i); } } };
} }
inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) { inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -249,49 +287,57 @@ inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBuf
(void)_rehasher; (void)_rehasher;
(void)_o; (void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExtraT* __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 _d0 = _o->d0;
auto _testf_pinf = _o->testf_pinf; auto _d1 = _o->d1;
auto _testf_ninf = _o->testf_ninf; auto _d2 = _o->d2;
auto _testd_nan = _o->testd_nan; auto _d3 = _o->d3;
auto _testd_pinf = _o->testd_pinf; auto _f0 = _o->f0;
auto _testd_ninf = _o->testd_ninf; auto _f1 = _o->f1;
auto _testf_vec = _o->testf_vec.size() ? _fbb.CreateVector(_o->testf_vec) : 0; auto _f2 = _o->f2;
auto _testd_vec = _o->testd_vec.size() ? _fbb.CreateVector(_o->testd_vec) : 0; auto _f3 = _o->f3;
auto _dvec = _o->dvec.size() ? _fbb.CreateVector(_o->dvec) : 0;
auto _fvec = _o->fvec.size() ? _fbb.CreateVector(_o->fvec) : 0;
return MyGame::CreateMonsterExtra( return MyGame::CreateMonsterExtra(
_fbb, _fbb,
_testf_nan, _d0,
_testf_pinf, _d1,
_testf_ninf, _d2,
_testd_nan, _d3,
_testd_pinf, _f0,
_testd_ninf, _f1,
_testf_vec, _f2,
_testd_vec); _f3,
_dvec,
_fvec);
} }
inline const flatbuffers::TypeTable *MonsterExtraTypeTable() { inline const flatbuffers::TypeTable *MonsterExtraTypeTable() {
static const flatbuffers::TypeCode type_codes[] = { static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_DOUBLE, 0, -1 }, { flatbuffers::ET_DOUBLE, 0, -1 },
{ flatbuffers::ET_DOUBLE, 0, -1 }, { flatbuffers::ET_DOUBLE, 0, -1 },
{ flatbuffers::ET_DOUBLE, 0, -1 }, { flatbuffers::ET_DOUBLE, 0, -1 },
{ flatbuffers::ET_FLOAT, 1, -1 }, { flatbuffers::ET_DOUBLE, 0, -1 },
{ flatbuffers::ET_DOUBLE, 1, -1 } { flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_DOUBLE, 1, -1 },
{ flatbuffers::ET_FLOAT, 1, -1 }
}; };
static const char * const names[] = { static const char * const names[] = {
"testf_nan", "d0",
"testf_pinf", "d1",
"testf_ninf", "d2",
"testd_nan", "d3",
"testd_pinf", "f0",
"testd_ninf", "f1",
"testf_vec", "f2",
"testd_vec" "f3",
"dvec",
"fvec"
}; };
static const flatbuffers::TypeTable tt = { static const flatbuffers::TypeTable tt = {
flatbuffers::ST_TABLE, 8, type_codes, nullptr, nullptr, names flatbuffers::ST_TABLE, 10, type_codes, nullptr, nullptr, names
}; };
return &tt; return &tt;
} }

View File

@ -1,11 +1,15 @@
{ {
// Float-point values with NaN and Inf defaults. // Initialize with non-default values.
testf_nan : nan, d0 : -nan, // match with default
testf_pinf : +inf, d1 : +inf,
testf_ninf : -inf, d2 : -inf,
testd_nan : nan, d3: nan,
testd_pinf : +inf, f0 : +nan, // match with default
testd_ninf : -inf, f1 : -nan, // match with default
testf_vec : [-1.0, 2.0, -inf, +inf, nan], f2 : +inf, // match with default
testd_vec : [-1.0, 4.0, -inf, +inf, nan] f3 : -inf, // match with default
// Values should have exact binary representation
// to avoid rounding effects in tests.
dvec : [2.0, +inf, -inf, nan,],
fvec : [1.0, -inf, +inf, nan],
} }

View File

@ -1412,13 +1412,13 @@ class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head()) self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
def test_default_nan_inf(self): def test_default_nan_inf(self):
self.assertTrue(math.isnan(self.mon.TestfNan())) self.assertTrue(math.isnan(self.mon.F1()))
self.assertEqual(self.mon.TestfPinf(), float("inf")) self.assertEqual(self.mon.F2(), float("inf"))
self.assertEqual(self.mon.TestfNinf(), float("-inf")) self.assertEqual(self.mon.F3(), float("-inf"))
self.assertTrue(math.isnan(self.mon.TestdNan())) self.assertTrue(math.isnan(self.mon.D1()))
self.assertEqual(self.mon.TestdPinf(), float("inf")) self.assertEqual(self.mon.D2(), float("inf"))
self.assertEqual(self.mon.TestdNinf(), float("-inf")) self.assertEqual(self.mon.D3(), float("-inf"))
class TestVtableDeduplication(unittest.TestCase): class TestVtableDeduplication(unittest.TestCase):

View File

@ -41,6 +41,25 @@
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
// clang-format off
// Check that char* and uint8_t* are interoperable types.
// The reinterpret_cast<> between the pointers are used to simplify data loading.
static_assert(flatbuffers::is_same<uint8_t, char>::value ||
flatbuffers::is_same<uint8_t, unsigned char>::value,
"unexpected uint8_t type");
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Ensure IEEE-754 support if tests of floats with NaN/Inf will run.
static_assert(std::numeric_limits<float>::is_iec559 &&
std::numeric_limits<double>::is_iec559,
"IEC-559 (IEEE-754) standard required");
#endif
// clang-format on
// Shortcuts for the infinity.
static const auto infinityf = std::numeric_limits<float>::infinity();
static const auto infinityd = std::numeric_limits<double>::infinity();
using namespace MyGame::Example; using namespace MyGame::Example;
void FlatBufferBuilderTest(); void FlatBufferBuilderTest();
@ -601,36 +620,105 @@ void JsonDefaultTest() {
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true); TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
} }
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// The IEEE-754 quiet_NaN is not simple binary constant.
// All binary NaN bit strings have all the bits of the biased exponent field E
// set to 1. A quiet NaN bit string should be encoded with the first bit d[1]
// of the trailing significand field T being 1 (d[0] is implicit bit).
// It is assumed that endianness of floating-point is same as integer.
template<typename T, typename U, U qnan_base> bool is_quiet_nan_impl(T v) {
static_assert(sizeof(T) == sizeof(U), "unexpected");
U b = 0;
std::memcpy(&b, &v, sizeof(T));
return ((b & qnan_base) == qnan_base);
}
static bool is_quiet_nan(float v) {
return is_quiet_nan_impl<float, uint32_t, 0x7FC00000u>(v);
}
static bool is_quiet_nan(double v) {
return is_quiet_nan_impl<double, uint64_t, 0x7FF8000000000000ul>(v);
}
void TestMonsterExtraFloats() { void TestMonsterExtraFloats() {
TEST_EQ(is_quiet_nan(1.0), false);
TEST_EQ(is_quiet_nan(infinityd), false);
TEST_EQ(is_quiet_nan(-infinityf), false);
TEST_EQ(is_quiet_nan(std::numeric_limits<float>::quiet_NaN()), true);
TEST_EQ(is_quiet_nan(std::numeric_limits<double>::quiet_NaN()), true);
using namespace flatbuffers;
using namespace MyGame; using namespace MyGame;
// Load FlatBuffer schema (.fbs) from disk. // Load FlatBuffer schema (.fbs) from disk.
std::string schemafile; std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_extra.fbs").c_str(), TEST_EQ(LoadFile((test_data_path + "monster_extra.fbs").c_str(), false,
false, &schemafile), &schemafile),
true); true);
// Parse schema first, so we can use it to parse the data after. // Parse schema first, so we can use it to parse the data after.
flatbuffers::Parser parser; Parser parser;
auto include_test_path = auto include_test_path = ConCatPathFileName(test_data_path, "include_test");
flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = { test_data_path.c_str(), const char *include_directories[] = { test_data_path.c_str(),
include_test_path.c_str(), nullptr }; include_test_path.c_str(), nullptr };
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true); TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
// Create empty extra and store to json. // Create empty extra and store to json.
parser.opts.output_default_scalars_in_json = true; parser.opts.output_default_scalars_in_json = true;
parser.opts.output_enum_identifiers = true; parser.opts.output_enum_identifiers = true;
flatbuffers::FlatBufferBuilder builder; FlatBufferBuilder builder;
MonsterExtraBuilder extra(builder); const auto def_root = MonsterExtraBuilder(builder).Finish();
FinishMonsterExtraBuffer(builder, extra.Finish()); FinishMonsterExtraBuffer(builder, def_root);
const auto def_obj = builder.GetBufferPointer();
const auto def_extra = GetMonsterExtra(def_obj);
TEST_NOTNULL(def_extra);
TEST_EQ(is_quiet_nan(def_extra->f0()), true);
TEST_EQ(is_quiet_nan(def_extra->f1()), true);
TEST_EQ(def_extra->f2(), +infinityf);
TEST_EQ(def_extra->f3(), -infinityf);
TEST_EQ(is_quiet_nan(def_extra->d0()), true);
TEST_EQ(is_quiet_nan(def_extra->d1()), true);
TEST_EQ(def_extra->d2(), +infinityd);
TEST_EQ(def_extra->d3(), -infinityd);
std::string jsongen; std::string jsongen;
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen); auto result = GenerateText(parser, def_obj, &jsongen);
TEST_EQ(result, true); TEST_EQ(result, true);
TEST_EQ(std::string::npos != jsongen.find("testf_nan: nan"), true); // Check expected default values.
TEST_EQ(std::string::npos != jsongen.find("testf_pinf: inf"), true); TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
TEST_EQ(std::string::npos != jsongen.find("testf_ninf: -inf"), true); TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
TEST_EQ(std::string::npos != jsongen.find("testd_nan: nan"), true); TEST_EQ(std::string::npos != jsongen.find("f2: inf"), true);
TEST_EQ(std::string::npos != jsongen.find("testd_pinf: inf"), true); TEST_EQ(std::string::npos != jsongen.find("f3: -inf"), true);
TEST_EQ(std::string::npos != jsongen.find("testd_ninf: -inf"), true); TEST_EQ(std::string::npos != jsongen.find("d0: nan"), true);
TEST_EQ(std::string::npos != jsongen.find("d1: nan"), true);
TEST_EQ(std::string::npos != jsongen.find("d2: inf"), true);
TEST_EQ(std::string::npos != jsongen.find("d3: -inf"), true);
// Parse 'mosterdata_extra.json'.
const auto extra_base = test_data_path + "monsterdata_extra";
jsongen = "";
TEST_EQ(LoadFile((extra_base + ".json").c_str(), false, &jsongen), true);
TEST_EQ(parser.Parse(jsongen.c_str()), true);
const auto test_file = parser.builder_.GetBufferPointer();
const auto test_size = parser.builder_.GetSize();
Verifier verifier(test_file, test_size);
TEST_ASSERT(VerifyMonsterExtraBuffer(verifier));
const auto extra = GetMonsterExtra(test_file);
TEST_NOTNULL(extra);
TEST_EQ(is_quiet_nan(extra->f0()), true);
TEST_EQ(is_quiet_nan(extra->f1()), true);
TEST_EQ(extra->f2(), +infinityf);
TEST_EQ(extra->f3(), -infinityf);
TEST_EQ(is_quiet_nan(extra->d0()), true);
TEST_EQ(extra->d1(), +infinityd);
TEST_EQ(extra->d2(), -infinityd);
TEST_EQ(is_quiet_nan(extra->d3()), true);
TEST_NOTNULL(extra->fvec());
TEST_EQ(extra->fvec()->size(), 4);
TEST_EQ(extra->fvec()->Get(0), 1.0f);
TEST_EQ(extra->fvec()->Get(1), -infinityf);
TEST_EQ(extra->fvec()->Get(2), +infinityf);
TEST_EQ(is_quiet_nan(extra->fvec()->Get(3)), true);
TEST_NOTNULL(extra->dvec());
TEST_EQ(extra->dvec()->size(), 4);
TEST_EQ(extra->dvec()->Get(0), 2.0);
TEST_EQ(extra->dvec()->Get(1), +infinityd);
TEST_EQ(extra->dvec()->Get(2), -infinityd);
TEST_EQ(is_quiet_nan(extra->dvec()->Get(3)), true);
} }
#else #else
void TestMonsterExtraFloats() {} void TestMonsterExtraFloats() {}
@ -1663,8 +1751,6 @@ void IntegerBoundaryTest() {
} }
void ValidFloatTest() { void ValidFloatTest() {
const auto infinityf = flatbuffers::numeric_limits<float>::infinity();
const auto infinityd = flatbuffers::numeric_limits<double>::infinity();
// check rounding to infinity // check rounding to infinity
TEST_EQ(TestValue<float>("{ Y:+3.4029e+38 }", "float"), +infinityf); TEST_EQ(TestValue<float>("{ Y:+3.4029e+38 }", "float"), +infinityf);
TEST_EQ(TestValue<float>("{ Y:-3.4029e+38 }", "float"), -infinityf); TEST_EQ(TestValue<float>("{ Y:-3.4029e+38 }", "float"), -infinityf);
@ -1694,7 +1780,7 @@ void ValidFloatTest() {
TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Old MSVC versions may have problem with this check. // Old MSVC versions may have problem with this check.
// https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/ // https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"), TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
@ -1740,7 +1826,7 @@ void ValidFloatTest() {
#else // FLATBUFFERS_HAS_NEW_STRTOD #else // FLATBUFFERS_HAS_NEW_STRTOD
TEST_OUTPUT_LINE("FLATBUFFERS_HAS_NEW_STRTOD tests skipped"); TEST_OUTPUT_LINE("FLATBUFFERS_HAS_NEW_STRTOD tests skipped");
#endif // FLATBUFFERS_HAS_NEW_STRTOD #endif // !FLATBUFFERS_HAS_NEW_STRTOD
} }
void InvalidFloatTest() { void InvalidFloatTest() {