From 1b4e602709cbd0a2db6e93e9b5aad25046fe3a5a Mon Sep 17 00:00:00 2001 From: Philip Top Date: Wed, 5 Mar 2025 19:38:36 -0800 Subject: [PATCH 1/8] add tests and fixes for array options --- examples/CMakeLists.txt | 6 +++++ examples/array_option.cpp | 15 +++++++++++++ include/CLI/TypeTools.hpp | 2 +- tests/OptionTypeTest.cpp | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 examples/array_option.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ced9bd9c8..3d417a9f0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -219,6 +219,12 @@ add_cli_exe(modhelp modhelp.cpp) add_test(NAME modhelp COMMAND modhelp -a test -h) set_property(TEST modhelp PROPERTY PASS_REGULAR_EXPRESSION "Option -a string in help: test") +if (CMAKE_CXX_STANDARD GREATER 16) + add_cli_exe(array_option array_option.cpp) + add_test(NAME array_option COMMAND array_option --a 1 2) + set_property(TEST array_option PROPERTY PASS_REGULAR_EXPRESSION "pass") + +endif() add_subdirectory(subcom_in_files) add_test(NAME subcom_in_files COMMAND subcommand_main subcommand_a -f this.txt --with-foo) set_property(TEST subcom_in_files PROPERTY PASS_REGULAR_EXPRESSION "Working on file: this\.txt" diff --git a/examples/array_option.cpp b/examples/array_option.cpp new file mode 100644 index 000000000..c8af3c4a9 --- /dev/null +++ b/examples/array_option.cpp @@ -0,0 +1,15 @@ +#include + +#include + +// from @gourin https://github.com/CLIUtils/CLI11/issues/1135 +int main(int argc, char** argv) +{ + std::array a{ 0, 1}; + CLI::App app{"My app"}; + app.add_option("--a", a, "an array")->capture_default_str(); + app.parse(argc, argv); + + std::cout<<"pass\n"; + return 0; +} diff --git a/include/CLI/TypeTools.hpp b/include/CLI/TypeTools.hpp index 4b56f10c5..6388357e9 100644 --- a/include/CLI/TypeTools.hpp +++ b/include/CLI/TypeTools.hpp @@ -387,7 +387,7 @@ inline std::string to_string(T &&) { /// convert a readable container to a string template ::value && !std::is_constructible::value && - !is_ostreamable::value && is_readable_container::value, + !is_ostreamable::value && is_readable_container::value && !is_tuple_like::value, detail::enabler> = detail::dummy> inline std::string to_string(T &&variable) { auto cval = variable.begin(); diff --git a/tests/OptionTypeTest.cpp b/tests/OptionTypeTest.cpp index 212626496..3bd12089b 100644 --- a/tests/OptionTypeTest.cpp +++ b/tests/OptionTypeTest.cpp @@ -27,6 +27,7 @@ #include #include #include +#include using Catch::literals::operator"" _a; @@ -912,6 +913,51 @@ TEST_CASE_METHOD(TApp, "vectorPairTypeRange", "[optiontype]") { CHECK("str4" == custom_opt[2].second); } +TEST_CASE_METHOD(TApp, "ArrayTriple", "[optiontype]") { + + using TY=std::array; + TY custom_opt; + + app.add_option("posit", custom_opt); + + args = {"12", "1","5"}; + + run(); + CHECK(12 == custom_opt[0]); + CHECK(1 == custom_opt[1]); + CHECK(5 == custom_opt[2]); + + // enable_if_t::value && !std::is_constructible::value && + // !is_ostreamable::value && is_tuple_like::value && type_count_base::value >= 2, + // detail::enabler>> + + CHECK(!std::is_convertible::value); + CHECK(!std::is_constructible::value); + CHECK(!CLI::detail::is_ostreamable::value); + auto ts=std::tuple_size::type>::value; + CHECK(ts==3); + + auto vb= CLI::detail::type_count_base::value; + CHECK(vb>=2); + CHECK(!CLI::detail::is_complex::value); + CHECK(CLI::detail::is_tuple_like::value); +} + +TEST_CASE_METHOD(TApp, "ArrayPair", "[optiontype]") { + + using TY=std::array; + TY custom_opt; + + app.add_option("posit", custom_opt); + + args = {"12", "1"}; + + run(); + CHECK(12 == custom_opt[0]); + CHECK(1 == custom_opt[1]); + +} + // now with independent type sizes and expected this is possible TEST_CASE_METHOD(TApp, "vectorTuple", "[optiontype]") { From 02232fedb3a4517833be7647f131c51dd27812fa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 03:51:36 +0000 Subject: [PATCH 2/8] style: pre-commit.ci fixes --- examples/CMakeLists.txt | 10 +++++----- examples/array_option.cpp | 13 ++++++------- tests/OptionTypeTest.cpp | 33 ++++++++++++++++----------------- 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3d417a9f0..297067eb3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -219,11 +219,11 @@ add_cli_exe(modhelp modhelp.cpp) add_test(NAME modhelp COMMAND modhelp -a test -h) set_property(TEST modhelp PROPERTY PASS_REGULAR_EXPRESSION "Option -a string in help: test") -if (CMAKE_CXX_STANDARD GREATER 16) - add_cli_exe(array_option array_option.cpp) - add_test(NAME array_option COMMAND array_option --a 1 2) - set_property(TEST array_option PROPERTY PASS_REGULAR_EXPRESSION "pass") - +if(CMAKE_CXX_STANDARD GREATER 16) + add_cli_exe(array_option array_option.cpp) + add_test(NAME array_option COMMAND array_option --a 1 2) + set_property(TEST array_option PROPERTY PASS_REGULAR_EXPRESSION "pass") + endif() add_subdirectory(subcom_in_files) add_test(NAME subcom_in_files COMMAND subcommand_main subcommand_a -f this.txt --with-foo) diff --git a/examples/array_option.cpp b/examples/array_option.cpp index c8af3c4a9..210ccbb74 100644 --- a/examples/array_option.cpp +++ b/examples/array_option.cpp @@ -3,13 +3,12 @@ #include // from @gourin https://github.com/CLIUtils/CLI11/issues/1135 -int main(int argc, char** argv) -{ - std::array a{ 0, 1}; - CLI::App app{"My app"}; - app.add_option("--a", a, "an array")->capture_default_str(); - app.parse(argc, argv); +int main(int argc, char **argv) { + std::array a{0, 1}; + CLI::App app{"My app"}; + app.add_option("--a", a, "an array")->capture_default_str(); + app.parse(argc, argv); - std::cout<<"pass\n"; + std::cout << "pass\n"; return 0; } diff --git a/tests/OptionTypeTest.cpp b/tests/OptionTypeTest.cpp index 3bd12089b..c1193bdf8 100644 --- a/tests/OptionTypeTest.cpp +++ b/tests/OptionTypeTest.cpp @@ -9,6 +9,7 @@ #include "catch.hpp" #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include using Catch::literals::operator"" _a; @@ -915,37 +915,37 @@ TEST_CASE_METHOD(TApp, "vectorPairTypeRange", "[optiontype]") { TEST_CASE_METHOD(TApp, "ArrayTriple", "[optiontype]") { - using TY=std::array; + using TY = std::array; TY custom_opt; app.add_option("posit", custom_opt); - args = {"12", "1","5"}; + args = {"12", "1", "5"}; run(); - CHECK(12 == custom_opt[0]); + CHECK(12 == custom_opt[0]); CHECK(1 == custom_opt[1]); CHECK(5 == custom_opt[2]); - // enable_if_t::value && !std::is_constructible::value && + // enable_if_t::value && !std::is_constructible::value && // !is_ostreamable::value && is_tuple_like::value && type_count_base::value >= 2, - // detail::enabler>> + // detail::enabler>> - CHECK(!std::is_convertible::value); - CHECK(!std::is_constructible::value); + CHECK(!std::is_convertible::value); + CHECK(!std::is_constructible::value); CHECK(!CLI::detail::is_ostreamable::value); - auto ts=std::tuple_size::type>::value; - CHECK(ts==3); - - auto vb= CLI::detail::type_count_base::value; - CHECK(vb>=2); - CHECK(!CLI::detail::is_complex::value); - CHECK(CLI::detail::is_tuple_like::value); + auto ts = std::tuple_size::type>::value; + CHECK(ts == 3); + + auto vb = CLI::detail::type_count_base::value; + CHECK(vb >= 2); + CHECK(!CLI::detail::is_complex::value); + CHECK(CLI::detail::is_tuple_like::value); } TEST_CASE_METHOD(TApp, "ArrayPair", "[optiontype]") { - using TY=std::array; + using TY = std::array; TY custom_opt; app.add_option("posit", custom_opt); @@ -955,7 +955,6 @@ TEST_CASE_METHOD(TApp, "ArrayPair", "[optiontype]") { run(); CHECK(12 == custom_opt[0]); CHECK(1 == custom_opt[1]); - } // now with independent type sizes and expected this is possible From 68cae80a0788d9e72603f5535fdf4501f77026d5 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Wed, 5 Mar 2025 20:28:52 -0800 Subject: [PATCH 3/8] try initializing v2 --- include/CLI/TypeTools.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/CLI/TypeTools.hpp b/include/CLI/TypeTools.hpp index 6388357e9..8bc3ba718 100644 --- a/include/CLI/TypeTools.hpp +++ b/include/CLI/TypeTools.hpp @@ -1497,7 +1497,7 @@ bool lexical_conversion(const std::vector &strings, AssignTo &outp using FirstType = typename std::remove_const::type>::type; using SecondType = typename std::tuple_element<1, ConvertTo>::type; FirstType v1; - SecondType v2; + SecondType v2{}; bool retval = lexical_assign(strings[0], v1); retval = retval && lexical_assign((strings.size() > 1) ? strings[1] : std::string{}, v2); if(retval) { From 3bb703a0cee192cbd07f4a0340fe332cc3eb4e66 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 6 Mar 2025 05:02:03 -0800 Subject: [PATCH 4/8] fix some warnings --- azure-pipelines.yml | 3 ++- examples/array_option.cpp | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0f8a92c32..4bae11a87 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -99,7 +99,7 @@ jobs: steps: - task: UsePythonVersion@0 inputs: - versionSpec: "3.7" + versionSpec: "3.11" - script: python3 -m pip install meson ninja displayName: install meson - script: mkdir tests/mesonTest/subprojects @@ -140,6 +140,7 @@ jobs: clang3.4: containerImage: silkeh/clang:3.4 cli11.std: 11 + cli11.options: -DCLI11_WARNINGS_AS_ERRORS=OFF clang8: containerImage: silkeh/clang:8 cli11.std: 14 diff --git a/examples/array_option.cpp b/examples/array_option.cpp index 210ccbb74..0d2387f49 100644 --- a/examples/array_option.cpp +++ b/examples/array_option.cpp @@ -1,8 +1,16 @@ -#include +// Copyright (c) 2017-2025, University of Cincinnati, developed by Henry Schreiner +// under NSF AWARD 1414736 and by the respective contributors. +// All rights reserved. +// +// SPDX-License-Identifier: BSD-3-Clause + +// Code modified from @gourin https://github.com/CLIUtils/CLI11/issues/1135 + +#include +#include #include -// from @gourin https://github.com/CLIUtils/CLI11/issues/1135 int main(int argc, char **argv) { std::array a{0, 1}; CLI::App app{"My app"}; From 6dcaa5707851b02cd910e3a80bbbaa082d3996c9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 6 Mar 2025 13:04:26 +0000 Subject: [PATCH 5/8] style: pre-commit.ci fixes --- examples/array_option.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/array_option.cpp b/examples/array_option.cpp index 0d2387f49..827a2638a 100644 --- a/examples/array_option.cpp +++ b/examples/array_option.cpp @@ -6,10 +6,9 @@ // Code modified from @gourin https://github.com/CLIUtils/CLI11/issues/1135 - +#include #include #include -#include int main(int argc, char **argv) { std::array a{0, 1}; From b6378cc3bf96ede13350c9284028e1fca3a1416f Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 6 Mar 2025 05:55:07 -0800 Subject: [PATCH 6/8] remove unnecessary cmake restriction --- examples/CMakeLists.txt | 8 +++----- examples/array_option.cpp | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 297067eb3..07c8f64d7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -219,12 +219,10 @@ add_cli_exe(modhelp modhelp.cpp) add_test(NAME modhelp COMMAND modhelp -a test -h) set_property(TEST modhelp PROPERTY PASS_REGULAR_EXPRESSION "Option -a string in help: test") -if(CMAKE_CXX_STANDARD GREATER 16) - add_cli_exe(array_option array_option.cpp) - add_test(NAME array_option COMMAND array_option --a 1 2) - set_property(TEST array_option PROPERTY PASS_REGULAR_EXPRESSION "pass") +add_cli_exe(array_option array_option.cpp) +add_test(NAME array_option COMMAND array_option --a 1 2) +set_property(TEST array_option PROPERTY PASS_REGULAR_EXPRESSION "pass") -endif() add_subdirectory(subcom_in_files) add_test(NAME subcom_in_files COMMAND subcommand_main subcommand_a -f this.txt --with-foo) set_property(TEST subcom_in_files PROPERTY PASS_REGULAR_EXPRESSION "Working on file: this\.txt" diff --git a/examples/array_option.cpp b/examples/array_option.cpp index 827a2638a..875cad3d5 100644 --- a/examples/array_option.cpp +++ b/examples/array_option.cpp @@ -4,7 +4,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -// Code modified from @gourin https://github.com/CLIUtils/CLI11/issues/1135 +// Code modified from Loic Gouarin(https://github.com/gouarin) https://github.com/CLIUtils/CLI11/issues/1135 #include #include From 246b7c9944148e2ee3e437e86b99ef0b2a812008 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Sun, 13 Apr 2025 06:39:14 -0700 Subject: [PATCH 7/8] resolve ambiguity for vector options --- tests/OptionTypeTest.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/OptionTypeTest.cpp b/tests/OptionTypeTest.cpp index d89a13576..babdb53a1 100644 --- a/tests/OptionTypeTest.cpp +++ b/tests/OptionTypeTest.cpp @@ -871,6 +871,23 @@ TEST_CASE_METHOD(TApp, "vectorPair", "[optiontype]") { CHECK_THROWS_AS(run(), CLI::ValidationError); } +// now with independent type sizes and expected this is possible +TEST_CASE_METHOD(TApp, "vectorArray", "[optiontype]") { + + std::vector> custom_opt; + + auto *opt = app.add_option("--set", custom_opt); + + args = {"--set", "1", "2","3", "--set", "3", "4" , "5"}; + + run(); + REQUIRE(2u == custom_opt.size()); + CHECK(1 == custom_opt[0][0]); + CHECK(4 == custom_opt[1][1]); + CHECK(opt->get_type_size()==3); + +} + TEST_CASE_METHOD(TApp, "vectorPairFail", "[optiontype]") { std::vector> custom_opt; From d68608d1fc446512845fccb92184675ffd35099b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 13 Apr 2025 13:51:56 +0000 Subject: [PATCH 8/8] style: pre-commit.ci fixes --- tests/OptionTypeTest.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/OptionTypeTest.cpp b/tests/OptionTypeTest.cpp index babdb53a1..219dbbd72 100644 --- a/tests/OptionTypeTest.cpp +++ b/tests/OptionTypeTest.cpp @@ -878,14 +878,13 @@ TEST_CASE_METHOD(TApp, "vectorArray", "[optiontype]") { auto *opt = app.add_option("--set", custom_opt); - args = {"--set", "1", "2","3", "--set", "3", "4" , "5"}; + args = {"--set", "1", "2", "3", "--set", "3", "4", "5"}; run(); REQUIRE(2u == custom_opt.size()); CHECK(1 == custom_opt[0][0]); CHECK(4 == custom_opt[1][1]); - CHECK(opt->get_type_size()==3); - + CHECK(opt->get_type_size() == 3); } TEST_CASE_METHOD(TApp, "vectorPairFail", "[optiontype]") {