mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Added parsing .inf and .nan (and friend)
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "yaml-cpp/null.h"
|
#include "yaml-cpp/null.h"
|
||||||
#include "yaml-cpp/traits.h"
|
#include "yaml-cpp/traits.h"
|
||||||
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -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, bool& output);
|
||||||
YAML_CPP_API bool Convert(const std::string& input, _Null& 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 <typename T>
|
template <typename T>
|
||||||
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
|
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||||
std::stringstream stream(input);
|
std::stringstream stream(input);
|
||||||
stream.unsetf(std::ios::dec);
|
stream.unsetf(std::ios::dec);
|
||||||
stream >> output;
|
stream >> output;
|
||||||
return !!stream;
|
if(!!stream)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(std::numeric_limits<T>::has_infinity && IsInfinity(input)) {
|
||||||
|
output = std::numeric_limits<T>::infinity();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(std::numeric_limits<T>::has_quiet_NaN && IsNaN(input)) {
|
||||||
|
output = std::numeric_limits<T>::quiet_NaN();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -803,6 +803,67 @@ namespace Test
|
|||||||
|
|
||||||
return ExpectedTagValue(node, "!");
|
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<doc.size();i++)
|
||||||
|
if(doc[i].to<double>() != std::numeric_limits<double>::infinity())
|
||||||
|
return false;
|
||||||
|
for(unsigned i=0;i<doc.size();i++)
|
||||||
|
if(doc[i].to<long double>() != std::numeric_limits<long double>::infinity())
|
||||||
|
return false;
|
||||||
|
for(unsigned i=0;i<doc.size();i++)
|
||||||
|
if(doc[i].to<float>() != std::numeric_limits<float>::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<doc.size();i++) {
|
||||||
|
double d;
|
||||||
|
doc[i] >> d;
|
||||||
|
if(d == d)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(unsigned i=0;i<doc.size();i++) {
|
||||||
|
long double d;
|
||||||
|
doc[i] >> d;
|
||||||
|
if(d == d)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(unsigned i=0;i<doc.size();i++) {
|
||||||
|
float d;
|
||||||
|
doc[i] >> d;
|
||||||
|
if(d == d)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -1079,6 +1140,8 @@ namespace Test
|
|||||||
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
||||||
RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total);
|
RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total);
|
||||||
RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific 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, false, "UTF-8, no BOM", passed, total);
|
||||||
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);
|
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);
|
||||||
|
Reference in New Issue
Block a user