#ifndef ARGPARSER_LIST_TYPE_H #define ARGPARSER_LIST_TYPE_H #include "errors.h" #include "type.h" #include #include #include namespace argparser { template class list_type : public type_impl> { public: list_type(std::string name, type_handle_impl element_type) : type_impl>(std::move(name)), element_type(element_type) {} std::vector parse(const char *begin, const char *end, const char *&parse_end, internal::parser_allow_undelimited allow_undelimited) override { auto cur_pos = begin; std::vector values{}; bool is_delimited; if (*cur_pos == '[') { is_delimited = true; cur_pos++; } else { if (!internal::enum_flag_contains(allow_undelimited, internal::parser_allow_undelimited::Comma)) { throw errors::type_parsing_error(this->name, std::string(begin, end), cur_pos - begin, "expected '['"); } else { is_delimited = false; } } if (cur_pos >= end) { throw errors::type_parsing_error(this->name, std::string(begin, end), end - begin, "unexpected end of input"); } internal::parser_allow_undelimited sub_parse_allow_undelimited = internal::parser_allow_undelimited::Parenthesis; if (!is_delimited) { sub_parse_allow_undelimited & allow_undelimited; } while (true) { const char *this_parse_end; auto val = element_type->parse(cur_pos, end, this_parse_end, sub_parse_allow_undelimited); values.push_back(val); cur_pos = this_parse_end; while (std::isspace(*cur_pos) && cur_pos <= end) cur_pos++; if (cur_pos >= end) { if (!is_delimited) { break; } else { throw errors::type_parsing_error(this->name, std::string(begin, end), end - begin, "unexpected end of input"); } } if (*cur_pos == ',') { cur_pos++; auto s = std::string_view(cur_pos, end); auto close_bracket_pos = s.find_first_of(']'); if (s.find_first_not_of(internal::whitespace) == close_bracket_pos) { break; } } else if (!is_delimited || *cur_pos == ']') { break; } else { throw errors::type_parsing_error(this->name, std::string(begin, end), end - begin, "expected , or ]"); } } if (is_delimited) { if (*cur_pos != ']') { throw errors::type_parsing_error(this->name, std::string(begin, end), end - begin, "unexpected end of input"); } else { cur_pos++; } } parse_end = cur_pos; return values; } private: type_handle_impl element_type; }; }// namespace argparser #endif//ARGPARSER_LIST_TYPE_H