#ifndef ARGPARSER_REPEAT_ARG_H #define ARGPARSER_REPEAT_ARG_H #include "argument.h" #include "errors.h" #include "parse-result.h" #include "type.h" #include #include #include #include #include #include #include namespace argparser { template class repeatable_arg : public arg, public std::enable_shared_from_this> { public: repeatable_arg(std::string name, type_handle_impl type) : arg(std::move(name)), type(type) {} std::shared_ptr> min(size_t min) { min_ = min; return this->shared_from_this(); } std::shared_ptr> max(size_t max) { max_ = max; return this->shared_from_this(); } [[nodiscard]] std::vector get(const parse_result &pr) const { auto v = pr.get_arg(name); if (!v.has_value()) { return std::vector{}; } return std::any_cast>(v); } [[nodiscard]] bool has(const parse_result &pr) const { return pr.has_arg(name); } private: type_handle_impl type; std::optional max_; std::optional min_; void do_parse(std::string input, parse_result &pr) const override { auto current_val = pr.get_arg(name); std::vector values; if (current_val.has_value()) { values = std::any_cast>(current_val); } assert(!max_.has_value() || values.size() < max_.value()); auto val = this->parse_single_value(input, type); values.push_back(val); pr.set_arg(name, std::make_any>(std::move(values))); } [[nodiscard]] bool get_can_parse_more(parse_result &pr) const override { if (max_.has_value()) { auto val = pr.get_arg(name); if (!val.has_value()) { return true; } return std::any_cast>(val).size() < max_.value(); } else { return true; } } [[nodiscard]] bool get_has_parsed_enough(parse_result &pr) const override { if (min_.has_value() && min_.value() > 0) { auto val = pr.get_arg(name); if (!val.has_value()) { return false; } auto val_ = std::any_cast>(val); return val_.size() >= min_.value(); } else { return true; } } }; template using repeatable_arg_handle = std::shared_ptr>; }// namespace argparser #endif//ARGPARSER_REPEAT_ARG_H