From c4b3b5e52e390e542c7dcda95effbc37544d676a Mon Sep 17 00:00:00 2001 From: beder Date: Sun, 13 Nov 2011 16:05:42 -0600 Subject: [PATCH] Added (unspecified-type) bool conversions for Node (new API) --- include/yaml-cpp/node/detail/bool_type.h | 26 ++++++++++++++++++++++++ include/yaml-cpp/node/impl.h | 5 +++++ include/yaml-cpp/node/node.h | 6 ++++++ test/new-api/nodetests.cpp | 11 ++++++++++ 4 files changed, 48 insertions(+) create mode 100644 include/yaml-cpp/node/detail/bool_type.h diff --git a/include/yaml-cpp/node/detail/bool_type.h b/include/yaml-cpp/node/detail/bool_type.h new file mode 100644 index 0000000..80ed9a4 --- /dev/null +++ b/include/yaml-cpp/node/detail/bool_type.h @@ -0,0 +1,26 @@ +#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +namespace YAML +{ + namespace detail + { + struct unspecified_bool { + struct NOT_ALLOWED; + static void true_value(NOT_ALLOWED*) {} + }; + typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); + } +} + +#define YAML_CPP_OPERATOR_BOOL()\ +operator YAML::detail::unspecified_bool_type() const\ +{\ + return this->operator!() ? 0 : &YAML::detail::unspecified_bool::true_value;\ +} + +#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index ac4089f..d562161 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -49,6 +49,11 @@ namespace YAML m_pNode->set_null(); } } + + inline bool Node::IsDefined() const + { + return m_pNode ? m_pNode->is_defined() : true; + } inline NodeType::value Node::Type() const { diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h index 95df7cb..348b653 100644 --- a/include/yaml-cpp/node/node.h +++ b/include/yaml-cpp/node/node.h @@ -10,6 +10,7 @@ #include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/type.h" #include "yaml-cpp/node/detail/iterator_fwd.h" +#include "yaml-cpp/node/detail/bool_type.h" #include namespace YAML @@ -29,11 +30,16 @@ namespace YAML ~Node(); NodeType::value Type() const; + bool IsDefined() const; bool IsNull() const { return Type() == NodeType::Null; } bool IsScalar() const { return Type() == NodeType::Scalar; } bool IsSequence() const { return Type() == NodeType::Sequence; } bool IsMap() const { return Type() == NodeType::Map; } + // bool conversions + YAML_CPP_OPERATOR_BOOL(); + bool operator!() const { return !IsDefined(); } + // access template const T as() const; const std::string& Scalar() const; diff --git a/test/new-api/nodetests.cpp b/test/new-api/nodetests.cpp index 37602fd..9b9bc2e 100644 --- a/test/new-api/nodetests.cpp +++ b/test/new-api/nodetests.cpp @@ -268,6 +268,16 @@ namespace Test YAML_ASSERT(node[true].as() == false); return true; } + + TEST AutoBoolConversion() + { + YAML::Node node; + node["foo"] = "bar"; + YAML_ASSERT(static_cast(node["foo"])); + YAML_ASSERT(!node["monkey"]); + YAML_ASSERT(!!node["foo"]); + return true; + } } void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) { @@ -312,6 +322,7 @@ namespace Test RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total); RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total); RunNodeTest(&Node::Bool, "bool", passed, total); + RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); std::cout << "Node tests: " << passed << "/" << total << " passed\n"; return passed == total;