From 58d7081e7f98c8cd69c89af5efcaa7268e385922 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Mon, 3 Jun 2024 10:47:26 +0200 Subject: [PATCH] [argparse] update library Update to PR https://github.com/p-ranav/argparse/pull/356 Also fixes the incompatibility between store_into and scan and action: when the three methods above were called, being all based on the (unique) action, the last one would overwrite the previous ones. This issue was making the parser strictly dependant on the order of the scan/store_into/action calls making them mutually exclusive. --- apps/argparse/README.TXT | 3 ++- apps/argparse/argparse.hpp | 46 +++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/apps/argparse/README.TXT b/apps/argparse/README.TXT index 395f64ad669b..d2f296a7f1c8 100644 --- a/apps/argparse/README.TXT +++ b/apps/argparse/README.TXT @@ -1,3 +1,4 @@ Provenance: https://github.com/p-ranav/argparse -Retrieved from https://github.com/p-ranav/argparse/blob/b85a0a414d415fccdf6d77072421b1d3887c8f79/include/argparse/argparse.hpp +Retrieved: https://github.com/p-ranav/argparse/blob/8dead89026466b3818e9c6b6b1d938600db39d8f/include/argparse/argparse.hpp + diff --git a/apps/argparse/argparse.hpp b/apps/argparse/argparse.hpp index d472ba933023..4767b9e125af 100644 --- a/apps/argparse/argparse.hpp +++ b/apps/argparse/argparse.hpp @@ -678,9 +678,9 @@ class Argument { std::is_void_v>, void_action, valued_action>; if constexpr (sizeof...(Args) == 0) { - m_action.emplace(std::forward(callable)); + m_actions.emplace_back(std::forward(callable)); } else { - m_action.emplace( + m_actions.emplace_back( [f = std::forward(callable), tup = std::make_tuple(std::forward(bound_args)...)]( std::string const &opt) mutable { @@ -702,14 +702,7 @@ class Argument { template ::value>::type * = nullptr> auto &store_into(T &var) { if (m_default_value.has_value()) { - try - { - var = std::any_cast(m_default_value); - } - catch (...) - { - var = static_cast(std::any_cast(m_default_value)); - } + var = std::any_cast(m_default_value); } action([&var](const auto &s) { var = details::parse_number()(s); @@ -719,14 +712,7 @@ class Argument { auto &store_into(double &var) { if (m_default_value.has_value()) { - try - { - var = std::any_cast(m_default_value); - } - catch (...) - { - var = std::any_cast(m_default_value); - } + var = std::any_cast(m_default_value); } action([&var](const auto &s) { var = details::parse_number()(s); @@ -994,7 +980,12 @@ class Argument { if (num_args_max == 0) { if (!dry_run) { m_values.emplace_back(m_implicit_value); - std::visit([](const auto &f) { f({}); }, m_action); + for(auto &action: m_actions) { + std::visit([&](const auto &f) { f({}); }, action); + } + if(m_actions.empty()){ + std::visit([&](const auto &f) { f({}); }, m_default_action); + } m_is_used = true; } return start; @@ -1011,8 +1002,7 @@ class Argument { std::bind(is_optional, std::placeholders::_1, m_prefix_chars)); dist = static_cast(std::distance(start, end)); if (dist < num_args_min) { - throw std::runtime_error("Too few arguments for '" + - std::string(m_used_name) + "'."); + throw std::runtime_error("Too few arguments"); } } @@ -1035,7 +1025,12 @@ class Argument { Argument &self; }; if (!dry_run) { - std::visit(ActionApply{start, end, *this}, m_action); + for(auto &action: m_actions) { + std::visit(ActionApply{start, end, *this}, action); + } + if(m_actions.empty()){ + std::visit(ActionApply{start, end, *this}, m_default_action); + } m_is_used = true; } return end; @@ -1585,9 +1580,10 @@ class Argument { std::optional> m_choices{std::nullopt}; using valued_action = std::function; using void_action = std::function; - std::variant m_action{ - std::in_place_type, - [](const std::string &value) { return value; }}; + std::vector> m_actions; + std::variant m_default_action{ + std::in_place_type, + [](const std::string &value) { return value; }}; std::vector m_values; NArgsRange m_num_args_range{1, 1}; // Bit field of bool values. Set default value in ctor.