summaryrefslogtreecommitdiff
path: root/thirdparty
diff options
context:
space:
mode:
authorDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2024-12-06 20:01:39 +0200
committerDirk-Jan C. Binnema <djcb@djcbsoftware.nl>2024-12-06 20:01:39 +0200
commit6166b435d2bfa4e8c12bcf78a44d7bdc7baa90cb (patch)
tree771a75bef7189e6f2fca04ff767becbb24095855 /thirdparty
parent49606a76abc353a5baafac2d7559d8b9919ed4a9 (diff)
thirdparty/cli11: bump to v2.4.2
Diffstat (limited to 'thirdparty')
-rw-r--r--thirdparty/CLI11.hpp104
1 files changed, 68 insertions, 36 deletions
diff --git a/thirdparty/CLI11.hpp b/thirdparty/CLI11.hpp
index 41027f0..8a5b4c5 100644
--- a/thirdparty/CLI11.hpp
+++ b/thirdparty/CLI11.hpp
@@ -1,11 +1,11 @@
-// CLI11: Version 2.4.1
+// CLI11: Version 2.4.2
// Originally designed by Henry Schreiner
// https://github.com/CLIUtils/CLI11
//
// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts
-// from: v2.4.1
+// from: v2.4.2
//
-// CLI11 2.4.1 Copyright (c) 2017-2024 University of Cincinnati, developed by Henry
+// CLI11 2.4.2 Copyright (c) 2017-2024 University of Cincinnati, developed by Henry
// Schreiner under NSF AWARD 1414736. All rights reserved.
//
// Redistribution and use in source and binary forms of CLI11, with or without
@@ -66,8 +66,8 @@
#define CLI11_VERSION_MAJOR 2
#define CLI11_VERSION_MINOR 4
-#define CLI11_VERSION_PATCH 1
-#define CLI11_VERSION "2.4.1"
+#define CLI11_VERSION_PATCH 2
+#define CLI11_VERSION "2.4.2"
@@ -1451,22 +1451,22 @@ class RequiredError : public ParseError {
if((min_option == 1) && (max_option == 1) && (used == 0))
return RequiredError("Exactly 1 option from [" + option_list + "]");
if((min_option == 1) && (max_option == 1) && (used > 1)) {
- return {"Exactly 1 option from [" + option_list + "] is required and " + std::to_string(used) +
+ return {"Exactly 1 option from [" + option_list + "] is required but " + std::to_string(used) +
" were given",
ExitCodes::RequiredError};
}
if((min_option == 1) && (used == 0))
return RequiredError("At least 1 option from [" + option_list + "]");
if(used < min_option) {
- return {"Requires at least " + std::to_string(min_option) + " options used and only " +
- std::to_string(used) + "were given from [" + option_list + "]",
+ return {"Requires at least " + std::to_string(min_option) + " options used but only " +
+ std::to_string(used) + " were given from [" + option_list + "]",
ExitCodes::RequiredError};
}
if(max_option == 1)
return {"Requires at most 1 options be given from [" + option_list + "]", ExitCodes::RequiredError};
- return {"Requires at most " + std::to_string(max_option) + " options be used and " + std::to_string(used) +
- "were given from [" + option_list + "]",
+ return {"Requires at most " + std::to_string(max_option) + " options be used but " + std::to_string(used) +
+ " were given from [" + option_list + "]",
ExitCodes::RequiredError};
}
};
@@ -1633,6 +1633,23 @@ template <> struct IsMemberType<const char *> {
using type = std::string;
};
+namespace adl_detail {
+/// Check for existence of user-supplied lexical_cast.
+///
+/// This struct has to be in a separate namespace so that it doesn't see our lexical_cast overloads in CLI::detail.
+/// Standard says it shouldn't see them if it's defined before the corresponding lexical_cast declarations, but this
+/// requires a working implementation of two-phase lookup, and not all compilers can boast that (msvc, ahem).
+template <typename T, typename S = std::string> class is_lexical_castable {
+ template <typename TT, typename SS>
+ static auto test(int) -> decltype(lexical_cast(std::declval<const SS &>(), std::declval<TT &>()), std::true_type());
+
+ template <typename, typename> static auto test(...) -> std::false_type;
+
+ public:
+ static constexpr bool value = decltype(test<T, S>(0))::value;
+};
+} // namespace adl_detail
+
namespace detail {
// These are utilities for IsMember and other transforming objects
@@ -1714,7 +1731,7 @@ template <typename T, typename C> class is_direct_constructible {
#pragma diag_suppress 2361
#endif
#endif
- TT{std::declval<CC>()}
+ TT{std::declval<CC>()}
#ifdef __CUDACC__
#ifdef __NVCC_DIAG_PRAGMA_SUPPORT__
#pragma nv_diag_default 2361
@@ -1722,8 +1739,8 @@ template <typename T, typename C> class is_direct_constructible {
#pragma diag_default 2361
#endif
#endif
- ,
- std::is_move_assignable<TT>());
+ ,
+ std::is_move_assignable<TT>());
template <typename TT, typename CC> static auto test(int, std::false_type) -> std::false_type;
@@ -2793,13 +2810,24 @@ bool lexical_cast(const std::string &input, T &output) {
/// Non-string parsable by a stream
template <typename T,
- enable_if_t<classify_object<T>::value == object_category::other && !std::is_assignable<T &, int>::value,
+ enable_if_t<classify_object<T>::value == object_category::other && !std::is_assignable<T &, int>::value &&
+ is_istreamable<T>::value,
detail::enabler> = detail::dummy>
bool lexical_cast(const std::string &input, T &output) {
- static_assert(is_istreamable<T>::value,
+ return from_stream(input, output);
+}
+
+/// Fallback overload that prints a human-readable error for types that we don't recognize and that don't have a
+/// user-supplied lexical_cast overload.
+template <typename T,
+ enable_if_t<classify_object<T>::value == object_category::other && !std::is_assignable<T &, int>::value &&
+ !is_istreamable<T>::value && !adl_detail::is_lexical_castable<T>::value,
+ detail::enabler> = detail::dummy>
+bool lexical_cast(const std::string & /*input*/, T & /*output*/) {
+ static_assert(!std::is_same<T, T>::value, // Can't just write false here.
"option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
"is convertible from another type use the add_option<T, XC>(...) with XC being the known type");
- return from_stream(input, output);
+ return false;
}
/// Assign a value through lexical cast operations
@@ -7097,6 +7125,10 @@ class App {
/// Check to see if a subcommand is part of this command (text version)
CLI11_NODISCARD App *get_subcommand(std::string subcom) const;
+ /// Get a subcommand by name (noexcept non-const version)
+ /// returns null if subcommand doesn't exist
+ CLI11_NODISCARD App *get_subcommand_no_throw(std::string subcom) const noexcept;
+
/// Get a pointer to subcommand by index
CLI11_NODISCARD App *get_subcommand(int index = 0) const;
@@ -7271,8 +7303,9 @@ class App {
}
/// Check with name instead of pointer to see if subcommand was selected
- CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const {
- return get_subcommand(subcommand_name)->parsed_ > 0;
+ CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const noexcept {
+ App *sub = get_subcommand_no_throw(subcommand_name);
+ return (sub != nullptr) ? (sub->parsed_ > 0) : false;
}
/// Sets excluded options for the subcommand
@@ -7402,7 +7435,7 @@ class App {
std::vector<Option *> get_options(const std::function<bool(Option *)> filter = {});
/// Get an option by name (noexcept non-const version)
- Option *get_option_no_throw(std::string option_name) noexcept;
+ CLI11_NODISCARD Option *get_option_no_throw(std::string option_name) noexcept;
/// Get an option by name (noexcept const version)
CLI11_NODISCARD const Option *get_option_no_throw(std::string option_name) const noexcept;
@@ -8056,8 +8089,8 @@ App::set_version_flag(std::string flag_name, std::function<std::string()> vfunc,
// Empty name will simply remove the version flag
if(!flag_name.empty()) {
- version_ptr_ = add_flag_callback(
- flag_name, [vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); }, version_help);
+ version_ptr_ =
+ add_flag_callback(flag_name, [vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); }, version_help);
version_ptr_->configurable(false);
}
@@ -8234,6 +8267,10 @@ CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand(std::string subcom) const
return subc;
}
+CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand_no_throw(std::string subcom) const noexcept {
+ return _find_subcommand(subcom, false, false);
+}
+
CLI11_NODISCARD CLI11_INLINE App *App::get_subcommand(int index) const {
if(index >= 0) {
auto uindex = static_cast<unsigned>(index);
@@ -8573,7 +8610,7 @@ CLI11_INLINE std::vector<Option *> App::get_options(const std::function<bool(Opt
return options;
}
-CLI11_INLINE Option *App::get_option_no_throw(std::string option_name) noexcept {
+CLI11_NODISCARD CLI11_INLINE Option *App::get_option_no_throw(std::string option_name) noexcept {
for(Option_p &opt : options_) {
if(opt->check_name(option_name)) {
return opt.get();
@@ -8913,11 +8950,9 @@ CLI11_INLINE void App::_process_env() {
}
for(App_p &sub : subcommands_) {
- if(sub->get_name().empty() || !sub->parse_complete_callback_) {
- if(sub->count_all() > 0) {
- // only process environment variables if the callback has actually been triggered already
- sub->_process_env();
- }
+ if(sub->get_name().empty() || (sub->count_all() > 0 && !sub->parse_complete_callback_)) {
+ // only process environment variables if the callback has actually been triggered already
+ sub->_process_env();
}
}
}
@@ -9220,12 +9255,8 @@ CLI11_INLINE void App::_parse_config(const std::vector<ConfigItem> &args) {
CLI11_INLINE bool App::_parse_single_config(const ConfigItem &item, std::size_t level) {
if(level < item.parents.size()) {
- try {
- auto *subcom = get_subcommand(item.parents.at(level));
- return subcom->_parse_single_config(item, level + 1);
- } catch(const OptionNotFound &) {
- return false;
- }
+ auto *subcom = get_subcommand_no_throw(item.parents.at(level));
+ return (subcom != nullptr) ? subcom->_parse_single_config(item, level + 1) : false;
}
// check for section open
if(item.name == "++") {
@@ -9259,11 +9290,12 @@ CLI11_INLINE bool App::_parse_single_config(const ConfigItem &item, std::size_t
if(op == nullptr) {
// If the option was not present
- if(get_allow_config_extras() == config_extras_mode::capture)
+ if(get_allow_config_extras() == config_extras_mode::capture) {
// Should we worry about classifying the extras properly?
missing_.emplace_back(detail::Classifier::NONE, item.fullname());
- for(const auto &input : item.inputs) {
- missing_.emplace_back(detail::Classifier::NONE, input);
+ for(const auto &input : item.inputs) {
+ missing_.emplace_back(detail::Classifier::NONE, input);
+ }
}
return false;
}