get this all compiling; currently with a pair notation; should be a simple return type instead

This commit is contained in:
marcel 2021-04-28 15:00:18 +02:00
parent a6bbe0e50a
commit abc841d184
5 changed files with 118 additions and 69 deletions

View File

@ -298,6 +298,14 @@ class YAML_CPP_API BadFile : public Exception {
BadFile(const BadFile&) = default; BadFile(const BadFile&) = default;
~BadFile() YAML_CPP_NOEXCEPT override; ~BadFile() YAML_CPP_NOEXCEPT override;
}; };
namespace conversion{
class DecodeException : public std::runtime_error {
using runtime_error::runtime_error;
};
}
} // namespace YAML } // namespace YAML
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@ -15,6 +15,7 @@
#include <sstream> #include <sstream>
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <stdexcept>
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/impl.h"
@ -24,6 +25,19 @@
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
namespace YAML{
namespace conversion{
namespace exception{
class DecodeException : public std::runtime_error {
using runtime_error::runtime_error;
};
}
}
}
namespace YAML { namespace YAML {
class Binary; class Binary;
struct _Null; struct _Null;
@ -63,12 +77,12 @@ template <>
struct convert<std::string> { struct convert<std::string> {
static Node encode(const std::string& rhs) { return Node(rhs); } static Node encode(const std::string& rhs) { return Node(rhs); }
static bool decode(const Node& node, std::string& rhs) { static std::pair<bool, std::string> decode(const Node& node) {
if (!node.IsScalar()) if (!node.IsScalar())
return false; throw conversion::DecodeException("");
rhs = node.Scalar(); return std::make_pair(true, node.Scalar());
return true;
} }
}; };
// C-strings can only be encoded // C-strings can only be encoded
@ -91,8 +105,10 @@ template <>
struct convert<_Null> { struct convert<_Null> {
static Node encode(const _Null& /* rhs */) { return Node(); } static Node encode(const _Null& /* rhs */) { return Node(); }
static bool decode(const Node& node, _Null& /* rhs */) { static std::pair<bool, _Null> decode(const Node& node) {
return node.IsNull(); 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()); \ return Node(stream.str()); \
} \ } \
\ \
static bool decode(const Node& node, type& rhs) { \ static std::pair<bool, type> decode(const Node& node) { \
if (node.Type() != NodeType::Scalar) { \ if (node.Type() != NodeType::Scalar) { \
return false; \ throw conversion::DecodeException(""); \
} \ } \
const std::string& input = node.Scalar(); \ const std::string& input = node.Scalar(); \
std::stringstream stream(input); \ std::stringstream stream(input); \
stream.unsetf(std::ios::dec); \ stream.unsetf(std::ios::dec); \
if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \ if ((stream.peek() == '-') && std::is_unsigned<type>::value) { \
return false; \ throw conversion::DecodeException(""); \
} \ } \
type rhs; \
if (conversion::ConvertStreamTo(stream, rhs)) { \ if (conversion::ConvertStreamTo(stream, rhs)) { \
return true; \ throw conversion::DecodeException(""); \
} \ } \
if (std::numeric_limits<type>::has_infinity) { \ if (std::numeric_limits<type>::has_infinity) { \
if (conversion::IsInfinity(input)) { \ if (conversion::IsInfinity(input)) { \
rhs = std::numeric_limits<type>::infinity(); \ return std::make_pair(true, \
return true; \ std::numeric_limits<type>::infinity()); \
} else if (conversion::IsNegativeInfinity(input)) { \ } else if (conversion::IsNegativeInfinity(input)) { \
rhs = negative_op std::numeric_limits<type>::infinity(); \ return std::make_pair(true, \
return true; \ negative_op std::numeric_limits<type>::infinity()); \
} \ } \
} \ } \
\ \
if (std::numeric_limits<type>::has_quiet_NaN) { \ if (std::numeric_limits<type>::has_quiet_NaN) { \
if (conversion::IsNaN(input)) { \ if (conversion::IsNaN(input)) { \
rhs = std::numeric_limits<type>::quiet_NaN(); \ rhs = std::numeric_limits<type>::quiet_NaN(); \
return true; \ return std::make_pair(true, \
std::numeric_limits<type>::quiet_NaN()); \
} \ } \
} \ } \
\ \
return false; \ throw conversion::DecodeException(""); \
} \ } \
} }
@ -222,7 +240,7 @@ template <>
struct convert<bool> { struct convert<bool> {
static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } 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<bool, bool> decode(const Node& node);
}; };
// std::map // std::map
@ -235,11 +253,11 @@ struct convert<std::map<K, V, C, A>> {
return node; return node;
} }
static bool decode(const Node& node, std::map<K, V, C, A>& rhs) { static std::pair<bool, std::map<K, V, C, A> > decode(const Node& node) {
if (!node.IsMap()) if (!node.IsMap())
return false; throw conversion::DecodeException("");
rhs.clear(); std::map<K, V, C, A> rhs;
for (const auto& element : node) for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3: // workaround for GCC 3:
@ -247,7 +265,7 @@ struct convert<std::map<K, V, C, A>> {
#else #else
rhs[element.first.as<K>()] = element.second.as<V>(); rhs[element.first.as<K>()] = element.second.as<V>();
#endif #endif
return true; return std::make_pair(true, rhs);
} }
}; };
@ -261,11 +279,11 @@ struct convert<std::vector<T, A>> {
return node; return node;
} }
static bool decode(const Node& node, std::vector<T, A>& rhs) { static std::pair<bool, std::vector<T, A> > decode(const Node& node) {
if (!node.IsSequence()) if (!node.IsSequence())
return false; throw conversion::DecodeException("");
rhs.clear(); std::vector<T, A> rhs;
for (const auto& element : node) for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3: // workaround for GCC 3:
@ -273,7 +291,7 @@ struct convert<std::vector<T, A>> {
#else #else
rhs.push_back(element.as<T>()); rhs.push_back(element.as<T>());
#endif #endif
return true; return std::make_pair(true, rhs);
} }
}; };
@ -287,11 +305,11 @@ struct convert<std::list<T,A>> {
return node; return node;
} }
static bool decode(const Node& node, std::list<T,A>& rhs) { static std::pair<bool, std::list<T,A> > decode(const Node& node) {
if (!node.IsSequence()) if (!node.IsSequence())
return false; throw conversion::DecodeException("");
rhs.clear(); std::list<T,A> rhs;
for (const auto& element : node) for (const auto& element : node)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3: // workaround for GCC 3:
@ -299,7 +317,7 @@ struct convert<std::list<T,A>> {
#else #else
rhs.push_back(element.as<T>()); rhs.push_back(element.as<T>());
#endif #endif
return true; return std::make_pair(true, rhs);
} }
}; };
@ -314,11 +332,11 @@ struct convert<std::array<T, N>> {
return node; return node;
} }
static bool decode(const Node& node, std::array<T, N>& rhs) { static std::pair<bool, std::array<T, N> > decode(const Node& node) {
if (!isNodeValid(node)) { if (!isNodeValid(node))
return false; throw conversion::DecodeException("");
}
std::array<T, N> rhs;
for (auto i = 0u; i < node.size(); ++i) { for (auto i = 0u; i < node.size(); ++i) {
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3: // workaround for GCC 3:
@ -327,7 +345,7 @@ struct convert<std::array<T, N>> {
rhs[i] = node[i].as<T>(); rhs[i] = node[i].as<T>();
#endif #endif
} }
return true; return std::make_pair(true, rhs);
} }
private: private:
@ -346,12 +364,11 @@ struct convert<std::pair<T, U>> {
return node; return node;
} }
static bool decode(const Node& node, std::pair<T, U>& rhs) { static std::pair<bool, std::pair<T, U> > decode(const Node& node) {
if (!node.IsSequence()) if (!node.IsSequence() or node.size() != 2)
return false; throw conversion::DecodeException("");
if (node.size() != 2)
return false;
std::pair<T, U> rhs;
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
// workaround for GCC 3: // workaround for GCC 3:
rhs.first = node[0].template as<T>(); rhs.first = node[0].template as<T>();
@ -364,7 +381,7 @@ struct convert<std::pair<T, U>> {
#else #else
rhs.second = node[1].as<U>(); rhs.second = node[1].as<U>();
#endif #endif
return true; return std::make_pair(true, rhs);
} }
}; };
@ -375,16 +392,17 @@ struct convert<Binary> {
return Node(EncodeBase64(rhs.data(), rhs.size())); return Node(EncodeBase64(rhs.data(), rhs.size()));
} }
static bool decode(const Node& node, Binary& rhs) { static std::pair<bool, Binary> decode(const Node& node) {
if (!node.IsScalar()) if (!node.IsScalar())
return false; throw conversion::DecodeException("");
std::vector<unsigned char> data = DecodeBase64(node.Scalar()); std::vector<unsigned char> data = DecodeBase64(node.Scalar());
if (data.empty() && !node.Scalar().empty()) if (data.empty() && !node.Scalar().empty())
return false; throw conversion::DecodeException("");
Binary rhs;
rhs.swap(data); rhs.swap(data);
return true; return std::make_pair(true, rhs);
} }
}; };
} }

View File

@ -98,19 +98,31 @@ struct remove_idx<Key,
template <typename T> template <typename T>
inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
T lhs; try {
if (convert<T>::decode(Node(*this, pMemory), lhs)) { const auto rslt = convert<T>::decode(Node(*this, pMemory));
return lhs == rhs; 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) { inline bool node::equals(const char* rhs, shared_memory_holder pMemory) {
std::string lhs; try {
if (convert<std::string>::decode(Node(*this, std::move(pMemory)), lhs)) { const auto rslt =
return lhs == rhs; convert<std::string>::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 // indexing

View File

@ -15,6 +15,7 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
namespace YAML { namespace YAML {
inline Node::Node() inline Node::Node()
: m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {} : m_isValid(true), m_invalidKey{}, m_pMemory(nullptr), m_pNode(nullptr) {}
@ -97,10 +98,15 @@ struct as_if {
if (!node.m_pNode) if (!node.m_pNode)
return fallback; return fallback;
T t; try {
if (convert<T>::decode(node, t)) const auto rslt = convert<T>::decode(node);
return t; if (rslt.first)
return fallback; return rslt.second;
} catch (conversion::DecodeException& e) {
return fallback;
} catch (...) {
std::rethrow_exception(std::current_exception());
}
} }
}; };
@ -127,11 +133,18 @@ struct as_if<T, void> {
if (!node.m_pNode) if (!node.m_pNode)
throw TypedBadConversion<T>(node.Mark()); throw TypedBadConversion<T>(node.Mark());
T t; try {
if (convert<T>::decode(node, t)) auto result = convert<T>::decode(node);
return t; if (result.first)
throw TypedBadConversion<T>(node.Mark()); return result.second;
} else
throw TypedBadConversion<T>(node.Mark());
} catch(const conversion::DecodeException& e) {
throw TypedBadConversion<T>(node.Mark());
} catch (...) {
std::rethrow_exception(std::current_exception());
}
};
}; };
template <> template <>

View File

@ -38,9 +38,9 @@ bool IsFlexibleCase(const std::string& str) {
} // namespace } // namespace
namespace YAML { namespace YAML {
bool convert<bool>::decode(const Node& node, bool& rhs) { std::pair<bool, bool> convert<bool>::decode(const Node& node) {
if (!node.IsScalar()) if (!node.IsScalar())
return false; throw conversion::DecodeException("");
// we can't use iostream bool extraction operators as they don't // we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from // recognize all possible values in the table below (taken from
@ -55,20 +55,18 @@ bool convert<bool>::decode(const Node& node, bool& rhs) {
}; };
if (!IsFlexibleCase(node.Scalar())) if (!IsFlexibleCase(node.Scalar()))
return false; throw conversion::DecodeException("");
for (const auto& name : names) { for (const auto& name : names) {
if (name.truename == tolower(node.Scalar())) { if (name.truename == tolower(node.Scalar())) {
rhs = true; return std::make_pair(true, true);
return true;
} }
if (name.falsename == tolower(node.Scalar())) { if (name.falsename == tolower(node.Scalar())) {
rhs = false; return std::make_pair(true, false);
return true;
} }
} }
return false; throw conversion::DecodeException("");
} }
} // namespace YAML } // namespace YAML