From 9ec2b96b19156ce5ac561b4401cfa60032dccd68 Mon Sep 17 00:00:00 2001 From: jbeder Date: Sun, 10 Jul 2011 16:27:40 +0000 Subject: [PATCH] Added parsing .inf and .nan (and friend) --- include/yaml-cpp/conversion.h | 27 ++++++++++++++- test/parsertests.cpp | 63 +++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/include/yaml-cpp/conversion.h b/include/yaml-cpp/conversion.h index 327f88d..6009fb7 100644 --- a/include/yaml-cpp/conversion.h +++ b/include/yaml-cpp/conversion.h @@ -8,6 +8,7 @@ #include "yaml-cpp/null.h" #include "yaml-cpp/traits.h" +#include #include #include @@ -21,12 +22,36 @@ namespace YAML YAML_CPP_API bool Convert(const std::string& input, bool& output); YAML_CPP_API bool Convert(const std::string& input, _Null& output); + inline bool IsInfinity(const std::string& input) { + return input == ".inf" || input == ".Inf" || input == ".INF" || + input == "+.inf" || input == "+.Inf" || input == "+.INF" || + input == "-.inf" || input == "-.Inf" || input == "-.INF"; + } + + inline bool IsNaN(const std::string& input) { + return input == ".nan" || input == ".NaN" || input == ".NAN"; + } + + template inline bool Convert(const std::string& input, T& output, typename enable_if >::type * = 0) { std::stringstream stream(input); stream.unsetf(std::ios::dec); stream >> output; - return !!stream; + if(!!stream) + return true; + + if(std::numeric_limits::has_infinity && IsInfinity(input)) { + output = std::numeric_limits::infinity(); + return true; + } + + if(std::numeric_limits::has_quiet_NaN && IsNaN(input)) { + output = std::numeric_limits::quiet_NaN(); + return true; + } + + return false; } } diff --git a/test/parsertests.cpp b/test/parsertests.cpp index 7b4174e..c5e52b9 100644 --- a/test/parsertests.cpp +++ b/test/parsertests.cpp @@ -803,6 +803,67 @@ namespace Test return ExpectedTagValue(node, "!"); } + + bool Infinity() + { + std::string input = + "- .inf\n" + "- .Inf\n" + "- .INF\n" + "- +.inf\n" + "- +.Inf\n" + "- +.INF\n" + "- -.inf\n" + "- -.Inf\n" + "- -.INF\n"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + for(unsigned i=0;i() != std::numeric_limits::infinity()) + return false; + for(unsigned i=0;i() != std::numeric_limits::infinity()) + return false; + for(unsigned i=0;i() != std::numeric_limits::infinity()) + return false; + return true; + } + + bool NaN() + { + std::string input = + "- .nan\n" + "- .NaN\n" + "- .NAN\n"; + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + for(unsigned i=0;i> d; + if(d == d) + return false; + } + for(unsigned i=0;i> d; + if(d == d) + return false; + } + for(unsigned i=0;i> d; + if(d == d) + return false; + } + return true; + } } namespace { @@ -1079,6 +1140,8 @@ namespace Test RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total); RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total); RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific sequence tag", passed, total); + RunParserTest(&Parser::Infinity, "infinity", passed, total); + RunParserTest(&Parser::NaN, "NaN", passed, total); RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total); RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);