From 924bb8b00e801d64dcfa11b434abc0c63a70f654 Mon Sep 17 00:00:00 2001 From: beder Date: Thu, 12 Jan 2012 01:03:31 -0600 Subject: [PATCH] Added default parameters for the as<> function (new API) --- include/yaml-cpp/node/impl.h | 81 +++++++++++++++++++++++++++++------- include/yaml-cpp/node/node.h | 2 + test/new-api/nodetests.cpp | 13 ++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index e379461..b58b394 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -65,26 +65,77 @@ namespace YAML } // access + + // template helpers + template + struct as_if { + explicit as_if(const Node& node_): node(node_) {} + const Node& node; + + const T operator()(const S& fallback) const { + if(!node.m_pNode) + return fallback; + + T t; + if(convert::decode(node, t)) + return t; + return fallback; + } + }; + + template + struct as_if { + explicit as_if(const Node& node_): node(node_) {} + const Node& node; + + const std::string operator()(const S& fallback) const { + if(node.Type() != NodeType::Scalar) + return fallback; + return node.Scalar(); + } + }; + + template + struct as_if { + explicit as_if(const Node& node_): node(node_) {} + const Node& node; + + const T operator()() const { + if(!node.m_pNode) + throw std::runtime_error("Unable to convert to type"); + + T t; + if(convert::decode(node, t)) + return t; + throw std::runtime_error("Unable to convert to type"); + } + }; + + template<> + struct as_if { + explicit as_if(const Node& node_): node(node_) {} + const Node& node; + + const std::string operator()() const { + if(node.Type() != NodeType::Scalar) + throw std::runtime_error("Unable to convert to string, not a scalar"); + return node.Scalar(); + } + }; + + // access functions template inline const T Node::as() const { - if(!m_pNode) - throw std::runtime_error("Unable to convert to type"); - - T t; - if(convert::decode(*this, t)) - return t; - throw std::runtime_error("Unable to convert to type"); - } - - template<> - inline const std::string Node::as() const - { - if(Type() != NodeType::Scalar) - throw std::runtime_error("Unable to convert to string, not a scalar"); - return Scalar(); + return as_if(*this)(); } + template + inline const T Node::as(const S& fallback) const + { + return as_if(*this)(fallback); + } + inline const std::string& Node::Scalar() const { return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h index 8066057..9445624 100644 --- a/include/yaml-cpp/node/node.h +++ b/include/yaml-cpp/node/node.h @@ -22,6 +22,7 @@ namespace YAML friend class NodeEvents; friend class detail::node_data; template friend class detail::iterator_base; + template friend struct as_if; Node(); explicit Node(NodeType::value type); @@ -43,6 +44,7 @@ namespace YAML // access template const T as() const; + template const T as(const S& fallback) const; const std::string& Scalar() const; const std::string& Tag() const; void SetTag(const std::string& tag); diff --git a/test/new-api/nodetests.cpp b/test/new-api/nodetests.cpp index c41afed..74f92ae 100644 --- a/test/new-api/nodetests.cpp +++ b/test/new-api/nodetests.cpp @@ -286,6 +286,18 @@ namespace Test node = YAML::Node(); return true; } + + TEST FallbackValues() + { + YAML::Node node = YAML::Load("foo: bar\nx: 2"); + YAML_ASSERT(node["foo"].as() == "bar"); + YAML_ASSERT(node["foo"].as("hello") == "bar"); + YAML_ASSERT(node["baz"].as("hello") == "hello"); + YAML_ASSERT(node["x"].as() == 2); + YAML_ASSERT(node["x"].as(5) == 2); + YAML_ASSERT(node["y"].as(5) == 5); + return true; + } } void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) { @@ -332,6 +344,7 @@ namespace Test RunNodeTest(&Node::Bool, "bool", passed, total); RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); RunNodeTest(&Node::Reassign, "reassign", passed, total); + RunNodeTest(&Node::FallbackValues, "fallback values", passed, total); std::cout << "Node tests: " << passed << "/" << total << " passed\n"; return passed == total;