mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 12:13:52 +00:00
Allow non standard option names like -option
(#1078)
This has been bounced around for a couple years now #474 and a few others have expressed desire to work with non-standard option names. We have been somewhat resistant to that but I think it can be done now. This PR adds a modifier `allow_non_standard_option_names()` It is purposely long, it is purposely off by default. But what it does is allow option names with a single `-` to act like a short option name. With this modifier enabled no single letter short option names are allowed to start with the same letter as a non-standard names. For example `-s` and `-single` would not be allowed. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
This commit is contained in:
parent
7bc90c7eb3
commit
5a03ee5838
@ -3,6 +3,7 @@ linelength=120 # As in .clang-format
|
||||
|
||||
# Unused filters
|
||||
filter=-build/c++11 # Reports e.g. chrono and thread, which overlap with Chromium's API. Not applicable to general C++ projects.
|
||||
filter=-build/c++17 # google only restrictions not relevant
|
||||
filter=-build/include_order # Requires unusual include order that encourages creating not self-contained headers
|
||||
filter=-build/include_subdir # Prevents including files in current directory for whatever reason
|
||||
filter=-readability/nolint # Conflicts with clang-tidy
|
||||
@ -13,3 +14,4 @@ filter=-runtime/string # Requires not using static const strings which makes th
|
||||
filter=-whitespace/blank_line # Unnecessarily strict with blank lines that otherwise help with readability
|
||||
filter=-whitespace/indent # Requires strange 3-space indent of private/protected/public markers
|
||||
filter=-whitespace/parens,-whitespace/braces # Conflict with clang-format
|
||||
filter=-whitespace/newline # handled by clang-format
|
||||
|
10
README.md
10
README.md
@ -158,8 +158,6 @@ installation fuss.
|
||||
There are some other possible "features" that are intentionally not supported by
|
||||
this library:
|
||||
|
||||
- Non-standard variations on syntax, like `-long` options. This is non-standard
|
||||
and should be avoided, so that is enforced by this library.
|
||||
- Completion of partial options, such as Python's `argparse` supplies for
|
||||
incomplete arguments. It's better not to guess. Most third party command line
|
||||
parsers for python actually reimplement command line parsing rather than using
|
||||
@ -904,6 +902,14 @@ option_groups. These are:
|
||||
the form of `/s /long /file:file_name.ext` This option does not change how
|
||||
options are specified in the `add_option` calls or the ability to process
|
||||
options in the form of `-s --long --file=file_name.ext`.
|
||||
- `.allow_non_standard_option_names()`:🚧 Allow specification of single `-` long
|
||||
form option names. This is not recommended but is available to enable
|
||||
reworking of existing interfaces. If this modifier is enabled on an app or
|
||||
subcommand, options or flags can be specified like normal but instead of
|
||||
throwing an exception, long form single dash option names will be allowed. It
|
||||
is not allowed to have a single character short option starting with the same
|
||||
character as a single dash long form name; for example, `-s` and `-single` are
|
||||
not allowed in the same application.
|
||||
- `.fallthrough()`: Allow extra unmatched options and positionals to "fall
|
||||
through" and be matched on a parent option. Subcommands by default are allowed
|
||||
to "fall through" as in they will first attempt to match on the current
|
||||
|
@ -22,7 +22,7 @@ jobs:
|
||||
- job: CppLint
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
container: sharaku/cpplint:latest
|
||||
container: helics/buildenv:cpplint
|
||||
steps:
|
||||
- bash: cpplint --counting=detailed --recursive examples include/CLI tests
|
||||
displayName: Checking against google style guide
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// example file to demonstrate a custom lexical cast function
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class MyFormatter : public CLI::Formatter {
|
||||
public:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
|
@ -260,6 +260,9 @@ class App {
|
||||
/// This is potentially useful as a modifier subcommand
|
||||
bool silent_{false};
|
||||
|
||||
/// indicator that the subcommand should allow non-standard option arguments, such as -single_dash_flag
|
||||
bool allow_non_standard_options_{false};
|
||||
|
||||
/// Counts the number of times this command/subcommand was parsed
|
||||
std::uint32_t parsed_{0U};
|
||||
|
||||
@ -392,6 +395,12 @@ class App {
|
||||
return this;
|
||||
}
|
||||
|
||||
/// allow non standard option names
|
||||
App *allow_non_standard_option_names(bool allowed = true) {
|
||||
allow_non_standard_options_ = allowed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// Set the subcommand to be disabled by default, so on clear(), at the start of each parse it is disabled
|
||||
App *disabled_by_default(bool disable = true) {
|
||||
if(disable) {
|
||||
@ -1146,6 +1155,9 @@ class App {
|
||||
/// Get the status of silence
|
||||
CLI11_NODISCARD bool get_silent() const { return silent_; }
|
||||
|
||||
/// Get the status of silence
|
||||
CLI11_NODISCARD bool get_allow_non_standard_option_names() const { return allow_non_standard_options_; }
|
||||
|
||||
/// Get the status of disabled
|
||||
CLI11_NODISCARD bool get_immediate_callback() const { return immediate_callback_; }
|
||||
|
||||
|
@ -341,9 +341,13 @@ class Option : public OptionBase<Option> {
|
||||
///@}
|
||||
|
||||
/// Making an option by hand is not defined, it must be made by the App class
|
||||
Option(std::string option_name, std::string option_description, callback_t callback, App *parent)
|
||||
Option(std::string option_name,
|
||||
std::string option_description,
|
||||
callback_t callback,
|
||||
App *parent,
|
||||
bool allow_non_standard = false)
|
||||
: description_(std::move(option_description)), parent_(parent), callback_(std::move(callback)) {
|
||||
std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(option_name));
|
||||
std::tie(snames_, lnames_, pname_) = detail::get_names(detail::split_names(option_name), allow_non_standard);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -39,7 +39,7 @@ CLI11_INLINE std::vector<std::pair<std::string, std::string>> get_default_flag_v
|
||||
|
||||
/// Get a vector of short names, one of long names, and a single name
|
||||
CLI11_INLINE std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
|
||||
get_names(const std::vector<std::string> &input);
|
||||
get_names(const std::vector<std::string> &input, bool allow_non_standard = false);
|
||||
|
||||
} // namespace detail
|
||||
// [CLI11:split_hpp:end]
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
// [CLI11:public_includes:set]
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@ -161,7 +162,7 @@ CLI11_INLINE Option *App::add_option(std::string option_name,
|
||||
std::string option_description,
|
||||
bool defaulted,
|
||||
std::function<std::string()> func) {
|
||||
Option myopt{option_name, option_description, option_callback, this};
|
||||
Option myopt{option_name, option_description, option_callback, this, allow_non_standard_options_};
|
||||
|
||||
if(std::find_if(std::begin(options_), std::end(options_), [&myopt](const Option_p &v) { return *v == myopt; }) ==
|
||||
std::end(options_)) {
|
||||
@ -191,9 +192,34 @@ CLI11_INLINE Option *App::add_option(std::string option_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
if(allow_non_standard_options_ && !myopt.snames_.empty()) {
|
||||
for(auto &sname : myopt.snames_) {
|
||||
if(sname.length() > 1) {
|
||||
std::string test_name;
|
||||
test_name.push_back('-');
|
||||
test_name.push_back(sname.front());
|
||||
auto *op = get_option_no_throw(test_name);
|
||||
if(op != nullptr) {
|
||||
throw(OptionAlreadyAdded("added option interferes with existing short option: " + sname));
|
||||
}
|
||||
}
|
||||
}
|
||||
for(auto &opt : options_) {
|
||||
for(const auto &osn : opt->snames_) {
|
||||
if(osn.size() > 1) {
|
||||
std::string test_name;
|
||||
test_name.push_back(osn.front());
|
||||
if(myopt.check_sname(test_name)) {
|
||||
throw(OptionAlreadyAdded("added option interferes with existing non standard option: " +
|
||||
osn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
options_.emplace_back();
|
||||
Option_p &option = options_.back();
|
||||
option.reset(new Option(option_name, option_description, option_callback, this));
|
||||
option.reset(new Option(option_name, option_description, option_callback, this, allow_non_standard_options_));
|
||||
|
||||
// Set the default string capture function
|
||||
option->default_function(func);
|
||||
@ -1888,7 +1914,8 @@ App::_parse_arg(std::vector<std::string> &args, detail::Classifier current_type,
|
||||
});
|
||||
|
||||
// Option not found
|
||||
if(op_ptr == std::end(options_)) {
|
||||
while(op_ptr == std::end(options_)) {
|
||||
// using while so we can break
|
||||
for(auto &subc : subcommands_) {
|
||||
if(subc->name_.empty() && !subc->disabled_) {
|
||||
if(subc->_parse_arg(args, current_type, local_processing_only)) {
|
||||
@ -1899,6 +1926,20 @@ App::_parse_arg(std::vector<std::string> &args, detail::Classifier current_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
if(allow_non_standard_options_ && current_type == detail::Classifier::SHORT && current.size() > 2) {
|
||||
std::string narg_name;
|
||||
std::string nvalue;
|
||||
detail::split_long(std::string{'-'} + current, narg_name, nvalue);
|
||||
op_ptr = std::find_if(std::begin(options_), std::end(options_), [narg_name](const Option_p &opt) {
|
||||
return opt->check_sname(narg_name);
|
||||
});
|
||||
if(op_ptr != std::end(options_)) {
|
||||
arg_name = narg_name;
|
||||
value = nvalue;
|
||||
rest.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// don't capture missing if this is a nameless subcommand and nameless subcommands can't fallthrough
|
||||
if(parent_ != nullptr && name_.empty()) {
|
||||
|
@ -103,7 +103,7 @@ CLI11_INLINE std::vector<std::pair<std::string, std::string>> get_default_flag_v
|
||||
}
|
||||
|
||||
CLI11_INLINE std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
|
||||
get_names(const std::vector<std::string> &input) {
|
||||
get_names(const std::vector<std::string> &input, bool allow_non_standard) {
|
||||
|
||||
std::vector<std::string> short_names;
|
||||
std::vector<std::string> long_names;
|
||||
@ -113,23 +113,35 @@ get_names(const std::vector<std::string> &input) {
|
||||
continue;
|
||||
}
|
||||
if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
|
||||
if(name.length() == 2 && valid_first_char(name[1]))
|
||||
if(name.length() == 2 && valid_first_char(name[1])) {
|
||||
short_names.emplace_back(1, name[1]);
|
||||
else if(name.length() > 2)
|
||||
} else if(name.length() > 2) {
|
||||
if(allow_non_standard) {
|
||||
name = name.substr(1);
|
||||
if(valid_name_string(name)) {
|
||||
short_names.push_back(name);
|
||||
} else {
|
||||
throw BadNameString::BadLongName(name);
|
||||
}
|
||||
} else {
|
||||
throw BadNameString::MissingDash(name);
|
||||
else
|
||||
}
|
||||
} else {
|
||||
throw BadNameString::OneCharName(name);
|
||||
}
|
||||
} else if(name.length() > 2 && name.substr(0, 2) == "--") {
|
||||
name = name.substr(2);
|
||||
if(valid_name_string(name))
|
||||
if(valid_name_string(name)) {
|
||||
long_names.push_back(name);
|
||||
else
|
||||
} else {
|
||||
throw BadNameString::BadLongName(name);
|
||||
}
|
||||
} else if(name == "-" || name == "--" || name == "++") {
|
||||
throw BadNameString::ReservedName(name);
|
||||
} else {
|
||||
if(!pos_name.empty())
|
||||
if(!pos_name.empty()) {
|
||||
throw BadNameString::MultiPositionalNames(name);
|
||||
}
|
||||
if(valid_name_string(name)) {
|
||||
pos_name = name;
|
||||
} else {
|
||||
|
@ -13,6 +13,9 @@
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE_METHOD(TApp, "OneFlagShort", "[app]") {
|
||||
app.add_flag("-c,--count");
|
||||
@ -663,6 +666,15 @@ TEST_CASE_METHOD(TApp, "singledash", "[app]") {
|
||||
} catch(...) {
|
||||
CHECK(false);
|
||||
}
|
||||
app.allow_non_standard_option_names();
|
||||
try {
|
||||
app.add_option("-!I{am}bad");
|
||||
} catch(const CLI::BadNameString &e) {
|
||||
std::string str = e.what();
|
||||
CHECK_THAT(str, Contains("!I{am}bad"));
|
||||
} catch(...) {
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "FlagLikeOption", "[app]") {
|
||||
@ -2389,6 +2401,45 @@ TEST_CASE_METHOD(TApp, "OrderedModifyingTransforms", "[app]") {
|
||||
CHECK(std::vector<std::string>({"one21", "two21"}) == val);
|
||||
}
|
||||
|
||||
// non standard options
|
||||
TEST_CASE_METHOD(TApp, "nonStandardOptions", "[app]") {
|
||||
std::string string1;
|
||||
CHECK_THROWS_AS(app.add_option("-single", string1), CLI::BadNameString);
|
||||
app.allow_non_standard_option_names();
|
||||
CHECK(app.get_allow_non_standard_option_names());
|
||||
app.add_option("-single", string1);
|
||||
args = {"-single", "string1"};
|
||||
|
||||
run();
|
||||
|
||||
CHECK(string1 == "string1");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "nonStandardOptions2", "[app]") {
|
||||
std::vector<std::string> strings;
|
||||
app.allow_non_standard_option_names();
|
||||
app.add_option("-single,--single,-m", strings);
|
||||
args = {"-single", "string1", "--single", "string2"};
|
||||
|
||||
run();
|
||||
|
||||
CHECK(strings == std::vector<std::string>{"string1", "string2"});
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "nonStandardOptionsIntersect", "[app]") {
|
||||
std::vector<std::string> strings;
|
||||
app.allow_non_standard_option_names();
|
||||
app.add_option("-s,-t");
|
||||
CHECK_THROWS_AS(app.add_option("-single,--single", strings), CLI::OptionAlreadyAdded);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "nonStandardOptionsIntersect2", "[app]") {
|
||||
std::vector<std::string> strings;
|
||||
app.allow_non_standard_option_names();
|
||||
app.add_option("-single,--single", strings);
|
||||
CHECK_THROWS_AS(app.add_option("-s,-t"), CLI::OptionAlreadyAdded);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "ThrowingTransform", "[app]") {
|
||||
std::string val;
|
||||
auto *m = app.add_option("-m,--mess", val);
|
||||
|
@ -13,17 +13,17 @@
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include <boost/container/vector.hpp>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace boost::container;
|
||||
|
||||
TEMPLATE_TEST_CASE("Boost container single",
|
||||
"[boost][optional]",
|
||||
(small_vector<int, 2>),
|
||||
(small_vector<int, 3>),
|
||||
flat_set<int>,
|
||||
stable_vector<int>,
|
||||
slist<int>) {
|
||||
(boost::container::small_vector<int, 2>),
|
||||
(boost::container::small_vector<int, 3>),
|
||||
boost::container::flat_set<int>,
|
||||
boost::container::stable_vector<int>,
|
||||
boost::container::slist<int>) {
|
||||
TApp tapp;
|
||||
TestType cv;
|
||||
CLI::Option *opt = tapp.app.add_option("-v", cv);
|
||||
@ -45,12 +45,12 @@ using isp = std::pair<int, std::string>;
|
||||
|
||||
TEMPLATE_TEST_CASE("Boost container pair",
|
||||
"[boost][optional]",
|
||||
stable_vector<isp>,
|
||||
(small_vector<isp, 2>),
|
||||
flat_set<isp>,
|
||||
slist<isp>,
|
||||
vector<isp>,
|
||||
(flat_map<int, std::string>)) {
|
||||
boost::container::stable_vector<isp>,
|
||||
(boost::container::small_vector<isp, 2>),
|
||||
boost::container::flat_set<isp>,
|
||||
boost::container::slist<isp>,
|
||||
boost::container::vector<isp>,
|
||||
(boost::container::flat_map<int, std::string>)) {
|
||||
|
||||
TApp tapp;
|
||||
TestType cv;
|
||||
@ -71,10 +71,10 @@ using tup_obj = std::tuple<int, std::string, double>;
|
||||
|
||||
TEMPLATE_TEST_CASE("Boost container tuple",
|
||||
"[boost][optional]",
|
||||
(small_vector<tup_obj, 3>),
|
||||
stable_vector<tup_obj>,
|
||||
flat_set<tup_obj>,
|
||||
slist<tup_obj>) {
|
||||
(boost::container::small_vector<tup_obj, 3>),
|
||||
boost::container::stable_vector<tup_obj>,
|
||||
boost::container::flat_set<tup_obj>,
|
||||
boost::container::slist<tup_obj>) {
|
||||
TApp tapp;
|
||||
TestType cv;
|
||||
|
||||
@ -90,24 +90,24 @@ TEMPLATE_TEST_CASE("Boost container tuple",
|
||||
CHECK(3u == cv.size());
|
||||
}
|
||||
|
||||
using icontainer1 = vector<int>;
|
||||
using icontainer2 = flat_set<int>;
|
||||
using icontainer3 = slist<int>;
|
||||
using icontainer1 = boost::container::vector<int>;
|
||||
using icontainer2 = boost::container::flat_set<int>;
|
||||
using icontainer3 = boost::container::slist<int>;
|
||||
|
||||
TEMPLATE_TEST_CASE("Boost container container",
|
||||
"[boost][optional]",
|
||||
std::vector<icontainer1>,
|
||||
slist<icontainer1>,
|
||||
flat_set<icontainer1>,
|
||||
(small_vector<icontainer1, 2>),
|
||||
boost::container::slist<icontainer1>,
|
||||
boost::container::flat_set<icontainer1>,
|
||||
(boost::container::small_vector<icontainer1, 2>),
|
||||
std::vector<icontainer2>,
|
||||
slist<icontainer2>,
|
||||
flat_set<icontainer2>,
|
||||
stable_vector<icontainer2>,
|
||||
(static_vector<icontainer2, 10>),
|
||||
slist<icontainer3>,
|
||||
flat_set<icontainer3>,
|
||||
(static_vector<icontainer3, 10>)) {
|
||||
boost::container::slist<icontainer2>,
|
||||
boost::container::flat_set<icontainer2>,
|
||||
boost::container::stable_vector<icontainer2>,
|
||||
(boost::container::static_vector<icontainer2, 10>),
|
||||
boost::container::slist<icontainer3>,
|
||||
boost::container::flat_set<icontainer3>,
|
||||
(boost::container::static_vector<icontainer3, 10>)) {
|
||||
|
||||
TApp tapp;
|
||||
TestType cv;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <complex>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
using cx = std::complex<double>;
|
||||
|
||||
|
@ -7,7 +7,12 @@
|
||||
#include "app_helper.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE("StringBased: convert_arg_for_ini", "[config]") {
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "app_helper.hpp"
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE_METHOD(TApp, "AddingExistingShort", "[creation]") {
|
||||
CLI::Option *opt = app.add_flag("-c,--count");
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class SimpleFormatter : public CLI::FormatterBase {
|
||||
public:
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "../fuzz/fuzzApp.hpp"
|
||||
#include "app_helper.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::string loadFailureFile(const std::string &type, int index) {
|
||||
std::string fileName(TEST_FILE_FOLDER "/fuzzFail/");
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
TEST_CASE("THelp: Basic", "[help]") {
|
||||
CLI::App app{"My prog"};
|
||||
@ -286,6 +290,20 @@ TEST_CASE("THelp: OptionalPositionalAndOptions", "[help]") {
|
||||
CHECK_THAT(help, Contains("AnotherProgram [OPTIONS] [something]"));
|
||||
}
|
||||
|
||||
TEST_CASE("THelp: NonStandardOptions", "[help]") {
|
||||
CLI::App app{"My prog", "nonstandard"};
|
||||
app.allow_non_standard_option_names();
|
||||
app.add_flag("-q,--quick");
|
||||
app.add_flag("-slow");
|
||||
app.add_option("--fast,-not-slow", "a description of what is");
|
||||
std::string x;
|
||||
app.add_option("something", x, "My option here");
|
||||
|
||||
std::string help = app.help();
|
||||
|
||||
CHECK_THAT(help, Contains("-not-slow"));
|
||||
}
|
||||
|
||||
TEST_CASE("THelp: RequiredPositionalAndOptions", "[help]") {
|
||||
CLI::App app{"My prog"};
|
||||
app.add_flag("-q,--quick");
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class NotStreamable {};
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
#include <complex>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using cx = std::complex<double>;
|
||||
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
#include "app_helper.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using vs_t = std::vector<std::string>;
|
||||
|
||||
TEST_CASE_METHOD(TApp, "BasicOptionGroup", "[optiongroup]") {
|
||||
|
@ -16,10 +16,13 @@
|
||||
#include <cstdlib>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "app_helper.hpp"
|
||||
|
||||
|
@ -7,6 +7,10 @@
|
||||
#include "app_helper.hpp"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
static_assert(CLI::is_shared_ptr<std::shared_ptr<int>>::value == true, "is_shared_ptr should work on shared pointers");
|
||||
static_assert(CLI::is_shared_ptr<int *>::value == false, "is_shared_ptr should work on pointers");
|
||||
|
@ -11,6 +11,8 @@
|
||||
#endif
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using input_t = std::vector<std::string>;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE_METHOD(TApp, "ExistingExeCheck", "[stringparse]") {
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include "app_helper.hpp"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using vs_t = std::vector<std::string>;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "catch.hpp"
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
@ -11,7 +11,12 @@
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(CLI11_CPP17)
|
||||
#if defined(__has_include)
|
||||
@ -78,7 +83,7 @@ TEST_CASE_METHOD(TApp, "EnumTransform", "[transform]") {
|
||||
// transformer doesn't do any checking so this still works
|
||||
args = {"-s", "5"};
|
||||
run();
|
||||
CHECK(std::int16_t(5) == static_cast<std::int16_t>(value));
|
||||
CHECK(static_cast<std::int16_t>(5) == static_cast<std::int16_t>(value));
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(TApp, "EnumCheckedTransform", "[transform]") {
|
||||
|
@ -5,6 +5,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include "app_helper.hpp"
|
||||
#include <string>
|
||||
|
||||
TEST_CASE_METHOD(TApp, "True Bool Option", "[bool][flag]") {
|
||||
// Strings needed here due to MSVC 2015.
|
||||
|
@ -5,6 +5,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include <CLI/CLI.hpp>
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
CLI::App app{"App description"};
|
||||
|
Loading…
x
Reference in New Issue
Block a user