From 8dba9b858e12eff358be780089a6d69ba988bb81 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Fri, 3 Oct 2025 19:41:06 +0200 Subject: [PATCH 1/5] Change signature of from_string function --- include/argparse.hpp | 20 ++++++++++++-------- test/unittest/custom.h | 6 +++--- tutorial/custom1.cpp | 5 +++-- tutorial/custom2.cpp | 7 +++++-- tutorial/custom3.cpp | 7 +++++-- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/include/argparse.hpp b/include/argparse.hpp index 94c5f1d..71c7a35 100644 --- a/include/argparse.hpp +++ b/include/argparse.hpp @@ -103,12 +103,17 @@ namespace argparse class Converter { public: - auto from_string(std::string const & s, T & t) const -> bool + auto from_string(std::string const & s) const -> std::optional { auto iss = std::istringstream(s); + auto t = T(); iss >> t; - return !iss.fail() && (iss.eof() || iss.peek() == std::istringstream::traits_type::eof()); + if (!iss.fail() && (iss.eof() || iss.peek() == std::istringstream::traits_type::eof())) + { + return t; + } + return std::nullopt; } auto to_string(T const & t) const -> std::string @@ -126,10 +131,10 @@ namespace argparse }; template - inline auto from_string(std::string const & s, T & t) -> bool + inline auto from_string(std::string const & s) -> std::optional { auto const conv = Converter(); - return conv.from_string(s, t); + return conv.from_string(s); } template @@ -546,10 +551,9 @@ namespace argparse } else { - auto value = T(); - if (argparse::from_string(string, value)) + if (auto const optvalue = argparse::from_string(string); optvalue.has_value()) { - return std::any(value); + return std::any(*optvalue); } else { @@ -990,7 +994,7 @@ namespace argparse static auto is_negative_number(std::string const & token) -> bool { - if (auto num = double(); from_string(token, num)) + if (auto const parsed = from_string(token); parsed.has_value()) { return true; } diff --git a/test/unittest/custom.h b/test/unittest/custom.h index 1218888..949ac6c 100644 --- a/test/unittest/custom.h +++ b/test/unittest/custom.h @@ -27,10 +27,10 @@ template<> class Converter { public: - auto from_string(std::string const & s, foo::Custom & t) const -> bool + auto from_string(std::string const & s) const -> std::optional { - t = foo::Custom(s); - return true; + auto t = foo::Custom(s); + return t; } auto to_string(foo::Custom const & t) const -> std::string diff --git a/tutorial/custom1.cpp b/tutorial/custom1.cpp index 3ce1101..6a725f5 100644 --- a/tutorial/custom1.cpp +++ b/tutorial/custom1.cpp @@ -24,12 +24,13 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return true; + return p; } auto to_string(geometry::Point const & p) const -> std::string diff --git a/tutorial/custom2.cpp b/tutorial/custom2.cpp index 4c1e7c5..b497438 100644 --- a/tutorial/custom2.cpp +++ b/tutorial/custom2.cpp @@ -24,12 +24,15 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return !iss.fail(); + return !iss.fail() + ? std::optional(p) + : std::nullopt; } auto to_string(geometry::Point const & p) const -> std::string diff --git a/tutorial/custom3.cpp b/tutorial/custom3.cpp index 7b98e1d..a01aa2e 100644 --- a/tutorial/custom3.cpp +++ b/tutorial/custom3.cpp @@ -24,12 +24,15 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return !iss.fail(); + return !iss.fail() + ? std::optional(p) + : std::nullopt; } auto to_string(geometry::Point const & p) const -> std::string From 1ff438e1d5b0c3de066f67e08a1e85507789986c Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Fri, 3 Oct 2025 19:48:18 +0200 Subject: [PATCH 2/5] Adapt code in tutorial's custom1 example --- tutorial/readme.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tutorial/readme.md b/tutorial/readme.md index 49bc635..5c23050 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -958,12 +958,13 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return true; + return p; } auto to_string(geometry::Point const & p) const -> std::string From 1cb77bcf3b1c407481aaf48ef647574506601c6b Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Fri, 3 Oct 2025 19:48:26 +0200 Subject: [PATCH 3/5] Adapt code in tutorial's custom2 example --- tutorial/readme.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tutorial/readme.md b/tutorial/readme.md index 5c23050..0c8b595 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -1034,12 +1034,15 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return !iss.fail(); + return !iss.fail() + ? std::optional(p) + : std::nullopt; } auto to_string(geometry::Point const & p) const -> std::string From 6cdcadfc99a179b9a6c1a0a0bf1b4ad4505e2822 Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Fri, 3 Oct 2025 19:48:45 +0200 Subject: [PATCH 4/5] Adapt code in tutorial's custom3 example --- tutorial/readme.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tutorial/readme.md b/tutorial/readme.md index 0c8b595..91e9d4e 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -1114,12 +1114,15 @@ template<> class Converter { public: - auto from_string(std::string const & s, geometry::Point & p) const -> bool + auto from_string(std::string const & s) const -> std::optional { std::istringstream iss(s); + auto p = geometry::Point(); char comma; iss >> p.x >> comma >> p.y; - return !iss.fail(); + return !iss.fail() + ? std::optional(p) + : std::nullopt; } auto to_string(geometry::Point const & p) const -> std::string From bf0aaf66101537d0f6dfb3ed5666f13e527a23aa Mon Sep 17 00:00:00 2001 From: Krzysiek Karbowiak Date: Fri, 3 Oct 2025 19:54:01 +0200 Subject: [PATCH 5/5] Update tutorial --- tutorial/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorial/readme.md b/tutorial/readme.md index 91e9d4e..a7f08da 100644 --- a/tutorial/readme.md +++ b/tutorial/readme.md @@ -1006,7 +1006,7 @@ optional arguments: $ custom1 0,0 1,1 The distance is 1.41421 ``` -The return value of `argparse::Converter::from_string` indicates whether the conversion succeeded. You can use it to your advantage (`custom2.cpp`): +The `argparse::Converter::from_string` function should return an empty optional to indicate conversion failure. You can use it to your advantage (`custom2.cpp`): ```c++ #include "argparse.hpp" #include