Add NaN and Inf defaults to the C++ generated code. (#5102)

* Add `NaN` and `Inf` defaults to the C++ generated code.

* Refactoring: add FloatConstantGenerator

* Refactoring-2:

- remove isnan checking for all float/double values
- add most probable implementation of virtual methods of FloatConstantGenerator

* Add conditional (FLATBUFFERS_NAN_DEFAULTS) isnan checking
This commit is contained in:
Vladimir Glavnyy
2019-01-08 01:04:44 +07:00
committed by Wouter van Oortmerssen
parent 155c55900f
commit dd288f71f3
10 changed files with 379 additions and 5 deletions

View File

@@ -19,7 +19,25 @@
#include "flatbuffers/base.h"
#if defined(FLATBUFFERS_NAN_DEFAULTS)
#include <cmath>
#endif
namespace flatbuffers {
// Generic 'operator==' with conditional specialisations.
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
(!defined(_MSC_VER) || _MSC_VER >= 1800)
// Like `operator==(e, def)` with weak NaN if T=(float|double).
template<> inline bool IsTheSameAs<float>(float e, float def) {
return (e == def) || (std::isnan(def) && std::isnan(e));
}
template<> inline bool IsTheSameAs<double>(double e, double def) {
return (e == def) || (std::isnan(def) && std::isnan(e));
}
#endif
// Wrapper for uoffset_t to allow safe template specialization.
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
template<typename T> struct Offset {
@@ -1087,7 +1105,7 @@ class FlatBufferBuilder {
// Like PushElement, but additionally tracks the field this represents.
template<typename T> void AddElement(voffset_t field, T e, T def) {
// We don't serialize values equal to the default.
if (e == def && !force_defaults_) return;
if (IsTheSameAs(e, def) && !force_defaults_) return;
auto off = PushElement(e);
TrackField(field, off);
}
@@ -2241,7 +2259,7 @@ class Table {
template<typename T> bool SetField(voffset_t field, T val, T def) {
auto field_offset = GetOptionalFieldOffset(field);
if (!field_offset) return val == def;
if (!field_offset) return IsTheSameAs(val, def);
WriteScalar(data_ + field_offset, val);
return true;
}