21struct ParseError :
public std::exception {
26 ParseError(
const string &t) : token(t) { }
27 ParseError(
const string &t,
const string &e) : token(t), expected(e) { }
29 const char *what()
const throw()
override {
return token.c_str(); }
32struct ParseBoolError :
public ParseError {
33 using ParseError::ParseError;
36struct ParseOnOffError :
public ParseError {
37 using ParseError::ParseError;
40struct ParseNumError :
public ParseError {
41 using ParseError::ParseError;
44struct EnumParseError :
public ParseError {
45 using ParseError::ParseError;
48bool isBool(
const string& token);
49bool isOnOff(
const string& token);
50bool isNum(
const string& token);
52bool parseBool(
const string& token)
throws;
53bool parseOnOff(
const string& token)
throws;
54long parseNum(
const string& token)
throws;
55string parseSeq(
const string& token)
throws;
57template <
typename Enum>
long parseEnum(
const string& key)
59 return parsePartialEnum <Enum> (key, [](
long){
return true; });
62template <
typename R,
typename Enum> R parseEnum(
const string& key)
64 return (R)parseEnum <Enum> (key);
67template <
typename Enum>
long parsePartialEnum(
const string& key, std::function<
bool(
long)> accept)
69 string upper, prefix, suffix;
72 for (
auto c : key) { upper += (char)std::toupper(c); }
75 for (isize i = Enum::minVal; i <= Enum::maxVal; i++) {
77 if (!accept(i))
continue;
79 auto enumkey = string(Enum::key(i));
82 if (enumkey == upper)
return i;
85 if (
auto pos = enumkey.find(
'.'); pos != std::string::npos) {
86 if (enumkey.substr(pos + 1, string::npos) == upper)
return i;
90 throw EnumParseError(key, Enum::keyList());
93template <
typename R,
typename Enum> R parsePartialEnum(
const string& key, std::function<
bool(
long)> accept)
95 return (R)parsePartialEnum<Enum>(key, accept);