Added default parameters for the as<> function (new API)

This commit is contained in:
Jesse Beder
2012-01-12 01:03:31 -06:00
parent ddc578dbd7
commit d1e4c2640c
3 changed files with 81 additions and 15 deletions

View File

@@ -65,25 +65,76 @@ namespace YAML
} }
// access // access
// template helpers
template<typename T, typename S>
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<T>::decode(node, t))
return t;
return fallback;
}
};
template<typename S>
struct as_if<std::string, S> {
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<typename T>
struct as_if<T, void> {
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<T>::decode(node, t))
return t;
throw std::runtime_error("Unable to convert to type");
}
};
template<>
struct as_if<std::string, void> {
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<typename T> template<typename T>
inline const T Node::as() const inline const T Node::as() const
{ {
if(!m_pNode) return as_if<T, void>(*this)();
throw std::runtime_error("Unable to convert to type");
T t;
if(convert<T>::decode(*this, t))
return t;
throw std::runtime_error("Unable to convert to type");
} }
template<> template<typename T, typename S>
inline const std::string Node::as() const inline const T Node::as(const S& fallback) const
{ {
if(Type() != NodeType::Scalar) return as_if<T, S>(*this)(fallback);
throw std::runtime_error("Unable to convert to string, not a scalar"); }
return Scalar();
}
inline const std::string& Node::Scalar() const inline const std::string& Node::Scalar() const
{ {

View File

@@ -22,6 +22,7 @@ namespace YAML
friend class NodeEvents; friend class NodeEvents;
friend class detail::node_data; friend class detail::node_data;
template<typename> friend class detail::iterator_base; template<typename> friend class detail::iterator_base;
template<typename T, typename S> friend struct as_if;
Node(); Node();
explicit Node(NodeType::value type); explicit Node(NodeType::value type);
@@ -43,6 +44,7 @@ namespace YAML
// access // access
template<typename T> const T as() const; template<typename T> const T as() const;
template<typename T, typename S> const T as(const S& fallback) const;
const std::string& Scalar() const; const std::string& Scalar() const;
const std::string& Tag() const; const std::string& Tag() const;
void SetTag(const std::string& tag); void SetTag(const std::string& tag);

View File

@@ -286,6 +286,18 @@ namespace Test
node = YAML::Node(); node = YAML::Node();
return true; return true;
} }
TEST FallbackValues()
{
YAML::Node node = YAML::Load("foo: bar\nx: 2");
YAML_ASSERT(node["foo"].as<std::string>() == "bar");
YAML_ASSERT(node["foo"].as<std::string>("hello") == "bar");
YAML_ASSERT(node["baz"].as<std::string>("hello") == "hello");
YAML_ASSERT(node["x"].as<int>() == 2);
YAML_ASSERT(node["x"].as<int>(5) == 2);
YAML_ASSERT(node["y"].as<int>(5) == 5);
return true;
}
} }
void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) { 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::Bool, "bool", passed, total);
RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total);
RunNodeTest(&Node::Reassign, "reassign", passed, total); RunNodeTest(&Node::Reassign, "reassign", passed, total);
RunNodeTest(&Node::FallbackValues, "fallback values", passed, total);
std::cout << "Node tests: " << passed << "/" << total << " passed\n"; std::cout << "Node tests: " << passed << "/" << total << " passed\n";
return passed == total; return passed == total;