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,26 +65,77 @@ namespace YAML
}
// 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>
inline const T Node::as() const
{
if(!m_pNode)
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<>
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<T, void>(*this)();
}
template<typename T, typename S>
inline const T Node::as(const S& fallback) const
{
return as_if<T, S>(*this)(fallback);
}
inline const std::string& Node::Scalar() const
{
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;

View File

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

View File

@ -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<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) {
@ -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;