diff --git a/src/yycc/carton/clap/parser.hpp b/src/yycc/carton/clap/parser.hpp index 36c052c..aea936b 100644 --- a/src/yycc/carton/clap/parser.hpp +++ b/src/yycc/carton/clap/parser.hpp @@ -45,10 +45,9 @@ namespace yycc::carton::clap::parser { NS_YYCC_CLAP_TYPES::ClapResult get_flag_option(NS_YYCC_CLAP_TYPES::Token token) const; template NS_YYCC_CLAP_TYPES::ClapResult> get_value_option( - NS_YYCC_CLAP_TYPES::Token token) const { + NS_YYCC_CLAP_TYPES::Token token, const T& validator = T()) const { auto raw_value = this->get_raw_value_option(token); if (raw_value.has_value()) { - T validator{}; auto value = validator.validate(raw_value.value()); if (value.has_value()) return value.value(); else return std::unexpected(NS_YYCC_CLAP_TYPES::ClapError::BadCast); diff --git a/src/yycc/carton/clap/resolver.hpp b/src/yycc/carton/clap/resolver.hpp index 5159d75..49ee25b 100644 --- a/src/yycc/carton/clap/resolver.hpp +++ b/src/yycc/carton/clap/resolver.hpp @@ -45,10 +45,9 @@ namespace yycc::carton::clap::resolver { NS_YYCC_CLAP_TYPES::ClapResult get_flag_variable(NS_YYCC_CLAP_TYPES::Token token) const; template NS_YYCC_CLAP_TYPES::ClapResult> get_value_variable( - NS_YYCC_CLAP_TYPES::Token token) const { + NS_YYCC_CLAP_TYPES::Token token, const T& validator = T()) const { auto raw_value = this->get_raw_value_variable(token); if (raw_value.has_value()) { - T validator{}; auto value = validator.validate(raw_value.value()); if (value.has_value()) return value.value(); else return std::unexpected(NS_YYCC_CLAP_TYPES::ClapError::BadCast); diff --git a/src/yycc/carton/clap/validator.hpp b/src/yycc/carton/clap/validator.hpp index d5ca76d..8408b18 100644 --- a/src/yycc/carton/clap/validator.hpp +++ b/src/yycc/carton/clap/validator.hpp @@ -1,4 +1,5 @@ #pragma once +#include "../../macro/class_copy_move.hpp" #include "../../num/parse.hpp" #include #include @@ -23,9 +24,11 @@ namespace yycc::carton::clap::validator { * otherwise, it is the validated value. * * Finally, it must can be default initialized. + * Please note that this class may be initialized during each calling. + * Please make sure that its ctor will not consume too much resources. */ template - concept Validator = std::default_initializable && requires(const T& t, const std::u8string_view& sv) { + concept Validator = requires(const T& t, const std::u8string_view& sv) { // Check whether there is T::ReturnType type typename T::ReturnType; // Check whether there is "validate" member function and it has correct signature. @@ -38,7 +41,10 @@ namespace yycc::carton::clap::validator { template::min(), auto TMax = std::numeric_limits::max()> struct IntegralValidator { + YYCC_DEFAULT_COPY_MOVE(IntegralValidator) + static_assert(TMin <= TMax); + using ReturnType = T; std::optional validate(const std::u8string_view& sv) { auto rv = NS_YYCC_NUM_PARSE::parse(sv); @@ -52,9 +58,12 @@ namespace yycc::carton::clap::validator { template::lowest(), auto TMax = std::numeric_limits::max()> struct FloatingPointValidator { + YYCC_DEFAULT_COPY_MOVE(FloatingPointValidator) + static_assert(std::isfinite(TMin)); static_assert(std::isfinite(TMax)); static_assert(TMin <= TMax); + using ReturnType = T; std::optional validate(const std::u8string_view& sv) { auto rv = NS_YYCC_NUM_PARSE::parse(sv); @@ -67,6 +76,8 @@ namespace yycc::carton::clap::validator { }; struct BoolValidator { + YYCC_DEFAULT_COPY_MOVE(BoolValidator) + using ReturnType = bool; std::optional validate(const std::u8string_view& sv) { auto rv = NS_YYCC_NUM_PARSE::parse(sv); @@ -76,6 +87,8 @@ namespace yycc::carton::clap::validator { }; struct StringValidator { + YYCC_DEFAULT_COPY_MOVE(StringValidator) + using ReturnType = std::u8string; std::optional validate(const std::u8string_view& sv) { return std::u8string(sv); } };