From abc841d184e8aeceb4aa7ed0060f82eb7b9e6465 Mon Sep 17 00:00:00 2001 From: marcel Date: Wed, 28 Apr 2021 15:00:18 +0200 Subject: [PATCH] get this all compiling; currently with a pair notation; should be a simple return type instead --- include/yaml-cpp/exceptions.h | 8 +++ include/yaml-cpp/node/convert.h | 106 ++++++++++++++++------------ include/yaml-cpp/node/detail/impl.h | 28 +++++--- include/yaml-cpp/node/impl.h | 31 +++++--- src/convert.cpp | 14 ++-- 5 files changed, 118 insertions(+), 69 deletions(-) diff --git a/include/yaml-cpp/exceptions.h b/include/yaml-cpp/exceptions.h index c3f4474..f08f17a 100644 --- a/include/yaml-cpp/exceptions.h +++ b/include/yaml-cpp/exceptions.h @@ -298,6 +298,14 @@ class YAML_CPP_API BadFile : public Exception { BadFile(const BadFile&) = default; ~BadFile() YAML_CPP_NOEXCEPT override; }; + + +namespace conversion{ + class DecodeException : public std::runtime_error { + using runtime_error::runtime_error; + }; +} + } // namespace YAML #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h index 596898d..12089ea 100644 --- a/include/yaml-cpp/node/convert.h +++ b/include/yaml-cpp/node/convert.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "yaml-cpp/binary.h" #include "yaml-cpp/node/impl.h" @@ -24,6 +25,19 @@ #include "yaml-cpp/null.h" + +namespace YAML{ +namespace conversion{ +namespace exception{ +class DecodeException : public std::runtime_error { + using runtime_error::runtime_error; +}; +} +} +} + + + namespace YAML { class Binary; struct _Null; @@ -63,12 +77,12 @@ template <> struct convert { static Node encode(const std::string& rhs) { return Node(rhs); } - static bool decode(const Node& node, std::string& rhs) { + static std::pair decode(const Node& node) { if (!node.IsScalar()) - return false; - rhs = node.Scalar(); - return true; + throw conversion::DecodeException(""); + return std::make_pair(true, node.Scalar()); } + }; // C-strings can only be encoded @@ -91,8 +105,10 @@ template <> struct convert<_Null> { static Node encode(const _Null& /* rhs */) { return Node(); } - static bool decode(const Node& node, _Null& /* rhs */) { - return node.IsNull(); + static std::pair decode(const Node& node) { + if (!node.IsNull()) + throw conversion::DecodeException(""); + return std::make_pair(node.IsNull(), _Null()); } }; @@ -156,37 +172,39 @@ ConvertStreamTo(std::stringstream& stream, T& rhs) { return Node(stream.str()); \ } \ \ - static bool decode(const Node& node, type& rhs) { \ + static std::pair decode(const Node& node) { \ if (node.Type() != NodeType::Scalar) { \ - return false; \ + throw conversion::DecodeException(""); \ } \ const std::string& input = node.Scalar(); \ std::stringstream stream(input); \ stream.unsetf(std::ios::dec); \ if ((stream.peek() == '-') && std::is_unsigned::value) { \ - return false; \ + throw conversion::DecodeException(""); \ } \ + type rhs; \ if (conversion::ConvertStreamTo(stream, rhs)) { \ - return true; \ + throw conversion::DecodeException(""); \ } \ if (std::numeric_limits::has_infinity) { \ if (conversion::IsInfinity(input)) { \ - rhs = std::numeric_limits::infinity(); \ - return true; \ + return std::make_pair(true, \ + std::numeric_limits::infinity()); \ } else if (conversion::IsNegativeInfinity(input)) { \ - rhs = negative_op std::numeric_limits::infinity(); \ - return true; \ + return std::make_pair(true, \ + negative_op std::numeric_limits::infinity()); \ } \ } \ \ if (std::numeric_limits::has_quiet_NaN) { \ if (conversion::IsNaN(input)) { \ rhs = std::numeric_limits::quiet_NaN(); \ - return true; \ + return std::make_pair(true, \ + std::numeric_limits::quiet_NaN()); \ } \ } \ \ - return false; \ + throw conversion::DecodeException(""); \ } \ } @@ -222,7 +240,7 @@ template <> struct convert { static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } - YAML_CPP_API static bool decode(const Node& node, bool& rhs); + YAML_CPP_API static std::pair decode(const Node& node); }; // std::map @@ -235,11 +253,11 @@ struct convert> { return node; } - static bool decode(const Node& node, std::map& rhs) { + static std::pair > decode(const Node& node) { if (!node.IsMap()) - return false; + throw conversion::DecodeException(""); - rhs.clear(); + std::map rhs; for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: @@ -247,7 +265,7 @@ struct convert> { #else rhs[element.first.as()] = element.second.as(); #endif - return true; + return std::make_pair(true, rhs); } }; @@ -261,11 +279,11 @@ struct convert> { return node; } - static bool decode(const Node& node, std::vector& rhs) { + static std::pair > decode(const Node& node) { if (!node.IsSequence()) - return false; + throw conversion::DecodeException(""); - rhs.clear(); + std::vector rhs; for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: @@ -273,7 +291,7 @@ struct convert> { #else rhs.push_back(element.as()); #endif - return true; + return std::make_pair(true, rhs); } }; @@ -287,11 +305,11 @@ struct convert> { return node; } - static bool decode(const Node& node, std::list& rhs) { + static std::pair > decode(const Node& node) { if (!node.IsSequence()) - return false; + throw conversion::DecodeException(""); - rhs.clear(); + std::list rhs; for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: @@ -299,7 +317,7 @@ struct convert> { #else rhs.push_back(element.as()); #endif - return true; + return std::make_pair(true, rhs); } }; @@ -314,11 +332,11 @@ struct convert> { return node; } - static bool decode(const Node& node, std::array& rhs) { - if (!isNodeValid(node)) { - return false; - } + static std::pair > decode(const Node& node) { + if (!isNodeValid(node)) + throw conversion::DecodeException(""); + std::array rhs; for (auto i = 0u; i < node.size(); ++i) { #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: @@ -327,7 +345,7 @@ struct convert> { rhs[i] = node[i].as(); #endif } - return true; + return std::make_pair(true, rhs); } private: @@ -346,12 +364,11 @@ struct convert> { return node; } - static bool decode(const Node& node, std::pair& rhs) { - if (!node.IsSequence()) - return false; - if (node.size() != 2) - return false; + static std::pair > decode(const Node& node) { + if (!node.IsSequence() or node.size() != 2) + throw conversion::DecodeException(""); + std::pair rhs; #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: rhs.first = node[0].template as(); @@ -364,7 +381,7 @@ struct convert> { #else rhs.second = node[1].as(); #endif - return true; + return std::make_pair(true, rhs); } }; @@ -375,16 +392,17 @@ struct convert { return Node(EncodeBase64(rhs.data(), rhs.size())); } - static bool decode(const Node& node, Binary& rhs) { + static std::pair decode(const Node& node) { if (!node.IsScalar()) - return false; + throw conversion::DecodeException(""); std::vector data = DecodeBase64(node.Scalar()); if (data.empty() && !node.Scalar().empty()) - return false; + throw conversion::DecodeException(""); + Binary rhs; rhs.swap(data); - return true; + return std::make_pair(true, rhs); } }; } diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h index b38038d..fe95b5d 100644 --- a/include/yaml-cpp/node/detail/impl.h +++ b/include/yaml-cpp/node/detail/impl.h @@ -98,19 +98,31 @@ struct remove_idx inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { - T lhs; - if (convert::decode(Node(*this, pMemory), lhs)) { - return lhs == rhs; + try { + const auto rslt = convert::decode(Node(*this, pMemory)); + if (rslt.first) { + return rslt.second == rhs; + } + return false; + } catch (const conversion::DecodeException& e) { + return false; + } catch(...) { + std::rethrow_exception(std::current_exception()); } - return false; } inline bool node::equals(const char* rhs, shared_memory_holder pMemory) { - std::string lhs; - if (convert::decode(Node(*this, std::move(pMemory)), lhs)) { - return lhs == rhs; + try { + const auto rslt = + convert::decode(Node(*this, std::move(pMemory))); + if (rslt.first) + return rslt.second == rhs; + return false; + } catch (const conversion::DecodeException& e) { + return false; + } catch(...) { + std::rethrow_exception(std::current_exception()); } - return false; } // indexing diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index 97dc282..50e1939 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -15,6 +15,7 @@ #include #include + namespace YAML { inline Node::Node() : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {} @@ -97,10 +98,15 @@ struct as_if { if (!node.m_pNode) return fallback; - T t; - if (convert::decode(node, t)) - return t; - return fallback; + try { + const auto rslt = convert::decode(node); + if (rslt.first) + return rslt.second; + } catch (conversion::DecodeException& e) { + return fallback; + } catch (...) { + std::rethrow_exception(std::current_exception()); + } } }; @@ -127,11 +133,18 @@ struct as_if { if (!node.m_pNode) throw TypedBadConversion(node.Mark()); - T t; - if (convert::decode(node, t)) - return t; - throw TypedBadConversion(node.Mark()); - } + try { + auto result = convert::decode(node); + if (result.first) + return result.second; + else + throw TypedBadConversion(node.Mark()); + } catch(const conversion::DecodeException& e) { + throw TypedBadConversion(node.Mark()); + } catch (...) { + std::rethrow_exception(std::current_exception()); + } + }; }; template <> diff --git a/src/convert.cpp b/src/convert.cpp index 9658b36..5f0b832 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -38,9 +38,9 @@ bool IsFlexibleCase(const std::string& str) { } // namespace namespace YAML { -bool convert::decode(const Node& node, bool& rhs) { +std::pair convert::decode(const Node& node) { if (!node.IsScalar()) - return false; + throw conversion::DecodeException(""); // we can't use iostream bool extraction operators as they don't // recognize all possible values in the table below (taken from @@ -55,20 +55,18 @@ bool convert::decode(const Node& node, bool& rhs) { }; if (!IsFlexibleCase(node.Scalar())) - return false; + throw conversion::DecodeException(""); for (const auto& name : names) { if (name.truename == tolower(node.Scalar())) { - rhs = true; - return true; + return std::make_pair(true, true); } if (name.falsename == tolower(node.Scalar())) { - rhs = false; - return true; + return std::make_pair(true, false); } } - return false; + throw conversion::DecodeException(""); } } // namespace YAML