#include #include "yaml-cpp/node/convert.h" 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 bool IsEntirely(const std::string& str, T func) { return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); }); } // 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 namespace YAML { bool convert::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 (const auto& name : names) { if (name.truename == tolower(node.Scalar())) { rhs = true; return true; } if (name.falsename == tolower(node.Scalar())) { rhs = false; return true; } } return false; } } // namespace YAML