"git@developer.sourcefind.cn:cnjsdfcy/simbricks.git" did not exist on "ad89039a5172830c3498b8f769a79d4f34960fe3"
Commit e0e01d53 authored by Jeppe Blicher Tarp's avatar Jeppe Blicher Tarp Committed by Jesse Beder
Browse files

Make sure output of NaN, Infinity and -Infinity is identical on all platforms (#717)

Specifically, printing `.nan`, `.inf`, and `-.inf`, respectively, as per the spec section 10.2.1.4.
parent 01226975
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
#pragma once #pragma once
#endif #endif
#include <cmath>
#include <cstddef> #include <cstddef>
#include <limits>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <type_traits>
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
...@@ -153,7 +156,28 @@ inline Emitter& Emitter::WriteStreamable(T value) { ...@@ -153,7 +156,28 @@ inline Emitter& Emitter::WriteStreamable(T value) {
std::stringstream stream; std::stringstream stream;
SetStreamablePrecision<T>(stream); SetStreamablePrecision<T>(stream);
bool special = false;
if (std::is_floating_point<T>::value) {
if ((std::numeric_limits<T>::has_quiet_NaN ||
std::numeric_limits<T>::has_signaling_NaN) &&
std::isnan(value)) {
special = true;
stream << ".nan";
} else if (std::numeric_limits<T>::has_infinity) {
if (value == std::numeric_limits<T>::infinity()) {
special = true;
stream << ".inf";
} else if (value == -std::numeric_limits<T>::infinity()) {
special = true;
stream << "-.inf";
}
}
}
if (!special) {
stream << value; stream << value;
}
m_stream << stream.str(); m_stream << stream.str();
StartedScalar(); StartedScalar();
......
...@@ -253,7 +253,8 @@ TEST_F(EmitterTest, ScalarFormat) { ...@@ -253,7 +253,8 @@ TEST_F(EmitterTest, ScalarFormat) {
out << DoubleQuoted << "explicit double-quoted scalar"; out << DoubleQuoted << "explicit double-quoted scalar";
out << "auto-detected\ndouble-quoted scalar"; out << "auto-detected\ndouble-quoted scalar";
out << "a non-\"auto-detected\" double-quoted scalar"; out << "a non-\"auto-detected\" double-quoted scalar";
out << Literal << "literal scalar\nthat may span\nmany, many\nlines " out << Literal
<< "literal scalar\nthat may span\nmany, many\nlines "
"and have \"whatever\" crazy\tsymbols that we like"; "and have \"whatever\" crazy\tsymbols that we like";
out << EndSeq; out << EndSeq;
...@@ -526,7 +527,8 @@ TEST_F(EmitterTest, SimpleComment) { ...@@ -526,7 +527,8 @@ TEST_F(EmitterTest, SimpleComment) {
TEST_F(EmitterTest, MultiLineComment) { TEST_F(EmitterTest, MultiLineComment) {
out << BeginSeq; out << BeginSeq;
out << "item 1" << Comment( out << "item 1"
<< Comment(
"really really long\ncomment that couldn't " "really really long\ncomment that couldn't "
"possibly\nfit on one line"); "possibly\nfit on one line");
out << "item 2"; out << "item 2";
...@@ -984,6 +986,45 @@ TEST_F(EmitterTest, ValueOfBackslash) { ...@@ -984,6 +986,45 @@ TEST_F(EmitterTest, ValueOfBackslash) {
ExpectEmit("foo: \"\\\\\""); ExpectEmit("foo: \"\\\\\"");
} }
TEST_F(EmitterTest, Infinity) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< std::numeric_limits<float>::infinity();
out << YAML::Key << "bar" << YAML::Value
<< std::numeric_limits<double>::infinity();
out << YAML::EndMap;
ExpectEmit(
"foo: .inf\n"
"bar: .inf");
}
TEST_F(EmitterTest, NegInfinity) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< -std::numeric_limits<float>::infinity();
out << YAML::Key << "bar" << YAML::Value
<< -std::numeric_limits<double>::infinity();
out << YAML::EndMap;
ExpectEmit(
"foo: -.inf\n"
"bar: -.inf");
}
TEST_F(EmitterTest, NaN) {
out << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value
<< std::numeric_limits<float>::quiet_NaN();
out << YAML::Key << "bar" << YAML::Value
<< std::numeric_limits<double>::quiet_NaN();
out << YAML::EndMap;
ExpectEmit(
"foo: .nan\n"
"bar: .nan");
}
class EmitterErrorTest : public ::testing::Test { class EmitterErrorTest : public ::testing::Test {
protected: protected:
void ExpectEmitError(const std::string& expectedError) { void ExpectEmitError(const std::string& expectedError) {
...@@ -1034,5 +1075,5 @@ TEST_F(EmitterErrorTest, InvalidAlias) { ...@@ -1034,5 +1075,5 @@ TEST_F(EmitterErrorTest, InvalidAlias) {
ExpectEmitError(ErrorMsg::INVALID_ALIAS); ExpectEmitError(ErrorMsg::INVALID_ALIAS);
} }
} } // namespace
} } // namespace YAML
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