convert.cpp (1816B)
1 #include <algorithm> 2 3 #include "yaml-cpp/node/convert.h" 4 5 namespace { 6 // we're not gonna mess with the mess that is all the isupper/etc. functions 7 bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } 8 bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } 9 char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; } 10 11 std::string tolower(const std::string& str) { 12 std::string s(str); 13 std::transform(s.begin(), s.end(), s.begin(), ToLower); 14 return s; 15 } 16 17 template <typename T> 18 bool IsEntirely(const std::string& str, T func) { 19 return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); }); 20 } 21 22 // IsFlexibleCase 23 // . Returns true if 'str' is: 24 // . UPPERCASE 25 // . lowercase 26 // . Capitalized 27 bool IsFlexibleCase(const std::string& str) { 28 if (str.empty()) 29 return true; 30 31 if (IsEntirely(str, IsLower)) 32 return true; 33 34 bool firstcaps = IsUpper(str[0]); 35 std::string rest = str.substr(1); 36 return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); 37 } 38 } // namespace 39 40 namespace YAML { 41 bool convert<bool>::decode(const Node& node, bool& rhs) { 42 if (!node.IsScalar()) 43 return false; 44 45 // we can't use iostream bool extraction operators as they don't 46 // recognize all possible values in the table below (taken from 47 // http://yaml.org/type/bool.html) 48 static const struct { 49 std::string truename, falsename; 50 } names[] = { 51 {"y", "n"}, 52 {"yes", "no"}, 53 {"true", "false"}, 54 {"on", "off"}, 55 }; 56 57 if (!IsFlexibleCase(node.Scalar())) 58 return false; 59 60 for (const auto& name : names) { 61 if (name.truename == tolower(node.Scalar())) { 62 rhs = true; 63 return true; 64 } 65 66 if (name.falsename == tolower(node.Scalar())) { 67 rhs = false; 68 return true; 69 } 70 } 71 72 return false; 73 } 74 } // namespace YAML