mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 12:13:52 +00:00
add tests and fixes for array options (#1136)
Fixes #1135. Adds enable check to certain to_string functions as some std::array operations were ambiguous. The addition of the capability to convert tuples to strings created an ambiguity in the case std::array, which acts like a tuple and a container. So it worked with the container conversion before, but could also work with the new tuple conversion. And we didn't have any tests to catch this. This PR resolves the ambiguity, and adds some tests to check that array is handled well. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
8fa8a0fa0c
commit
f75fd22ba3
@ -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
|
||||
|
@ -219,6 +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")
|
||||
|
||||
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_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"
|
||||
|
21
examples/array_option.cpp
Normal file
21
examples/array_option.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 Loic Gouarin(https://github.com/gouarin) https://github.com/CLIUtils/CLI11/issues/1135
|
||||
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::array<int, 2> 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;
|
||||
}
|
@ -387,7 +387,7 @@ inline std::string to_string(T &&) {
|
||||
/// convert a readable container to a string
|
||||
template <typename T,
|
||||
enable_if_t<!std::is_convertible<T, std::string>::value && !std::is_constructible<std::string, T>::value &&
|
||||
!is_ostreamable<T>::value && is_readable_container<T>::value,
|
||||
!is_ostreamable<T>::value && is_readable_container<T>::value && !is_tuple_like<T>::value,
|
||||
detail::enabler> = detail::dummy>
|
||||
inline std::string to_string(T &&variable) {
|
||||
auto cval = variable.begin();
|
||||
@ -1497,7 +1497,7 @@ bool lexical_conversion(const std::vector<std ::string> &strings, AssignTo &outp
|
||||
using FirstType = typename std::remove_const<typename std::tuple_element<0, ConvertTo>::type>::type;
|
||||
using SecondType = typename std::tuple_element<1, ConvertTo>::type;
|
||||
FirstType v1;
|
||||
SecondType v2;
|
||||
SecondType v2{};
|
||||
bool retval = lexical_assign<FirstType, FirstType>(strings[0], v1);
|
||||
retval = retval && lexical_assign<SecondType, SecondType>((strings.size() > 1) ? strings[1] : std::string{}, v2);
|
||||
if(retval) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include <complex>
|
||||
@ -912,6 +913,50 @@ TEST_CASE_METHOD(TApp, "vectorPairTypeRange", "[optiontype]") {
|
||||
CHECK("str4" == custom_opt[2].second);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "ArrayTriple", "[optiontype]") {
|
||||
|
||||
using TY = std::array<int, 3>;
|
||||
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<!std::is_convertible<T, std::string>::value && !std::is_constructible<std::string, T>::value &&
|
||||
// !is_ostreamable<T>::value && is_tuple_like<T>::value && type_count_base<T>::value >= 2,
|
||||
// detail::enabler>>
|
||||
|
||||
CHECK(!std::is_convertible<TY, std::string>::value);
|
||||
CHECK(!std::is_constructible<std::string, TY>::value);
|
||||
CHECK(!CLI::detail::is_ostreamable<TY>::value);
|
||||
auto ts = std::tuple_size<typename std::decay<TY>::type>::value;
|
||||
CHECK(ts == 3);
|
||||
|
||||
auto vb = CLI::detail::type_count_base<TY>::value;
|
||||
CHECK(vb >= 2);
|
||||
CHECK(!CLI::detail::is_complex<TY>::value);
|
||||
CHECK(CLI::detail::is_tuple_like<TY>::value);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "ArrayPair", "[optiontype]") {
|
||||
|
||||
using TY = std::array<int, 2>;
|
||||
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]") {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user