From 54415f9527dbbb5830fcaa01456ec5cbe952ec69 Mon Sep 17 00:00:00 2001 From: "killua.z" Date: Tue, 5 May 2026 11:57:36 +0400 Subject: [PATCH] feat: add reference capabilities to positional arguments. use existing v2 api to capture reference arguments. --- src/headers/parser/argument_builder.hpp | 6 +---- src/headers/parser/parser_v2.hpp | 30 ++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/headers/parser/argument_builder.hpp b/src/headers/parser/argument_builder.hpp index 2de870c..26aa89b 100644 --- a/src/headers/parser/argument_builder.hpp +++ b/src/headers/parser/argument_builder.hpp @@ -368,12 +368,8 @@ private: throw std::logic_error("reference() was selected without a target."); } + pairs[argument_parser::v2::flags::Reference] = target; parser.template add_argument(pairs); - parser.on_complete([target, key](argument_parser::base_parser const& completed_parser) { - if (auto value = completed_parser.template get_optional(key)) { - *target = value.value(); - } - }); } auto build_parametered_action(argument_parser::v2::base_parser& parser) const -> void { diff --git a/src/headers/parser/parser_v2.hpp b/src/headers/parser/parser_v2.hpp index bfea633..239ee65 100644 --- a/src/headers/parser/parser_v2.hpp +++ b/src/headers/parser/parser_v2.hpp @@ -154,9 +154,13 @@ namespace argument_parser::v2 { found_params[extended_add_argument_flags::Action] = true; if constexpr (!std::is_same_v) { auto ref = get_or_throw(argument_pairs.at(add_argument_flags::Reference), "reference"); - action = helpers::make_parametered_action([ref](T const& t) { - *ref = t; - }).clone(); + if (action) { + throw std::logic_error("Cannot use both action and reference for the same argument"); + } else { + action = helpers::make_parametered_action([ref](T const& t) { + *ref = t; + }).clone(); + } } else { throw std::logic_error("Reference argument must not be void"); } @@ -255,6 +259,26 @@ namespace argument_parser::v2 { position = get_or_throw(argument_pairs.at(add_argument_flags::Position), "position"); } + if (argument_pairs.find(add_argument_flags::Reference) != argument_pairs.end()) { + if (!IsTyped) { + throw std::logic_error("Reference argument must be typed"); + } + + if constexpr (!std::is_same_v) { + auto ref = get_or_throw(argument_pairs.at(add_argument_flags::Reference), "reference"); + if (action) { + throw std::logic_error("Cannot use both action and reference for the same argument"); + } else { + action = helpers::make_parametered_action([ref](T const& t) { + *ref = t; + }).clone(); + } + } else { + throw std::logic_error("Reference argument must not be void"); + } + } + + if (help_text.empty()) { if constexpr (IsTyped) { if constexpr (internal::sfinae::has_format_hint>::value &&