Added bool conversions

This commit is contained in:
Jesse Beder
2011-09-14 01:48:36 -05:00
parent e5d0366797
commit f64f619c29
3 changed files with 103 additions and 5 deletions

View File

@@ -24,7 +24,7 @@ namespace YAML
} }
static bool decode(const Node& node, std::string& rhs) { static bool decode(const Node& node, std::string& rhs) {
if(node.Type() != NodeType::Scalar) if(!node.IsScalar())
return false; return false;
rhs = node.Scalar(); rhs = node.Scalar();
return true; return true;
@@ -38,7 +38,7 @@ namespace YAML
} }
static bool decode(const Node& node, _Null& /* rhs */) { static bool decode(const Node& node, _Null& /* rhs */) {
return node.Type() == NodeType::Null; return node.IsNull();
} }
}; };
@@ -78,6 +78,16 @@ namespace YAML
#undef YAML_DEFINE_CONVERT_STREAMABLE #undef YAML_DEFINE_CONVERT_STREAMABLE
// bool
template<>
struct convert<bool> {
static Node encode(bool rhs) {
return rhs ? Node("true") : Node("false");
}
static bool decode(const Node& node, bool& rhs);
};
// std::map // std::map
template<typename K, typename V> template<typename K, typename V>
struct convert<std::map<K, V> > { struct convert<std::map<K, V> > {
@@ -89,7 +99,7 @@ namespace YAML
} }
static bool decode(const Node& node, std::map<K, V>& rhs) { static bool decode(const Node& node, std::map<K, V>& rhs) {
if(node.Type() != NodeType::Map) if(!node.IsMap())
return false; return false;
rhs.clear(); rhs.clear();
@@ -110,7 +120,7 @@ namespace YAML
} }
static bool decode(const Node& node, std::vector<T>& rhs) { static bool decode(const Node& node, std::vector<T>& rhs) {
if(node.Type() != NodeType::Sequence) if(!node.IsSequence())
return false; return false;
rhs.clear(); rhs.clear();
@@ -131,7 +141,7 @@ namespace YAML
} }
static bool decode(const Node& node, std::list<T>& rhs) { static bool decode(const Node& node, std::list<T>& rhs) {
if(node.Type() != NodeType::Sequence) if(!node.IsSequence())
return false; return false;
rhs.clear(); rhs.clear();

View File

@@ -1,5 +1,83 @@
#include "yaml-cpp/node/convert.h" #include "yaml-cpp/node/convert.h"
#include "yaml-cpp/node/impl.h"
#include <algorithm>
namespace
{
// we're not gonna mess with the mess that is all the isupper/etc. functions
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str)
{
std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower);
return s;
}
template <typename T>
bool IsEntirely(const std::string& str, T func)
{
for(std::size_t i=0;i<str.size();i++)
if(!func(str[i]))
return false;
return true;
}
// IsFlexibleCase
// . Returns true if 'str' is:
// . UPPERCASE
// . lowercase
// . Capitalized
bool IsFlexibleCase(const std::string& str)
{
if(str.empty())
return true;
if(IsEntirely(str, IsLower))
return true;
bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
}
namespace YAML namespace YAML
{ {
bool convert<bool>::decode(const Node& node, bool& rhs) {
if(!node.IsScalar())
return false;
// we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from
// http://yaml.org/type/bool.html)
static const struct {
std::string truename, falsename;
} names[] = {
{ "y", "n" },
{ "yes", "no" },
{ "true", "false" },
{ "on", "off" },
};
if(!IsFlexibleCase(node.Scalar()))
return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
if(names[i].truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
if(names[i].falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
}
return false;
}
} }

View File

@@ -259,6 +259,15 @@ namespace Test
YAML_ASSERT(node["other"] == node["key"]); YAML_ASSERT(node["other"] == node["key"]);
return true; return true;
} }
TEST Bool()
{
YAML::Node node;
node[true] = false;
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node[true].as<bool>() == false);
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) {
@@ -302,6 +311,7 @@ namespace Test
RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total); RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total);
RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total); RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total);
RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total); RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total);
RunNodeTest(&Node::Bool, "bool", passed, total);
std::cout << "Node tests: " << passed << "/" << total << " passed\n"; std::cout << "Node tests: " << passed << "/" << total << " passed\n";
return passed == total; return passed == total;