75 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <algorithm>
 | 
						|
 | 
						|
#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 <typename T>
 | 
						|
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<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 (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
 |