From 52f1f060557985a16c427a51a5de22a441b2a3cd Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:01:50 +0200 Subject: [PATCH 1/6] feat(Parser): impl Parse for: int, std::string, bool --- include/Parser.hpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/include/Parser.hpp b/include/Parser.hpp index 89eddfa..302e229 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -3,11 +3,42 @@ #include "Arg.hpp" #include "utils.hpp" +#include #include #include #include #include +template +struct Parse { + static_assert(sizeof(T) == 0, "No Parse specialization defined for this type"); +}; + +template<> +struct Parse { + static std::optional parse(std::string_view s) { + int value; + auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); + if (ec == std::errc()) return value; + return std::nullopt; + } +}; + +template<> +struct Parse { + static std::optional parse(std::string_view s) { + return std::string(s); + } +}; + +template<> +struct Parse { + static std::optional parse(std::string_view s) { + auto as_int = Parse::parse(s).value(); + return as_int; + } +}; + class ClapParser { public: void add_arg(const Arg& arg); From 1bc25c8e6dcd94de313e4820023bc984b7665c3d Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:03:09 +0200 Subject: [PATCH 2/6] feat(Parser): added a 'Parseable' c++ concept --- include/Parser.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/Parser.hpp b/include/Parser.hpp index 302e229..4046498 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -39,6 +39,11 @@ struct Parse { } }; +template +concept Parseable = requires(std::string_view s) { + { Parse::parse(s) } -> std::convertible_to>; +}; + class ClapParser { public: void add_arg(const Arg& arg); From 950d6575417c1e5fb4a85cb83f34acb9191176ca Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:04:24 +0200 Subject: [PATCH 3/6] feat(Parser): parser uses way better parsing method! --- include/Parser.hpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/include/Parser.hpp b/include/Parser.hpp index 4046498..3caf513 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -50,15 +50,19 @@ class ClapParser { void parse(const int& argc, char* argv[]); void print_help() const; - template inline std::optional get_one_as(const std::string& name) { + template + requires Parseable + inline std::optional get_one_as(const std::string& name) { Arg* arg = ok_or(ClapParser::find_arg(*this, "--" + name), []{ return std::nullopt; }); - if (auto arg_value = arg->get__value(); arg_value) { - T value; - std::istringstream(*arg_value) >> value; - return value; - } - return std::nullopt; + // if (auto arg_value = arg->get__value(); arg_value) { + // T value; + // std::istringstream(*arg_value) >> value; + // return value; + // } + // return std::nullopt; + + return Parse::parse(arg->get__value().value()); } static void print_parser(std::ostream& os, const ClapParser& parser, int indent); From 0da288c6c481e10bae980d4d91847e0ecb1ee945 Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:16:06 +0200 Subject: [PATCH 4/6] feat(Parser): impl Parse for (most) numeric types --- include/Parser.hpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/include/Parser.hpp b/include/Parser.hpp index 3caf513..c2d69ff 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -11,16 +11,22 @@ template struct Parse { - static_assert(sizeof(T) == 0, "No Parse specialization defined for this type"); -}; - -template<> -struct Parse { - static std::optional parse(std::string_view s) { - int value; - auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); - if (ec == std::errc()) return value; - return std::nullopt; + static std::optional parse(std::string_view s) { + if constexpr (std::is_integral_v) { + T value; + auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); + if (ec == std::errc()) return value; + return std::nullopt; + } + else if constexpr (std::is_floating_point_v) { + T value; + auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); + if (ec == std::errc()) return value; + return std::nullopt; + } + else { + static_assert(sizeof(T) == 0, "No Parse specialization defined for this type"); + } } }; From 8545e16826c2f35710ca3792bad7d6e5c0ac659d Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:19:28 +0200 Subject: [PATCH 5/6] fix(Parser): include 'charconv', remove 'cmath' --- include/Parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Parser.hpp b/include/Parser.hpp index c2d69ff..aea750e 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -3,7 +3,7 @@ #include "Arg.hpp" #include "utils.hpp" -#include +#include #include #include #include From fee7117ea8386988556c63031b66a62350510f5c Mon Sep 17 00:00:00 2001 From: csboo Date: Wed, 14 May 2025 03:27:11 +0200 Subject: [PATCH 6/6] fix(Parser): more explicit number casting for MacOS compatibility --- include/Parser.hpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/include/Parser.hpp b/include/Parser.hpp index aea750e..dd7b0c7 100644 --- a/include/Parser.hpp +++ b/include/Parser.hpp @@ -3,6 +3,11 @@ #include "Arg.hpp" #include "utils.hpp" +#include +#include +#include +#include +#include #include #include #include @@ -18,10 +23,22 @@ struct Parse { if (ec == std::errc()) return value; return std::nullopt; } - else if constexpr (std::is_floating_point_v) { - T value; - auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), value); - if (ec == std::errc()) return value; + else if constexpr (std::is_same_v) { + char* end = nullptr; + float value = std::strtof(s.data(), &end); + if (end == s.data() + s.size()) return value; + return std::nullopt; + } + else if constexpr (std::is_same_v) { + char* end = nullptr; + double value = std::strtod(s.data(), &end); + if (end == s.data() + s.size()) return value; + return std::nullopt; + } + else if constexpr (std::is_same_v) { + char* end = nullptr; + long double value = std::strtold(s.data(), &end); + if (end == s.data() + s.size()) return value; return std::nullopt; } else {