mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-10 07:06:26 +00:00
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:
committed by
Wouter van Oortmerssen
parent
155c55900f
commit
dd288f71f3
@@ -130,6 +130,33 @@ extern void GenComment(const std::vector<std::string> &dc,
|
||||
std::string *code_ptr, const CommentConfig *config,
|
||||
const char *prefix = "");
|
||||
|
||||
class FloatConstantGenerator {
|
||||
public:
|
||||
virtual ~FloatConstantGenerator(){};
|
||||
std::string GenFloatConstant(const FieldDef &field) const;
|
||||
|
||||
private:
|
||||
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);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::string GenFloatConstantImpl(const FieldDef &field) const;
|
||||
};
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_CODE_GENERATORS_H_
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user