diff --git a/toml/parser.hpp b/toml/parser.hpp index 4e00af6..858465d 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -7,23 +7,6 @@ namespace toml { -template -struct parse_barekey -{ - typedef charT value_type; - typedef toml::key result_type; - static_assert(std::is_same::value, "char type is different from default key type"); - - template::value_type, - value_type>::value>::type> - static result_type invoke(Iterator iter, Iterator end) - { - return result_type(iter, end); - } -}; - template struct parse_escape_sequence { @@ -507,6 +490,207 @@ struct parse_datetime } }; +template +struct parse_fixed_type_array +{ + typedef charT value_type; + typedef toml::Array result_type; + typedef acceptorT acceptor_type; + typedef parserT parser_type; + typedef is_skippable_in_array skippable; + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + result_type result; + assert(*iter == '[' && *end == ']'); + ++iter; --end; + iter = skippable::invoke(iter); + while(iter != end) + { + const Iterator tmp = acceptor_type::invoke(iter); + result.emplace_back(parser_type::invoke(iter, tmp)); + iter = tmp; + iter = skippable::invoke(iter); + iter = is_charactor::invoke(iter); + iter = skippable::invoke(iter); + } + return result; + } +}; + +template +struct parse_inline_table; + +template +struct parse_array +{ + typedef charT value_type; + typedef toml::Array result_type; + typedef is_skippable_in_array skippable; + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + const Iterator init = skippable::invoke(std::next(iter)); + if(is_boolean::invoke(init) != init) + return parse_fixed_type_array, + parse_boolean>::invoke(iter, end); + + if(is_integer::invoke(init) != init) + return parse_fixed_type_array, + parse_integer>::invoke(iter, end); + + if(is_float::invoke(init) != init) + return parse_fixed_type_array, + parse_float>::invoke(iter, end); + + if(is_string::invoke(init) != init) + return parse_fixed_type_array, + parse_string>::invoke(iter, end); + + if(is_datetime::invoke(init) != init) + return parse_fixed_type_array, + parse_datetime>::invoke(iter, end); + + if(is_array::invoke(init) != init) + return parse_fixed_type_array, + parse_array>::invoke(iter, end); + + if(is_inline_table::invoke(init) != init) + return parse_fixed_type_array, + parse_inline_table>::invoke(iter, end); + + throw internal_error("no valid array here"); + } +}; + +template +struct parse_value +{ + typedef charT value_type; + typedef toml::value result_type; + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + if(iter != is_string::invoke(iter)) + return result_type(parse_string::invoke(iter, end)); + else if(iter != is_integer::invoke(iter)) + return result_type(parse_integer::invoke(iter, end)); + else if(iter != is_float::invoke(iter)) + return result_type(parse_float::invoke(iter, end)); + else if(iter != is_boolean::invoke(iter)) + return result_type(parse_boolean::invoke(iter, end)); + else if(iter != is_datetime::invoke(iter)) + return result_type(parse_datetime::invoke(iter, end)); + else if(iter != is_array::invoke(iter)) + return result_type(parse_array::invoke(iter, end)); + else if(iter != is_inline_table::invoke(iter)) + return result_type(parse_inline_table::invoke(iter, end)); + + throw internal_error("no valid value here"); + } +}; + +template +struct parse_barekey +{ + typedef charT value_type; + typedef toml::key result_type; + static_assert(std::is_same::value, "char type is different from default key type"); + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + return result_type(iter, end); + } +}; + +template +struct parse_key +{ + typedef charT value_type; + typedef toml::key result_type; + static_assert(std::is_same::value, "char type is different from default key type"); + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + if(iter != is_barekey::invoke(iter)) + return parse_barekey(iter, end); + else if(iter != is_string::invoke(iter)) + return parse_string(iter, end); + throw internal_error("no valid key here"); + } +}; + +template +struct parse_key_value_pair +{ + typedef charT value_type; + typedef std::pair result_type; + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + Iterator tmp = is_key::invoke(iter); + const toml::key k = parse_key::invoke(iter, tmp); + iter = tmp; + iter = is_any_num_of_ws::invoke(iter); + assert(*iter == '='); ++iter; + iter = is_any_num_of_ws::invoke(iter); + tmp = is_value::invoke(iter); + const toml::value v = parse_value::invoke(iter, tmp); + return std::make_pair(k, v); + } +}; + +template +struct parse_inline_table +{ + typedef charT value_type; + typedef toml::Table result_type; + + template::value_type, + value_type>::value>::type> + static result_type invoke(Iterator iter, Iterator end) + { + assert(*iter == '{' && *end == '}'); + ++iter; --end; + iter = is_any_num_of_ws::invoke(iter); + + result_type result; + + while(iter != end) + { + Iterator tmp = is_key_value_pair::invoke(iter); + result.emplace(parse_key_value_pair::invoke(iter, tmp)); + iter = tmp; + + iter = is_any_num_of_ws::invoke(iter); + iter = is_charactor::invoke(iter); + iter = is_any_num_of_ws::invoke(iter); + } + return result; + } +}; + + }// toml #endif// TOML11_PARSER