#ifndef ARGPARSER_REPEAT_OPT_H #define ARGPARSER_REPEAT_OPT_H #include #include #include #include #include #include "errors.h" #include "option.h" #include "parse-result.h" #include "type.h" namespace argparser { template class repeatable_option_impl : public option, public std::enable_shared_from_this> { public: repeatable_option_impl(std::string name, type_handle_impl type) : option(std::move(name)), type(std::move(type)) {} std::shared_ptr> default_value(std::vector val) { this->default_value_ = std::make_optional(val); return this->shared_from_this(); } std::shared_ptr> min(unsigned int min) { this->min_ = min; return this->shared_from_this(); } std::shared_ptr> max(unsigned int max) { this->max_ = max; return this->shared_from_this(); } void validate(const parse_result &pr) const override { unsigned int count = 0; if (pr.has_opt(this->name)) { count = get(pr).size(); } if ((min_.has_value() && count < min_.value()) || (max_.has_value() && count > max_.value())) { throw errors::wrong_option_count_error(this->name, min_, max_, count); } } [[nodiscard]] bool consumes_value() const override { return true; } [[nodiscard]] std::vector get(const parse_result &pr) const { auto v = pr.get_opt(name); if (!v.has_value()) { if (default_value_.has_value()) { return default_value_.value(); } throw std::runtime_error(std::format("option {} was not provided", name)); } return std::any_cast>(v); } [[nodiscard]] bool has(const parse_result &pr) const { return pr.has_opt(name); } private: void do_parse(std::optional arg, std::any &val) override { assert(arg.has_value()); const char *parse_end; auto begin = &*arg->begin(); auto end = &*arg->end(); auto single_val = this->type->parse(begin, end, parse_end, internal::parser_allow_undelimited::Any); if (parse_end != end) { throw errors::type_parsing_error(this->type->get_name(), std::string(begin, end), parse_end - begin, "unexpected input"); } std::vector val_vec{}; if (val.has_value()) { val_vec = std::any_cast>(val); } val_vec.push_back(single_val); val = std::make_any>(val_vec); } type_handle_impl type; std::optional> default_value_ = std::nullopt; std::optional min_ = std::nullopt; std::optional max_ = std::nullopt; }; template using repeatable_option_handle_impl = std::shared_ptr>; }// namespace argparser #endif//ARGPARSER_REPEAT_OPT_H