mirror of
https://git.lynn.is/Gwen/argparser.git
synced 2024-04-29 14:43:46 +02:00
96 lines
2.8 KiB
C++
96 lines
2.8 KiB
C++
#ifndef ARGPARSER_REPEAT_ARG_H
|
|
#define ARGPARSER_REPEAT_ARG_H
|
|
|
|
#include "argument.h"
|
|
#include "errors.h"
|
|
#include "parse-result.h"
|
|
#include "type.h"
|
|
#include <any>
|
|
#include <cassert>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <span>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace argparser {
|
|
|
|
template<typename T>
|
|
class repeatable_arg : public arg, public std::enable_shared_from_this<repeatable_arg<T>> {
|
|
public:
|
|
repeatable_arg(std::string name, type_handle_impl<T> type) : arg(std::move(name)), type(type) {}
|
|
|
|
std::shared_ptr<repeatable_arg<T>> min(size_t min) {
|
|
min_ = min;
|
|
return this->shared_from_this();
|
|
}
|
|
|
|
std::shared_ptr<repeatable_arg<T>> max(size_t max) {
|
|
max_ = max;
|
|
return this->shared_from_this();
|
|
}
|
|
|
|
|
|
[[nodiscard]] std::vector<T> get(const parse_result &pr) const {
|
|
auto v = pr.get_arg(name);
|
|
if (!v.has_value()) {
|
|
return std::vector<T>{};
|
|
}
|
|
return std::any_cast<std::vector<T>>(v);
|
|
}
|
|
|
|
[[nodiscard]] bool has(const parse_result &pr) const {
|
|
return pr.has_arg(name);
|
|
}
|
|
|
|
private:
|
|
type_handle_impl<T> type;
|
|
std::optional<size_t> max_;
|
|
std::optional<size_t> min_;
|
|
|
|
void do_parse(std::string input, parse_result &pr) const override {
|
|
auto current_val = pr.get_arg(name);
|
|
std::vector<T> values;
|
|
if (current_val.has_value()) {
|
|
values = std::any_cast<std::vector<T>>(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::vector<T>>(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<std::vector<T>>(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<std::vector<T>>(val);
|
|
return val_.size() >= min_.value();
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
using repeatable_arg_handle = std::shared_ptr<repeatable_arg<T>>;
|
|
}// namespace argparser
|
|
|
|
|
|
#endif//ARGPARSER_REPEAT_ARG_H
|