From 27d88f83d94895196e7c9b016597eee70227c786 Mon Sep 17 00:00:00 2001 From: dota17 Date: Thu, 21 May 2020 11:27:02 +0800 Subject: [PATCH] fix issue 844/848: support the as/as --- include/yaml-cpp/node/convert.h | 43 +++++++++++++++++++++++++++-- test/integration/load_node_test.cpp | 16 ++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h index db7e44d..1d9ae48 100644 --- a/include/yaml-cpp/node/convert.h +++ b/include/yaml-cpp/node/convert.h @@ -7,15 +7,16 @@ #pragma once #endif +#include #include #include +#include #include #include #include #include #include #include -#include #include "yaml-cpp/binary.h" #include "yaml-cpp/node/impl.h" @@ -114,6 +115,44 @@ typename std::enable_if::value, void>::type inner_encode(const T& rhs, std::stringstream& stream){ stream << rhs; } + +template +typename std::enable_if::value, bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + uint16_t num; + if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { + rhs = std::min(num, (uint16_t)UINT8_MAX); + return true; + } + return false; +} + +template +typename std::enable_if::value, bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + int16_t num; + if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { + if (num > INT8_MAX) { + rhs = INT8_MAX; + } else if (num < INT8_MIN) { + rhs = INT8_MIN; + } else { + rhs = num; + } + return true; + } + return false; +} + +template +typename std::enable_if::value || + std::is_same::value), bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { + return true; + } + return false; +} } #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ @@ -137,7 +176,7 @@ inner_encode(const T& rhs, std::stringstream& stream){ if ((stream.peek() == '-') && std::is_unsigned::value) { \ return false; \ } \ - if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { \ + if (conversion::ConvertStreamTo(stream, rhs)) { \ return true; \ } \ if (std::numeric_limits::has_infinity) { \ diff --git a/test/integration/load_node_test.cpp b/test/integration/load_node_test.cpp index 9a93a68..f556413 100644 --- a/test/integration/load_node_test.cpp +++ b/test/integration/load_node_test.cpp @@ -21,7 +21,7 @@ TEST(LoadNodeTest, FallbackValues) { } TEST(LoadNodeTest, NumericConversion) { - Node node = Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); + Node node = Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015, -128, 127, 128, 255, 256, a, ab]"); EXPECT_EQ(1.5f, node[0].as()); EXPECT_EQ(1.5, node[0].as()); EXPECT_THROW(node[0].as(), TypedBadConversion); @@ -32,11 +32,25 @@ TEST(LoadNodeTest, NumericConversion) { EXPECT_EQ(-std::numeric_limits::infinity(), node[4].as()); EXPECT_EQ(21, node[5].as()); EXPECT_EQ(13, node[6].as()); + EXPECT_EQ(-128, +node[7].as()); + EXPECT_EQ(127, +node[8].as()); + EXPECT_EQ(127, +node[9].as()); + EXPECT_EQ(255, +node[10].as()); + EXPECT_EQ(255, +node[11].as()); + // test as/as with ‘a’,"ab",'1',"127" + EXPECT_EQ('a', node[12].as()); + EXPECT_THROW(node[13].as(), TypedBadConversion); + EXPECT_EQ('1', node[1].as()); + EXPECT_THROW(node[8].as(), TypedBadConversion); + EXPECT_THROW(node[12].as(), TypedBadConversion); + EXPECT_THROW(node[13].as(), TypedBadConversion); + EXPECT_EQ(1, +node[1].as()); // Throw exception: convert a negative number to an unsigned number. EXPECT_THROW(node[7].as(), TypedBadConversion); EXPECT_THROW(node[7].as(), TypedBadConversion); EXPECT_THROW(node[7].as(), TypedBadConversion); EXPECT_THROW(node[7].as(), TypedBadConversion); + EXPECT_THROW(node[7].as(), TypedBadConversion); } TEST(LoadNodeTest, Binary) {