#ifndef ARGPARSER_SINGLE_OPT_H #define ARGPARSER_SINGLE_OPT_H #include #include #include #include #include #include "option.h" #include "parse-result.h" #include "type.h" namespace argparser { template class option_impl : public option, public std::enable_shared_from_this> { public: option_impl(std::string name, type_handle_impl type) : option(std::move(name)), type(std::move(type)) {} std::shared_ptr> required() { required_ = true; return this->shared_from_this(); } std::shared_ptr> default_value(T val) { this->default_value_ = val; this->has_default_value = true; return this->shared_from_this(); } void validate(const parse_result &res) const override { if (this->required_) { if (!res.has_opt(this->name)) { throw errors::missing_option_error(this->name); } } } [[nodiscard]] bool consumes_value() const override { return true; } [[nodiscard]] T get(const parse_result &pr) const { auto v = pr.get_opt(name); if (!v.has_value()) { if (has_default_value) { return default_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(); 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"); } } type_handle_impl type; bool required_ = false; bool has_default_value = false; T default_value_; }; template using option_handle_impl = std::shared_ptr>; }// namespace argparser #endif//ARGPARSER_SINGLE_OPT_H