38 #error This file should only be included once in any given source (.cpp) file.
58 #include <type_traits>
73 #error This file cannot be included alongside a different CLI11 header.
76 #define CLI11_VERSION_MAJOR 2
77 #define CLI11_VERSION_MINOR 3
78 #define CLI11_VERSION_PATCH 1
79 #define CLI11_VERSION "2.3.1"
85 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER)
86 #if __cplusplus >= 201402L
88 #if __cplusplus >= 201703L
90 #if __cplusplus > 201703L
95 #elif defined(_MSC_VER) && __cplusplus == 199711L
98 #if _MSVC_LANG >= 201402L
100 #if _MSVC_LANG > 201402L && _MSC_VER >= 1910
102 #if _MSVC_LANG > 201703L && _MSC_VER >= 1910
109 #if defined(CLI11_CPP14)
110 #define CLI11_DEPRECATED(reason) [[deprecated(reason)]]
111 #elif defined(_MSC_VER)
112 #define CLI11_DEPRECATED(reason) __declspec(deprecated(reason))
114 #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason)))
118 #if !defined(CLI11_CPP17) || \
119 (defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER) && __GNUC__ < 10 && __GNUC__ > 4)
120 #define CLI11_NODISCARD
122 #define CLI11_NODISCARD [[nodiscard]]
126 #ifndef CLI11_USE_STATIC_RTTI
127 #if(defined(_HAS_STATIC_RTTI) && _HAS_STATIC_RTTI)
128 #define CLI11_USE_STATIC_RTTI 1
129 #elif defined(__cpp_rtti)
130 #if(defined(_CPPRTTI) && _CPPRTTI == 0)
131 #define CLI11_USE_STATIC_RTTI 1
133 #define CLI11_USE_STATIC_RTTI 0
135 #elif(defined(__GCC_RTTI) && __GXX_RTTI)
136 #define CLI11_USE_STATIC_RTTI 0
138 #define CLI11_USE_STATIC_RTTI 1
146 #define CLI11_INLINE inline
153 #if defined CLI11_CPP17 && defined __has_include && !defined CLI11_HAS_FILESYSTEM
154 #if __has_include(<filesystem>)
156 #if defined __MAC_OS_X_VERSION_MIN_REQUIRED && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
157 #define CLI11_HAS_FILESYSTEM 0
158 #elif defined(__wasi__)
160 #define CLI11_HAS_FILESYSTEM 0
162 #include <filesystem>
163 #if defined __cpp_lib_filesystem && __cpp_lib_filesystem >= 201703
164 #if defined _GLIBCXX_RELEASE && _GLIBCXX_RELEASE >= 9
165 #define CLI11_HAS_FILESYSTEM 1
166 #elif defined(__GLIBCXX__)
168 #define CLI11_HAS_FILESYSTEM 0
170 #define CLI11_HAS_FILESYSTEM 1
173 #define CLI11_HAS_FILESYSTEM 0
179 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
180 #include <filesystem>
182 #include <sys/stat.h>
183 #include <sys/types.h>
211 using enums::operator<<;
223 std::ostringstream
s;
229 s << delim << *beg++;
235 template <
typename T,
239 std::ostringstream
s;
242 auto loc = s.tellp();
244 auto nloc = s.tellp();
256 std::ostringstream
s;
260 s << v[v.size() -
start - 1];
303 return trim(s, filter);
314 template <
typename T>
bool valid_first_char(T
c) {
return ((c !=
'-') && (c !=
'!') && (c !=
' ') && c !=
'\n'); }
321 return ((c !=
'=') && (c !=
':') && (c !=
'{') && (c !=
' ') && c !=
'\n');
330 return (str.find_first_of(badChars) == std::string::npos);
336 return (str.empty() || str == sep);
341 return std::all_of(str.begin(), str.end(), [](
char c) {
return std::isalpha(
c, std::locale()); });
347 return std::tolower(x, std::locale());
363 return (flags.find_first_of(
"{!") != std::string::npos);
370 const std::vector<std::string> names,
377 std::size_t start_pos = 0;
378 while((start_pos = str.find(trigger, start_pos)) != std::string::npos) {
379 start_pos = modify(str, start_pos);
404 std::vector<std::string> elems;
407 elems.emplace_back();
409 std::stringstream ss;
412 while(std::getline(ss, item, delim)) {
413 elems.push_back(item);
420 auto it = std::find_if(str.begin(), str.end(), [](
char ch) {
return !std::isspace<char>(ch, std::locale()); });
421 str.erase(str.begin(), it);
426 auto it = std::find_if(str.begin(), str.end(), [&
filter](
char ch) {
return filter.find(ch) == std::string::npos; });
427 str.erase(str.begin(), it);
432 auto it = std::find_if(str.rbegin(), str.rend(), [](
char ch) {
return !std::isspace<char>(ch, std::locale()); });
433 str.erase(it.base(), str.end());
439 std::find_if(str.rbegin(), str.rend(), [&
filter](
char ch) {
return filter.find(ch) == std::string::npos; });
440 str.erase(it.base(), str.end());
445 if(str.length() > 1 && (str.front() ==
'"' || str.front() ==
'\'')) {
446 if(str.front() == str.back()) {
448 str.erase(str.begin(), str.begin() + 1);
455 std::string::size_type
n = 0;
456 while(n != std::string::npos && n < input.size()) {
457 n = input.find(
'\n', n);
458 if(n != std::string::npos) {
459 input = input.substr(0, n + 1) + leader + input.substr(n + 1);
469 out << std::setw(static_cast<int>(wid)) <<
std::left << name;
470 if(!description.empty()) {
471 if(name.length() >= wid)
472 out <<
"\n" << std::setw(static_cast<int>(wid)) <<
"";
473 for(
const char c : description) {
476 out << std::setw(static_cast<int>(wid)) <<
"";
485 if(!aliases.empty()) {
486 out << std::setw(static_cast<int>(wid)) <<
" aliases: ";
488 for(
const auto &alias : aliases) {
506 for(
auto c = str.begin() + 1;
c != e; ++
c)
514 std::size_t start_pos = 0;
516 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
517 str.replace(start_pos, from.length(), to);
518 start_pos += to.length();
525 auto loc = flags.find_first_of(
'{', 2);
526 while(loc != std::string::npos) {
527 auto finish = flags.find_first_of(
"},", loc + 1);
528 if((finish != std::string::npos) && (flags[finish] ==
'}')) {
529 flags.erase(flags.begin() +
static_cast<std::ptrdiff_t
>(loc),
530 flags.begin() +
static_cast<std::ptrdiff_t
>(finish) + 1);
532 loc = flags.find_first_of(
'{', loc + 1);
534 flags.erase(
std::remove(flags.begin(), flags.end(),
'!'), flags.end());
541 if(ignore_underscore) {
553 }
else if(ignore_underscore) {
568 auto find_ws = [delimiter](
char ch) {
569 return (delimiter ==
'\0') ? std::isspace<char>(ch, std::locale()) : (ch == delimiter);
573 std::vector<std::string> output;
574 bool embeddedQuote =
false;
576 while(!str.empty()) {
577 if(delims.find_first_of(str[0]) != std::string::npos) {
579 auto end = str.find_first_of(keyChar, 1);
580 while((
end != std::string::npos) && (str[
end - 1] ==
'\\')) {
581 end = str.find_first_of(keyChar,
end + 1);
582 embeddedQuote =
true;
584 if(
end != std::string::npos) {
585 output.push_back(str.substr(1,
end - 1));
586 if(
end + 2 < str.size()) {
587 str = str.substr(
end + 2);
593 output.push_back(str.substr(1));
600 output.push_back(value);
603 output.push_back(str);
610 embeddedQuote =
false;
618 auto next = str[offset + 1];
619 if((next ==
'\"') || (next ==
'\'') || (next ==
'`')) {
620 auto astart = str.find_last_of(
"-/ \"\'`", offset - 1);
621 if(astart != std::string::npos) {
622 if(str[astart] == ((str[offset] ==
'=') ?
'-' :
'/'))
630 if((str.front() !=
'"' && str.front() !=
'\'') || str.front() != str.back()) {
631 char quote = str.find(
'"') < str.find(
'\'') ?
'\'' :
'"';
632 if(str.find(
' ') != std::string::npos) {
633 str.insert(0, 1, quote);
634 str.append(1, quote);
646 #define CLI11_ERROR_DEF(parent, name) \
648 name(std::string ename, std::string msg, int exit_code) : parent(std::move(ename), std::move(msg), exit_code) {} \
649 name(std::string ename, std::string msg, ExitCodes exit_code) \
650 : parent(std::move(ename), std::move(msg), exit_code) {} \
653 name(std::string msg, ExitCodes exit_code) : parent(#name, std::move(msg), exit_code) {} \
654 name(std::string msg, int exit_code) : parent(#name, std::move(msg), exit_code) {}
657 #define CLI11_ERROR_SIMPLE(name) \
658 explicit name(std::string msg) : name(#name, msg, ExitCodes::name) {}
691 class Error :
public std::runtime_error {
692 int actual_exit_code;
701 : runtime_error(msg), actual_exit_code(exit_code), error_name(std::move(name)) {}
731 name +
": You can't change expected arguments after you've changed the multi option policy!");
737 return IncorrectConstruction(name +
": multi_option_policy only works for flags and exact value options");
748 return BadNameString(
"Must have a name, not just dashes: " + name);
751 return BadNameString(
"Only one positional name allowed, remove: " + name);
821 :
ConversionError(
"The value " + member +
" is not an allowed value for " + name) {}
844 if(min_subcom == 1) {
850 Option(std::size_t min_option, std::size_t max_option, std::size_t used,
const std::string &option_list) {
851 if((min_option == 1) && (max_option == 1) && (used == 0))
852 return RequiredError(
"Exactly 1 option from [" + option_list +
"]");
853 if((min_option == 1) && (max_option == 1) && (used > 1)) {
854 return {
"Exactly 1 option from [" + option_list +
"] is required and " +
std::to_string(used) +
858 if((min_option == 1) && (used == 0))
859 return RequiredError(
"At least 1 option from [" + option_list +
"]");
860 if(used < min_option) {
861 return {
"Requires at least " +
std::to_string(min_option) +
" options used and only " +
869 "were given from [" + option_list +
"]",
881 : (
"Expected at least " +
std::to_string(-expected) +
" arguments to " + name +
901 " required for each element");
923 :
ExtrasError((args.size() > 1 ?
"The following arguments were not expected: "
924 :
"The following argument was not expected: ") +
929 (args.size() > 1 ?
"The following arguments were not expected: "
930 :
"The following argument was not expected: ") +
941 return ConfigError(item +
": This option is not allowed in a configuration file");
968 #undef CLI11_ERROR_DEF
969 #undef CLI11_ERROR_SIMPLE
1005 template <
typename T>
struct is_bool : std::false_type {};
1008 template <>
struct is_bool<bool> : std::true_type {};
1014 template <
typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
1017 template <
typename T>
struct is_shared_ptr<const std::shared_ptr<T>> : std::true_type {};
1041 using type =
typename std::pointer_traits<T>::element_type;
1049 template <
typename T,
typename _ =
void>
struct pair_adaptor : std::false_type {
1055 template <
typename Q>
static auto first(Q &&pair_value) -> decltype(std::forward<Q>(pair_value)) {
1056 return std::forward<Q>(pair_value);
1059 template <
typename Q>
static auto second(Q &&pair_value) -> decltype(std::forward<Q>(pair_value)) {
1060 return std::forward<Q>(pair_value);
1066 template <
typename T>
1076 template <
typename Q>
static auto first(Q &&pair_value) -> decltype(std::get<0>(std::forward<Q>(pair_value))) {
1077 return std::get<0>(std::forward<Q>(pair_value));
1080 template <
typename Q>
static auto second(Q &&pair_value) -> decltype(std::get<1>(std::forward<Q>(pair_value))) {
1081 return std::get<1>(std::forward<Q>(pair_value));
1092 #pragma GCC diagnostic push
1093 #pragma GCC diagnostic ignored "-Wnarrowing"
1097 template <
typename TT,
typename CC>
1098 static auto test(
int, std::true_type) -> decltype(
1101 #pragma diag_suppress 2361
1103 TT{std::declval<CC>()}
1105 #pragma diag_default 2361
1108 std::is_move_assignable<TT>());
1110 template <
typename TT,
typename CC>
static auto test(
int, std::false_type) -> std::false_type;
1112 template <
typename,
typename>
static auto test(...) -> std::false_type;
1118 #pragma GCC diagnostic pop
1125 template <
typename TT,
typename SS>
1126 static auto test(
int) -> decltype(std::declval<SS &>() << std::declval<TT>(), std::true_type());
1128 template <
typename,
typename>
static auto test(...) -> std::false_type;
1131 static constexpr
bool value = decltype(test<T, S>(0))::value;
1136 template <
typename TT,
typename SS>
1137 static auto test(
int) -> decltype(std::declval<SS &>() >> std::declval<TT &>(), std::true_type());
1139 template <
typename,
typename>
static auto test(...) -> std::false_type;
1142 static constexpr
bool value = decltype(test<T, S>(0))::value;
1147 template <
typename TT>
1148 static auto test(
int) -> decltype(std::declval<TT>().real(), std::declval<TT>().imag(), std::true_type());
1150 template <
typename>
static auto test(...) -> std::false_type;
1153 static constexpr
bool value = decltype(test<T>(0))::value;
1159 std::istringstream is;
1162 return !is.fail() && !is.rdbuf()->in_avail();
1176 template <
typename T>
1181 decltype(std::declval<T>().end()),
1182 decltype(std::declval<T>().clear()),
1183 decltype(std::declval<T>().insert(std::declval<decltype(std::declval<T>().end())>(),
1184 std::declval<const typename T::value_type &>()))>,
1186 :
public conditional_t<std::is_constructible<T, std::string>::value, std::false_type, std::true_type> {};
1194 template <
typename T>
1198 :
public std::true_type {};
1201 template <
typename T,
typename _ =
void>
struct is_wrapper : std::false_type {};
1204 template <
typename T>
1209 template <
typename SS>
1213 template <
typename>
static auto test(...) -> std::false_type;
1216 static constexpr
bool value = decltype(test<S>(0))::value;
1221 auto to_string(T &&value) -> decltype(std::forward<T>(value)) {
1222 return std::forward<T>(
value);
1226 template <
typename T,
1234 template <
typename T,
1239 std::stringstream
stream;
1241 return stream.str();
1245 template <
typename T,
1254 template <
typename T,
1259 auto cval = variable.begin();
1260 auto end = variable.end();
1264 std::vector<std::string> defaults;
1265 while(cval !=
end) {
1273 template <
typename T1,
1278 return to_string(std::forward<T>(value));
1282 template <
typename T1,
1300 template <
typename T,
1307 template <
typename T,
typename def,
typename Enable =
void>
struct wrapped_type {
using type = def; };
1310 template <
typename T,
typename def>
struct wrapped_type<
T, def, typename std::enable_if<is_wrapper<T>::value>
::type> {
1315 template <
typename T,
typename Enable =
void>
struct type_count_base {
static const int value{0}; };
1318 template <
typename T>
1320 typename std::enable_if<!is_tuple_like<T>::value && !is_mutable_container<T>::value &&
1321 !std::is_void<T>::value>
::type> {
1322 static constexpr
int value{1};
1326 template <
typename T>
1345 template <
typename T,
typename Enable =
void>
struct type_count {
static const int value{0}; };
1348 template <
typename T>
1350 typename std::enable_if<!is_wrapper<T>::value && !is_tuple_like<T>::value && !is_complex<T>::value &&
1351 !std::is_void<T>::value>
::type> {
1352 static constexpr
int value{1};
1357 static constexpr
int value{2};
1361 template <
typename T>
struct type_count<
T, typename std::enable_if<is_mutable_container<T>::value>
::type> {
1366 template <
typename T>
1368 typename std::enable_if<is_wrapper<T>::value && !is_complex<T>::value && !is_tuple_like<T>::value &&
1369 !is_mutable_container<T>::value>
::type> {
1374 template <
typename T, std::
size_t I>
1380 template <
typename T, std::
size_t I>
1386 template <
typename T>
struct type_count<
T, typename std::enable_if<is_tuple_like<T>::value>
::type> {
1387 static constexpr
int value{tuple_type_size<T, 0>()};
1391 template <
typename T>
struct subtype_count {
1396 template <
typename T,
typename Enable =
void>
struct type_count_min {
static const int value{0}; };
1399 template <
typename T>
1400 struct type_count_min<
1402 typename std::enable_if<!is_mutable_container<T>::value && !is_tuple_like<T>::value && !is_wrapper<T>::value &&
1403 !is_complex<T>::value && !std::is_void<T>::value>
::type> {
1408 template <
typename T>
struct type_count_min<
T, typename std::enable_if<is_complex<T>::value>
::type> {
1409 static constexpr
int value{1};
1413 template <
typename T>
1414 struct type_count_min<
1416 typename std::enable_if<is_wrapper<T>::value && !is_complex<T>::value && !is_tuple_like<T>::value>
::type> {
1421 template <
typename T, std::
size_t I>
1427 template <
typename T, std::
size_t I>
1433 template <
typename T>
struct type_count_min<
T, typename std::enable_if<is_tuple_like<T>::value>
::type> {
1434 static constexpr
int value{tuple_type_size_min<T, 0>()};
1438 template <
typename T>
struct subtype_count_min {
1441 : type_count_min<
T>::value};
1445 template <
typename T,
typename Enable =
void>
struct expected_count {
static const int value{0}; };
1448 template <
typename T>
1449 struct expected_count<
T,
1450 typename std::enable_if<!is_mutable_container<T>::value && !is_wrapper<T>::value &&
1451 !std::is_void<T>::value>
::type> {
1452 static constexpr
int value{1};
1455 template <
typename T>
struct expected_count<
T, typename std::enable_if<is_mutable_container<T>::value>
::type> {
1460 template <
typename T>
1461 struct expected_count<
T, typename std::enable_if<!is_mutable_container<T>::value && is_wrapper<T>::value>
::type> {
1466 enum class object_category :
int {
1469 unsigned_integral = 4,
1472 floating_point = 10,
1473 number_constructible = 12,
1474 double_constructible = 14,
1475 integer_constructible = 16,
1477 string_assignable = 23,
1478 string_constructible = 24,
1482 complex_number = 60,
1484 container_value = 80,
1491 template <
typename T,
typename Enable =
void>
struct classify_object {
1492 static constexpr object_category value{object_category::other};
1496 template <
typename T>
1497 struct classify_object<
1499 typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value && std::is_signed<T>::value &&
1500 !is_bool<T>::value && !std::is_enum<T>::value>
::type> {
1501 static constexpr object_category value{object_category::integral_value};
1505 template <
typename T>
1506 struct classify_object<
T,
1507 typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value &&
1508 !std::is_same<T, char>::value && !is_bool<T>::value>
::type> {
1509 static constexpr object_category value{object_category::unsigned_integral};
1513 template <
typename T>
1514 struct classify_object<
T, typename std::enable_if<std::is_same<T, char>::value && !std::is_enum<T>::value>
::type> {
1515 static constexpr object_category value{object_category::char_value};
1519 template <
typename T>
struct classify_object<
T, typename std::enable_if<is_bool<T>::value>
::type> {
1520 static constexpr object_category value{object_category::boolean_value};
1524 template <
typename T>
struct classify_object<
T, typename std::enable_if<std::is_floating_point<T>::value>
::type> {
1525 static constexpr object_category value{object_category::floating_point};
1529 template <
typename T>
1530 struct classify_object<
T,
1531 typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
1532 std::is_assignable<T &, std::string>::value>
::type> {
1533 static constexpr object_category value{object_category::string_assignable};
1537 template <
typename T>
1538 struct classify_object<
1540 typename std::enable_if<!std::is_floating_point<T>::value && !std::is_integral<T>::value &&
1541 !std::is_assignable<T &, std::string>::value && (type_count<T>::value == 1) &&
1542 std::is_constructible<T, std::string>::value>
::type> {
1543 static constexpr object_category value{object_category::string_constructible};
1547 template <
typename T>
struct classify_object<
T, typename std::enable_if<std::is_enum<T>::value>
::type> {
1548 static constexpr object_category value{object_category::enumeration};
1551 template <
typename T>
struct classify_object<
T, typename std::enable_if<is_complex<T>::value>
::type> {
1552 static constexpr object_category value{object_category::complex_number};
1557 template <
typename T>
struct uncommon_type {
1568 template <
typename T>
1569 struct classify_object<
T,
1570 typename std::enable_if<(!is_mutable_container<T>::value && is_wrapper<T>::value &&
1571 !is_tuple_like<T>::value && uncommon_type<T>::value)>
::type> {
1572 static constexpr object_category value{object_category::wrapper_value};
1576 template <
typename T>
1577 struct classify_object<
T,
1578 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
1579 !is_wrapper<T>::value && is_direct_constructible<T, double>::value &&
1580 is_direct_constructible<T, int>::value>
::type> {
1581 static constexpr object_category value{object_category::number_constructible};
1585 template <
typename T>
1586 struct classify_object<
T,
1587 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
1588 !is_wrapper<T>::value && !is_direct_constructible<T, double>::value &&
1589 is_direct_constructible<T, int>::value>
::type> {
1590 static constexpr object_category value{object_category::integer_constructible};
1594 template <
typename T>
1595 struct classify_object<
T,
1596 typename std::enable_if<uncommon_type<T>::value && type_count<T>::value == 1 &&
1597 !is_wrapper<T>::value && is_direct_constructible<T, double>::value &&
1598 !is_direct_constructible<T, int>::value>
::type> {
1599 static constexpr object_category value{object_category::double_constructible};
1603 template <
typename T>
1604 struct classify_object<
1606 typename std::enable_if<is_tuple_like<T>::value &&
1607 ((type_count<T>::value >= 2 && !is_wrapper<T>::value) ||
1608 (uncommon_type<T>::value && !is_direct_constructible<T, double>::value &&
1609 !is_direct_constructible<T, int>::value) ||
1610 (uncommon_type<T>::value && type_count<T>::value >= 2))>
::type> {
1611 static constexpr object_category value{object_category::tuple_value};
1620 template <
typename T>
struct classify_object<
T, typename std::enable_if<is_mutable_container<T>::value>
::type> {
1621 static constexpr object_category value{object_category::container_value};
1630 template <
typename T,
1636 template <
typename T,
1644 template <
typename T,
1650 template <
typename T,
1660 template <
typename T,
1667 template <
typename T,
1674 template <
typename T,
1681 template <
typename T,
1689 template <
typename T,
1695 template <
typename T,
1702 template <
typename T,
1710 template <
typename T, std::
size_t I>
1716 template <
typename T, std::
size_t I>
1719 tuple_name<T, I + 1>();
1720 if(str.back() ==
',')
1726 template <
typename T,
1730 auto tname =
std::string(1,
'[') + tuple_name<T, 0>();
1731 tname.push_back(
']');
1736 template <
typename T,
1737 enable_if_t<classify_object<T>::value == object_category::container_value ||
1741 return type_name<typename T::value_type>();
1752 char *
val =
nullptr;
1753 std::uint64_t output_ll = std::strtoull(input.c_str(), &
val, 0);
1754 output =
static_cast<T>(output_ll);
1755 if(val == (input.c_str() + input.size()) && static_cast<std::uint64_t>(output) == output_ll) {
1759 std::int64_t output_sll = std::strtoll(input.c_str(), &
val, 0);
1760 if(val == (input.c_str() + input.size())) {
1761 output = (output_sll < 0) ? static_cast<T>(0) : static_cast<T>(output_sll);
1762 return (static_cast<std::int64_t>(output) == output_sll);
1773 char *
val =
nullptr;
1774 std::int64_t output_ll = std::strtoll(input.c_str(), &
val, 0);
1775 output =
static_cast<T>(output_ll);
1776 if(val == (input.c_str() + input.size()) && static_cast<std::int64_t>(output) == output_ll) {
1779 if(input ==
"true") {
1781 output =
static_cast<T>(1);
1791 if(val == trueString) {
1794 if(val == falseString) {
1798 std::int64_t ret = 0;
1799 if(val.size() == 1) {
1800 if(val[0] >=
'1' && val[0] <=
'9') {
1801 return (static_cast<std::int64_t>(val[0]) -
'0');
1816 throw std::invalid_argument(
"unrecognized character");
1820 if(val == trueString || val ==
"on" || val ==
"yes" || val ==
"enable") {
1822 }
else if(val == falseString || val ==
"off" || val ==
"no" || val ==
"disable") {
1825 ret = std::stoll(val);
1831 template <
typename T,
1832 enable_if_t<classify_object<T>::value == object_category::integral_value ||
1840 template <
typename T,
1841 enable_if_t<classify_object<T>::value == object_category::char_value, detail::enabler> =
detail::dummy>
1843 if(input.size() == 1) {
1844 output =
static_cast<T>(input[0]);
1851 template <
typename T,
1852 enable_if_t<classify_object<T>::value == object_category::boolean_value, detail::enabler> =
detail::dummy>
1858 }
catch(
const std::invalid_argument &) {
1860 }
catch(
const std::out_of_range &) {
1863 output = (input[0] !=
'-');
1869 template <
typename T,
1870 enable_if_t<classify_object<T>::value == object_category::floating_point, detail::enabler> =
detail::dummy>
1875 char *val =
nullptr;
1876 auto output_ld = std::strtold(input.c_str(), &
val);
1877 output =
static_cast<T>(output_ld);
1878 return val == (input.c_str() + input.size());
1882 template <
typename T,
1883 enable_if_t<classify_object<T>::value == object_category::complex_number, detail::enabler> =
detail::dummy>
1888 bool worked =
false;
1889 auto nloc = str1.find_last_of(
"+-");
1890 if(nloc != std::string::npos && nloc > 0) {
1892 str1 = str1.substr(nloc);
1893 if(str1.back() ==
'i' || str1.back() ==
'j')
1897 if(str1.back() ==
'i' || str1.back() ==
'j') {
1914 template <
typename T,
1915 enable_if_t<classify_object<T>::value == object_category::string_assignable, detail::enabler> =
detail::dummy>
1924 enable_if_t<classify_object<T>::value == object_category::string_constructible, detail::enabler> =
detail::dummy>
1931 template <
typename T,
1932 enable_if_t<classify_object<T>::value == object_category::enumeration, detail::enabler> =
detail::dummy>
1938 output =
static_cast<T>(
val);
1943 template <
typename T,
1944 enable_if_t<classify_object<T>::value == object_category::wrapper_value &&
1956 template <
typename T,
1957 enable_if_t<classify_object<T>::value == object_category::wrapper_value &&
1972 enable_if_t<classify_object<T>::value == object_category::number_constructible, detail::enabler> =
detail::dummy>
1992 enable_if_t<classify_object<T>::value == object_category::integer_constructible, detail::enabler> =
detail::dummy>
2005 enable_if_t<classify_object<T>::value == object_category::double_constructible, detail::enabler> =
detail::dummy>
2016 template <
typename T,
2023 #pragma warning(push)
2024 #pragma warning(disable : 4800)
2030 #pragma warning(pop)
2042 template <
typename T,
2043 enable_if_t<classify_object<T>::value == object_category::other && !std::is_assignable<T &, int>::value,
2047 "option object type must have a lexical cast overload or streaming input operator(>>) defined, if it "
2048 "is convertible from another type use the add_option<T, XC>(...) with XC being the known type");
2054 template <
typename AssignTo,
2058 classify_object<AssignTo>::value == object_category::string_constructible),
2065 template <
typename AssignTo,
2068 classify_object<AssignTo>::value != object_category::string_assignable &&
2069 classify_object<AssignTo>::value != object_category::string_constructible,
2073 output = AssignTo{};
2081 template <
typename AssignTo,
2084 classify_object<AssignTo>::value == object_category::wrapper_value,
2097 template <
typename AssignTo,
2100 classify_object<AssignTo>::value != object_category::wrapper_value &&
2117 template <
typename AssignTo,
2123 bool parse_result = (!input.empty()) ? lexical_cast<ConvertTo>(input, val) :
true;
2127 return parse_result;
2139 bool parse_result = input.empty() ?
true :
lexical_cast<ConvertTo>(input,
val);
2141 output = AssignTo(val);
2143 return parse_result;
2147 template <
typename AssignTo,
2150 classify_object<AssignTo>::value <= object_category::wrapper_value,
2152 bool lexical_conversion(
const std::vector<std ::string> &
strings, AssignTo &output) {
2153 return lexical_assign<AssignTo, ConvertTo>(strings[0], output);
2158 template <
typename AssignTo,
2163 bool lexical_conversion(
const std::vector<std ::string> &
strings, AssignTo &output) {
2167 bool retval = lexical_assign<decltype(v1), decltype(v1)>(strings[0],
v1);
2168 if(strings.size() > 1) {
2169 retval = retval && lexical_assign<decltype(v2), decltype(v2)>(strings[1],
v2);
2172 output = AssignTo{
v1, v2};
2178 template <
class AssignTo,
2183 bool lexical_conversion(
const std::vector<std ::string> &strings, AssignTo &output) {
2184 output.erase(output.begin(), output.end());
2185 if(strings.size() == 1 && strings[0] ==
"{}") {
2188 bool skip_remaining =
false;
2189 if(strings.size() == 2 && strings[0] ==
"{}" &&
is_separator(strings[1])) {
2190 skip_remaining =
true;
2192 for(
const auto &elem : strings) {
2194 bool retval = lexical_assign<typename AssignTo::value_type, typename ConvertTo::value_type>(elem, out);
2198 output.insert(output.end(), std::move(out));
2199 if(skip_remaining) {
2203 return (!output.empty());
2208 bool lexical_conversion(
const std::vector<std::string> &strings, AssignTo &output) {
2210 if(strings.size() >= 2 && !strings[1].empty()) {
2213 auto str1 = strings[1];
2214 if(str1.back() ==
'i' || str1.back() ==
'j') {
2219 output = ConvertTo{
x,
y};
2223 return lexical_assign<AssignTo, ConvertTo>(strings[0], output);
2227 template <
class AssignTo,
2230 (type_count<ConvertTo>::value == 1),
2232 bool lexical_conversion(
const std::vector<std ::string> &strings, AssignTo &output) {
2235 output.reserve(strings.size());
2236 for(
const auto &elem : strings) {
2238 output.emplace_back();
2239 retval = retval && lexical_assign<typename AssignTo::value_type, ConvertTo>(elem, output.back());
2241 return (!output.empty()) && retval;
2247 template <
class AssignTo,
2252 bool lexical_conversion(std::vector<std::string> strings, AssignTo &output);
2255 template <
class AssignTo,
2258 type_count_base<ConvertTo>::value != 2 &&
2259 ((type_count<ConvertTo>::value > 2) ||
2260 (type_count<ConvertTo>::value > type_count_base<ConvertTo>::value)),
2262 bool lexical_conversion(
const std::vector<std::string> &strings, AssignTo &output);
2265 template <
class AssignTo,
2268 (type_count_base<ConvertTo>::value != type_count<ConvertTo>::value ||
2269 type_count<ConvertTo>::value > 2),
2271 bool lexical_conversion(
const std::vector<std::string> &strings, AssignTo &output);
2275 template <
typename AssignTo,
2281 bool lexical_conversion(
const std::vector<std ::string> &strings, AssignTo &output) {
2283 if(strings.size() > 1 || (!strings.empty() && !(strings.front().empty()))) {
2285 auto retval = lexical_conversion<ConvertTo, ConvertTo>(
strings,
val);
2286 output = AssignTo{val};
2289 output = AssignTo{};
2294 template <
class AssignTo,
class ConvertTo, std::
size_t I>
2296 tuple_conversion(
const std::vector<std::string> &, AssignTo &) {
2301 template <
class AssignTo,
class ConvertTo>
2303 tuple_type_conversion(std::vector<std::string> &strings, AssignTo &output) {
2304 auto retval = lexical_assign<AssignTo, ConvertTo>(strings[0], output);
2305 strings.erase(strings.begin());
2310 template <
class AssignTo,
class ConvertTo>
2314 tuple_type_conversion(std::vector<std::string> &strings, AssignTo &output) {
2315 auto retval = lexical_conversion<AssignTo, ConvertTo>(
strings, output);
2316 strings.erase(strings.begin(), strings.begin() + type_count<ConvertTo>::value);
2321 template <
class AssignTo,
class ConvertTo>
2325 tuple_type_conversion(std::vector<std::string> &strings, AssignTo &output) {
2329 const std::size_t mx{(
std::max)(mx_count, strings.size())};
2337 bool retval = lexical_conversion<AssignTo, ConvertTo>(
2338 std::vector<std::string>(strings.begin(), strings.begin() +
static_cast<std::ptrdiff_t
>(
index)), output);
2339 strings.erase(strings.begin(), strings.begin() +
static_cast<std::ptrdiff_t
>(
index) + 1);
2344 template <
class AssignTo,
class ConvertTo, std::
size_t I>
2346 tuple_conversion(std::vector<std::string> strings, AssignTo &output) {
2348 using ConvertToElement =
typename std::
2350 if(!strings.empty()) {
2352 strings, std::get<I>(output));
2354 retval = retval && tuple_conversion<AssignTo, ConvertTo, I + 1>(std::move(strings), output);
2359 template <
class AssignTo,
2362 type_count_base<ConvertTo>::value == 2,
2364 bool lexical_conversion(std::vector<std::string> strings, AssignTo &output) {
2366 while(!strings.empty()) {
2370 bool retval = tuple_type_conversion<decltype(v1), decltype(v1)>(
strings,
v1);
2371 if(!strings.empty()) {
2372 retval = retval && tuple_type_conversion<decltype(v2), decltype(v2)>(
strings,
v2);
2380 return (!output.empty());
2384 template <
class AssignTo,
2387 (type_count_base<ConvertTo>::value != type_count<ConvertTo>::value ||
2388 type_count<ConvertTo>::value > 2),
2390 bool lexical_conversion(
const std::vector<std ::string> &strings, AssignTo &output) {
2393 "if the conversion type is defined as a tuple it must be the same size as the type you are converting to");
2394 return tuple_conversion<AssignTo, ConvertTo, 0>(
strings, output);
2398 template <
class AssignTo,
2401 type_count_base<ConvertTo>::value != 2 &&
2402 ((type_count<ConvertTo>::value > 2) ||
2403 (type_count<ConvertTo>::value > type_count_base<ConvertTo>::value)),
2405 bool lexical_conversion(
const std::vector<std ::string> &strings, AssignTo &output) {
2408 std::vector<std::string> temp;
2410 std::size_t icount{0};
2411 std::size_t xcm{type_count<ConvertTo>::value};
2412 auto ii_max = strings.size();
2413 while(ii < ii_max) {
2414 temp.push_back(strings[ii]);
2417 if(icount == xcm ||
is_separator(temp.back()) || ii == ii_max) {
2423 lexical_conversion<typename AssignTo::value_type, typename ConvertTo::value_type>(temp, temp_out);
2428 output.insert(output.end(), std::move(temp_out));
2436 template <
typename AssignTo,
2438 enable_if_t<classify_object<ConvertTo>::value == object_category::wrapper_value &&
2441 bool lexical_conversion(
const std::vector<std::string> &strings, AssignTo &output) {
2442 if(strings.empty() || strings.front().empty()) {
2443 output = ConvertTo{};
2447 if(lexical_conversion<typename ConvertTo::value_type, typename ConvertTo::value_type>(strings, val)) {
2448 output = ConvertTo{val};
2455 template <
typename AssignTo,
2457 enable_if_t<classify_object<ConvertTo>::value == object_category::wrapper_value &&
2460 bool lexical_conversion(
const std::vector<std::string> &strings, AssignTo &output) {
2462 if(strings.empty() || strings.front().empty()) {
2463 output = ConvertType{};
2467 if(lexical_conversion<typename ConvertTo::value_type, typename ConvertTo::value_type>(strings, val)) {
2479 for(
const auto &
arg : values) {
2485 }
catch(
const std::exception &) {
2493 for(
const auto &arg : values) {
2500 val == static_cast<std::int64_t>(val)) {
2532 get_names(
const std::vector<std::string> &input);
2541 if(current.size() > 1 && current[0] ==
'-' &&
valid_first_char(current[1])) {
2542 name = current.substr(1, 1);
2543 rest = current.substr(2);
2550 if(current.size() > 2 && current.substr(0, 2) ==
"--" &&
valid_first_char(current[2])) {
2551 auto loc = current.find_first_of(
'=');
2552 if(loc != std::string::npos) {
2553 name = current.substr(2, loc - 2);
2554 value = current.substr(loc + 1);
2556 name = current.substr(2);
2565 if(current.size() > 1 && current[0] ==
'/' &&
valid_first_char(current[1])) {
2566 auto loc = current.find_first_of(
':');
2567 if(loc != std::string::npos) {
2568 name = current.substr(1, loc - 1);
2569 value = current.substr(loc + 1);
2571 name = current.substr(1);
2580 std::vector<std::string> output;
2581 std::size_t val = 0;
2582 while((val = current.find(
',')) != std::string::npos) {
2583 output.push_back(
trim_copy(current.substr(0, val)));
2584 current = current.substr(val + 1);
2592 flags.erase(std::remove_if(flags.begin(),
2595 return ((
name.empty()) || (!(((
name.find_first_of(
'{') != std::string::npos) &&
2596 (
name.back() ==
'}')) ||
2597 (
name[0] ==
'!'))));
2600 std::vector<std::pair<std::string, std::string>> output;
2601 output.reserve(flags.size());
2602 for(
auto &flag : flags) {
2603 auto def_start = flag.find_first_of(
'{');
2605 if((def_start != std::string::npos) && (flag.back() ==
'}')) {
2606 defval = flag.substr(def_start + 1);
2608 flag.erase(def_start, std::string::npos);
2610 flag.erase(0, flag.find_first_not_of(
"-!"));
2611 output.emplace_back(flag, defval);
2619 std::vector<std::string> short_names;
2620 std::vector<std::string> long_names;
2624 if(
name.length() == 0) {
2627 if(
name.length() > 1 &&
name[0] ==
'-' &&
name[1] !=
'-') {
2629 short_names.emplace_back(1,
name[1]);
2631 throw BadNameString::OneCharName(
name);
2632 }
else if(
name.length() > 2 &&
name.substr(0, 2) ==
"--") {
2635 long_names.push_back(
name);
2637 throw BadNameString::BadLongName(
name);
2638 }
else if(
name ==
"-" ||
name ==
"--") {
2639 throw BadNameString::DashesOnly(
name);
2641 if(pos_name.length() > 0)
2642 throw BadNameString::MultiPositionalNames(
name);
2647 return std::make_tuple(short_names, long_names, pos_name);
2659 std::vector<std::string> parents{};
2665 std::vector<std::string> inputs{};
2669 std::vector<std::string> tmp = parents;
2670 tmp.emplace_back(
name);
2678 std::vector<ConfigItem> items{};
2685 virtual std::vector<ConfigItem> from_config(std::istream &)
const = 0;
2689 if(item.
inputs.size() == 1) {
2690 return item.
inputs.at(0);
2692 if(item.
inputs.empty()) {
2695 throw ConversionError::TooManyInputsFlag(item.
fullname());
2702 throw FileError::Missing(name);
2704 return from_config(input);
2708 virtual ~
Config() =
default;
2715 char commentChar =
'#';
2717 char arrayStart =
'[';
2719 char arrayEnd =
']';
2721 char arraySeparator =
',';
2723 char valueDelimiter =
'=';
2725 char stringQuote =
'"';
2727 char characterQuote =
'\'';
2729 uint8_t maximumLayers{255};
2731 char parentSeparatorChar{
'.'};
2733 int16_t configIndex{-1};
2739 to_config(
const App * ,
bool default_also,
bool write_description,
std::string prefix)
const override;
2741 std::vector<ConfigItem> from_config(std::istream &input)
const override;
2744 commentChar = cchar;
2749 arrayStart = aStart;
2755 arraySeparator = aSep;
2760 valueDelimiter = vSep;
2765 stringQuote = qString;
2766 characterQuote = qChar;
2771 maximumLayers = layers;
2776 parentSeparatorChar = sep;
2785 configSection = sectionName;
2795 configIndex = sectionIndex;
2811 arraySeparator =
' ';
2812 valueDelimiter =
'=';
2833 std::function<std::string()> desc_function_{[]() {
return std::string{}; }};
2841 int application_index_ = -1;
2845 bool non_modifying_{
false};
2848 : desc_function_([validator_desc]() {
return validator_desc; }), func_(std::move(
func)) {}
2851 Validator() =
default;
2856 : desc_function_([validator_desc]() {
return validator_desc; }), func_(std::move(op)),
2860 func_ = std::move(op);
2876 desc_function_ = [validator_desc]() {
return validator_desc; };
2885 return desc_function_();
2891 name_ = std::move(validator_name);
2897 newval.
name_ = std::move(validator_name);
2904 active_ = active_val;
2916 non_modifying_ = no_modify;
2921 application_index_ = app_index;
3022 auto val = DesiredType();
3024 return std::string(
"Failed parsing ") + input_string +
" as a " + detail::type_name<DesiredType>();
3028 TypeValidator() : TypeValidator(detail::
type_name<DesiredType>()) {}
3032 const TypeValidator<double>
Number(
"NUMBER");
3048 template <
typename T>
3050 if(validator_name.empty()) {
3051 std::stringstream out;
3052 out << detail::type_name<T>() <<
" in [" << min_val <<
" - " << max_val <<
"]";
3053 description(out.str());
3060 std::stringstream out;
3061 out <<
"Value " << input <<
" not in range [";
3062 out << min_val <<
" - " << max_val <<
"]";
3070 template <
typename T>
3072 :
Range(static_cast<T>(0), max_val, validator_name) {}
3088 template <
typename T>
Bound(T min_val, T max_val) {
3089 std::stringstream out;
3090 out << detail::type_name<T>() <<
" bounded to [" << min_val <<
" - " << max_val <<
"]";
3091 description(out.str());
3097 return std::string(
"Value ") + input +
" could not be converted";
3101 else if(val > max_val)
3109 template <
typename T>
explicit Bound(T max_val) :
Bound(static_cast<
T>(0), max_val) {}
3113 template <
typename T,
3145 [key_only](
const iteration_type_t &
v) {
3160 template <
typename CC,
typename VV>
3161 static auto test(
int) -> decltype(std::declval<CC>().
find(std::declval<VV>()), std::true_type());
3162 template <
typename,
typename>
static auto test(...) -> decltype(std::false_type());
3164 static const auto value = decltype(test<C, V>(0))::value;
3165 using type = std::integral_constant<bool, value>;
3170 auto search(
const T &set,
const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
3176 return {(it !=
std::end(setref)), it};
3181 auto search(
const T &set,
const V &val) -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
3183 auto it = setref.find(val);
3184 return {(it !=
std::end(setref)), it};
3188 template <
typename T,
typename V>
3189 auto search(
const T &set,
const V &val,
const std::function<V(V)> &filter_function)
3190 -> std::pair<bool, decltype(std::begin(detail::smart_deref(set)))> {
3193 auto res =
search(set, val);
3194 if((res.first) || (!(filter_function))) {
3201 a = filter_function(
a);
3204 return {(it !=
std::end(setref)), it};
3211 template <
typename T>
3213 if((a > 0) == (b > 0)) {
3219 template <
typename T>
3226 if(a == 0 || b == 0 || a == 1 || b == 1) {
3241 template <
typename T>
3244 if(std::isinf(c) && !std::isinf(a) && !std::isinf(b)) {
3258 template <
typename T,
typename... Args>
3260 :
IsMember(std::vector<
T>(values), std::forward<Args>(
args)...) {}
3267 template <
typename T,
typename F>
explicit IsMember(T set, F filter_function) {
3278 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
3310 template <
typename T,
typename... Args>
3313 std::forward<
T>(set),
3314 [filter_fn_1, filter_fn_2](std::
string a) {
return filter_fn_2(filter_fn_1(
a)); },
3327 template <
typename... Args>
3328 Transformer(std::initializer_list<std::pair<std::string, std::string>> values, Args &&...
args)
3336 template <
typename T,
typename F>
explicit Transformer(T mapping, F filter_function) {
3339 "mapping must produce value pairs");
3348 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
3353 func_ = [mapping, filter_fn](
std::string &input) {
3371 template <
typename T,
typename... Args>
3374 std::forward<
T>(mapping),
3375 [filter_fn_1, filter_fn_2](std::
string a) {
return filter_fn_2(filter_fn_1(
a)); },
3385 template <
typename... Args>
3397 "mapping must produce value pairs");
3407 std::function<local_item_t(local_item_t)> filter_fn = filter_function;
3409 auto tfunc = [mapping]() {
3420 desc_function_ = tfunc;
3422 func_ = [mapping, tfunc, filter_fn](
std::string &input) {
3437 if(output_string == input) {
3442 return "Check " + input +
" " + tfunc() +
" FAILED";
3447 template <
typename T,
typename... Args>
3450 std::forward<
T>(mapping),
3451 [filter_fn_1, filter_fn_2](std::
string a) {
return filter_fn_2(filter_fn_1(
a)); },
3487 CASE_INSENSITIVE = 1,
3493 template <
typename Number>
3497 description(generate_description<Number>(unit_name, opts));
3498 validate_mapping(mapping, opts);
3510 auto unit_begin = input.end();
3511 while(unit_begin > input.begin() &&
std::isalpha(*(unit_begin - 1), std::locale())) {
3516 input.resize(static_cast<std::size_t>(
std::distance(input.begin(), unit_begin)));
3519 if(opts & UNIT_REQUIRED &&
unit.empty()) {
3522 if(opts & CASE_INSENSITIVE) {
3528 detail::type_name<Number>());
3535 auto it = mapping.find(
unit);
3536 if(it == mapping.end()) {
3538 " unit not recognized. "
3539 "Allowed values: " +
3543 if(!input.empty()) {
3547 detail::type_name<Number>());
3553 " factor would cause number overflow. Use smaller value.");
3556 num =
static_cast<Number>(it->second);
3568 template <
typename Number>
static void validate_mapping(std::map<std::string, Number> &mapping, Options opts) {
3569 for(
auto &kv : mapping) {
3570 if(kv.first.empty()) {
3574 throw ValidationError(
"Unit must contain only letters.");
3579 if(opts & CASE_INSENSITIVE) {
3580 std::map<std::string, Number> lower_mapping;
3581 for(
auto &kv : mapping) {
3583 if(lower_mapping.count(
s)) {
3589 mapping = std::move(lower_mapping);
3595 std::stringstream out;
3596 out << detail::type_name<Number>() <<
' ';
3597 if(opts & UNIT_REQUIRED) {
3600 out <<
'[' << name <<
']';
3636 static std::map<std::string, result_t> init_mapping(
bool kb_is_1000);
3639 static std::map<std::string, result_t> get_mapping(
bool kb_is_1000);
3658 if(non_modifying_) {
3660 retstring = func_(value);
3662 retstring = func_(str);
3670 newval.
desc_function_ = [validator_desc]() {
return validator_desc; };
3677 newval._merge_description(*
this, other,
" AND ");
3680 const std::function<std::string(std::string & filename)> &f1 = func_;
3681 const std::function<std::string(std::string & filename)> &f2 = other.
func_;
3686 if(!s1.empty() && !s2.empty())
3687 return std::string(
"(") + s1 +
") AND (" + s2 +
")";
3699 newval._merge_description(*
this, other,
" OR ");
3702 const std::function<std::string(std::string &)> &f1 = func_;
3703 const std::function<std::string(std::string &)> &f2 = other.
func_;
3708 if(s1.empty() || s2.empty())
3711 return std::string(
"(") + s1 +
") OR (" + s2 +
")";
3720 const std::function<std::string()> &dfunc1 = desc_function_;
3722 auto str = dfunc1();
3726 const std::function<std::string(std::string & res)> &f1 = func_;
3731 return std::string(
"check ") + dfunc1() +
" succeeded improperly";
3743 const std::function<std::string()> &dfunc1 = val1.
desc_function_;
3744 const std::function<std::string()> &dfunc2 = val2.
desc_function_;
3746 desc_function_ = [=]() {
3749 if((f1.empty()) || (f2.empty())) {
3752 return std::string(1,
'(') + f1 +
')' + merger +
'(' + f2 +
')';
3758 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
3761 auto stat = std::filesystem::status(
file, ec);
3765 switch(stat.type()) {
3766 case std::filesystem::file_type::none:
3767 case std::filesystem::file_type::not_found:
3769 case std::filesystem::file_type::directory:
3771 case std::filesystem::file_type::symlink:
3772 case std::filesystem::file_type::block:
3773 case std::filesystem::file_type::character:
3774 case std::filesystem::file_type::fifo:
3775 case std::filesystem::file_type::socket:
3776 case std::filesystem::file_type::regular:
3777 case std::filesystem::file_type::unknown:
3784 #if defined(_MSC_VER)
3785 struct __stat64 buffer;
3786 if(_stat64(
file, &buffer) == 0) {
3791 if(stat(
file, &buffer) == 0) {
3803 return "File does not exist: " +
filename;
3806 return "File is actually a directory: " +
filename;
3816 return "Directory does not exist: " +
filename;
3819 return "Directory is actually a file: " +
filename;
3829 return "Path does not exist: " +
filename;
3839 return "Path already exists: " +
filename;
3849 return std::string(
"Invalid IPV4 address must have four parts (") + ip_addr +
')';
3852 for(
const auto &var :
result) {
3855 return std::string(
"Failed parsing number (") + var +
')';
3857 if(num < 0 || num > 255) {
3858 return std::string(
"Each IP number must be between 0 and 255 ") + var;
3873 if(default_path.back() !=
'/' && default_path.back() !=
'\\') {
3875 test_file_path +=
'/';
3882 if(enableErrorReturn) {
3883 return "File does not exist: " +
filename;
3893 description(
"SIZE [b, kb(=1000b), kib(=1024b), ...]");
3899 CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::init_mapping(
bool kb_is_1000) {
3900 std::map<std::string, result_t> m;
3901 result_t k_factor = kb_is_1000 ? 1000 : 1024;
3906 for(
std::string p : {
"k",
"m",
"g",
"t",
"p",
"e"}) {
3917 CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::get_mapping(
bool kb_is_1000) {
3919 static auto m = init_mapping(
true);
3922 static auto m = init_mapping(
false);
3930 std::pair<std::string, std::string> vals;
3932 auto esp = commandline.find_first_of(
' ', 1);
3934 esp = commandline.find_first_of(
' ', esp + 1);
3935 if(esp == std::string::npos) {
3938 if(commandline[0] ==
'"' || commandline[0] ==
'\'' || commandline[0] ==
'`') {
3939 bool embeddedQuote =
false;
3940 auto keyChar = commandline[0];
3941 auto end = commandline.find_first_of(keyChar, 1);
3942 while((
end != std::string::npos) && (commandline[
end - 1] ==
'\\')) {
3943 end = commandline.find_first_of(keyChar,
end + 1);
3944 embeddedQuote =
true;
3946 if(
end != std::string::npos) {
3947 vals.first = commandline.substr(1,
end - 1);
3953 esp = commandline.find_first_of(
' ', 1);
3956 esp = commandline.find_first_of(
' ', 1);
3962 if(vals.first.empty()) {
3963 vals.first = commandline.substr(0, esp);
3968 vals.second = (esp < commandline.length() - 1) ? commandline.substr(esp + 1) :
std::string{};
4055 using funct_t = std::function<std::string(const App *, std::string, AppFormatMode)>;
4069 return lambda_(app, name, mode);
4124 std::stringstream out;
4200 template <
typename T>
void copy_to(T *other)
const;
4211 return static_cast<CRTP *
>(
this);
4217 return static_cast<CRTP *
>(
this);
4225 return static_cast<CRTP *
>(
this);
4261 auto *
self =
static_cast<CRTP *
>(
this);
4268 auto *
self =
static_cast<CRTP *
>(
this);
4275 auto self =
static_cast<CRTP *
>(
this);
4282 auto *
self =
static_cast<CRTP *
>(
this);
4289 auto self =
static_cast<CRTP *
>(
this);
4298 return static_cast<CRTP *
>(
this);
4304 return static_cast<CRTP *
>(
this);
4565 auto opt =
static_cast<T *
>(
parent_)->get_option_no_throw(opt_name);
4566 if(opt ==
nullptr) {
4567 throw IncorrectConstruction::MissingOption(opt_name);
4586 auto opt =
static_cast<T *
>(
parent_)->get_option_no_throw(opt_name);
4587 if(opt ==
nullptr) {
4588 throw IncorrectConstruction::MissingOption(opt_name);
4732 bool all_options =
false
4789 template <
typename T>
void results(T &output)
const {
4790 bool retval =
false;
4793 retval = detail::lexical_conversion<T, T>(res, output);
4800 _validate_results(res);
4802 _reduce_results(extra, res);
4803 if(!extra.empty()) {
4804 res = std::move(extra);
4812 retval = detail::lexical_conversion<T, T>(res, output);
4849 Option *
type_size(
int option_type_size_min,
int option_type_size_max);
4907 void _validate_results(
results_t &res)
const;
4925 other->group(group_);
4926 other->required(required_);
4927 other->ignore_case(ignore_case_);
4928 other->ignore_underscore(ignore_underscore_);
4929 other->configurable(configurable_);
4930 other->disable_flag_override(disable_flag_override_);
4931 other->delimiter(delimiter_);
4932 other->always_capture_default(always_capture_default_);
4933 other->multi_option_policy(multi_option_policy_);
4959 value_min = -value_min;
4965 if(value_max < value_min) {
4979 if(!validator_name.empty())
4987 validators_.emplace_back(
Validator, std::move(Validator_description), std::move(Validator_name));
4994 if(!Validator_name.empty())
5008 std::move(transform_description),
5009 std::move(transform_name)));
5030 if((Validator_name.empty()) && (!validators_.empty())) {
5031 return &(validators_.front());
5038 if(index >= 0 && index < static_cast<int>(
validators_.size())) {
5082 auto *parent =
static_cast<T *
>(
parent_);
5083 for(
const Option_p &opt : parent->options_) {
5084 if(opt.get() ==
this) {
5087 const auto &omatch = opt->matching_name(*
this);
5088 if(!omatch.empty()) {
5090 throw OptionAlreadyAdded(
"adding ignore case caused a name conflict with " + omatch);
5103 auto *parent =
static_cast<T *
>(
parent_);
5104 for(
const Option_p &opt : parent->options_) {
5105 if(opt.get() ==
this) {
5108 const auto &omatch = opt->matching_name(*
this);
5109 if(!omatch.empty()) {
5111 throw OptionAlreadyAdded(
"adding ignore underscore caused a name conflict with " + omatch);
5139 std::vector<std::string> name_list;
5143 name_list.push_back(
pname_);
5147 name_list.push_back(
"-" + sname);
5154 name_list.push_back(
"--" + lname);
5161 name_list.push_back(
"-" + sname);
5164 name_list.push_back(
"--" + lname);
5205 bool local_result =
callback_(send_results);
5235 if(name.length() > 2 && name[0] ==
'-' && name[1] ==
'-')
5237 if(name.length() > 1 && name.front() ==
'-')
5250 if(local_name == local_pname) {
5269 if(!((input_value.empty()) || (input_value == emptyString))) {
5271 if(default_ind >= 0) {
5274 throw(ArgumentMismatch::FlagOverride(name));
5277 if(input_value != trueString) {
5278 throw(ArgumentMismatch::FlagOverride(name));
5284 if((input_value.empty()) || (input_value == emptyString)) {
5296 return (val == 1) ? falseString : (val == (-1) ? trueString :
std::to_string(-val));
5297 }
catch(
const std::invalid_argument &) {
5306 _add_result(std::move(s),
results_);
5312 results_added = _add_result(std::move(s),
results_);
5319 for(
auto &str : s) {
5320 _add_result(std::move(str),
results_);
5330 _validate_results(res);
5334 _reduce_results(extra, res);
5335 if(!extra.empty()) {
5336 res = std::move(extra);
5344 if(option_type_size < 0) {
5363 if(option_type_size_min < 0 || option_type_size_max < 0) {
5366 option_type_size_min = (
std::abs)(option_type_size_min);
5367 option_type_size_max = (
std::abs)(option_type_size_max);
5370 if(option_type_size_min > option_type_size_max) {
5391 if(!vtype.empty()) {
5392 full_type_name +=
":" + vtype;
5396 return full_type_name;
5416 if(!err_msg.empty())
5428 auto err_msg = _validate(
result, index);
5430 if(!err_msg.empty())
5449 std::size_t trim_size = std::min<std::size_t>(
5451 if(original.size() != trim_size) {
5452 out.assign(original.end() -
static_cast<results_t::difference_type
>(trim_size), original.end());
5456 std::size_t trim_size = std::min<std::size_t>(
5458 if(original.size() != trim_size) {
5459 out.assign(original.begin(), original.begin() +
static_cast<results_t::difference_type
>(trim_size));
5468 out.push_back(detail::sum_string_vector(original));
5480 if(original.size() < num_min) {
5481 throw ArgumentMismatch::AtLeast(
get_name(), static_cast<int>(num_min), original.size());
5483 if(original.size() > num_max) {
5484 throw ArgumentMismatch::AtMost(
get_name(), static_cast<int>(num_max), original.size());
5493 out.push_back(
"{}");
5494 out.push_back(
"%%");
5497 out.push_back(
"%%");
5508 auto v = vali.get_application_index();
5509 if(
v == -1 ||
v == index) {
5511 err_msg = vali(result);
5513 err_msg = err.what();
5515 if(!err_msg.empty())
5524 int result_count = 0;
5526 result.back() ==
']') {
5531 result_count += _add_result(std::move(var), res);
5534 return result_count;
5537 res.push_back(std::move(result));
5540 if((result.find_first_of(
delimiter_) != std::string::npos)) {
5548 res.push_back(std::move(result));
5552 return result_count;
5558 #define CLI11_PARSE(app, argc, argv) \
5560 (app).parse((argc), (argv)); \
5561 } catch(const CLI::ParseError &e) { \
5562 return (app).exit(e); \
5571 namespace FailureMessage {
5695 using missing_t = std::vector<std::pair<detail::Classifier, std::string>>;
5813 :
App(app_description, app_name, nullptr) {
5814 set_help_flag(
"-h,--help",
"Print this help message and exit");
5817 App(
const App &) =
delete;
5821 virtual ~App() =
default;
5982 formatter_ = std::make_shared<FormatterLambda>(fmt);
6019 bool defaulted =
false,
6023 template <
typename AssignTo,
6024 typename ConvertTo = AssignTo,
6031 return detail::lexical_conversion<AssignTo, ConvertTo>(res, variable);
6034 Option *opt =
add_option(option_name, fun, option_description,
false, [&variable]() {
6035 return CLI::detail::checked_to_string<AssignTo, ConvertTo>(variable);
6037 opt->
type_name(detail::type_name<ConvertTo>());
6055 return detail::lexical_conversion<AssignTo, AssignTo>(res, variable);
6059 opt->
type_name(detail::type_name<AssignTo>());
6067 template <
typename ArgType>
6074 bool result = detail::lexical_conversion<ArgType, ArgType>(res, variable);
6081 Option *opt =
add_option(option_name, std::move(fun), option_description,
false);
6082 opt->
type_name(detail::type_name<ArgType>());
6094 template <
typename T,
6110 const std::string &version_help =
"Display program version information and exit");
6115 const std::string &version_help =
"Display program version information and exit");
6128 template <
typename T,
6132 return _add_flag_internal(flag_name,
CLI::callback_t(), flag_description);
6137 template <
typename T,
6139 !std::is_constructible<std::function<void(int)>,
T>
::value,
6148 auto *opt = _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
6149 return detail::default_flag_modifiers<T>(opt);
6153 template <
typename T,
6157 std::vector<T> &flag_results,
6161 for(
const auto &elem : res) {
6162 flag_results.emplace_back();
6167 return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
6174 std::function<
void(
void)>
function,
6179 std::function<
void(std::int64_t)>
function,
6185 std::function<
void(std::int64_t)>
function,
6187 return add_flag_function(std::move(flag_name), std::move(
function), std::move(flag_description));
6194 const std::string &help_message =
"Read an ini file",
6195 bool config_required =
false);
6201 template <
typename T = Option_group>
6206 auto option_group = std::make_shared<T>(std::move(group_description), group_name,
this);
6207 auto *
ptr = option_group.get();
6209 App_p app_ptr = std::dynamic_pointer_cast<
App>(option_group);
6331 explicit operator bool()
const {
return parsed_ > 0; }
6351 void parse(
int argc,
const char *
const *argv);
6361 void parse(std::vector<std::string> &
args);
6364 void parse(std::vector<std::string> &&
args);
6374 int exit(
const Error &e, std::ostream &out = std::cout, std::ostream &err = std::cerr)
const;
6408 if(opt ==
nullptr) {
6417 if(app ==
nullptr) {
6432 if(opt ==
nullptr) {
6440 if(app ==
nullptr) {
6467 footer_ = std::move(footer_string);
6500 #if CLI11_USE_STATIC_RTTI == 0
6520 std::vector<Option *>
get_options(
const std::function<
bool(Option *)>
filter = {});
6531 if(opt ==
nullptr) {
6540 if(opt ==
nullptr) {
6696 void run_callback(
bool final_mode =
false,
bool suppress_final_callback =
false);
6703 bool ignore_used_subcommands =
true)
const;
6741 void _parse(std::vector<std::string> &&
args);
6806 :
App(std::move(group_description),
"", parent) {
6830 subc->get_parent()->remove_subcommand(subcom);
6875 namespace FailureMessage {
6891 template <
typename... Args>
static decltype(
auto)
parse_arg(
App *app, Args &&...
args) {
6901 template <
typename... Args>
6908 template <
typename... Args>
6923 : name_(std::move(app_name)), description_(std::move(app_description)), parent_(parent) {
6981 throw(
OptionAlreadyAdded(
"alias already matches an existing subcommand: " + app_name));
7007 if(!match.empty()) {
7009 throw OptionAlreadyAdded(
"ignore case would cause subcommand name conflicts: " + match);
7021 if(!match.empty()) {
7023 throw OptionAlreadyAdded(
"ignore underscore would cause subcommand name conflicts: " + match);
7035 Option myopt{option_name, option_description, option_callback,
this};
7041 option.reset(
new Option(option_name, option_description, option_callback,
this));
7044 option->default_function(
func);
7048 option->capture_default_str();
7054 if(!defaulted && option->get_always_capture_default())
7055 option->capture_default_str();
7057 return option.get();
7061 const auto &matchname = opt->matching_name(myopt);
7062 if(!matchname.empty()) {
7063 throw(
OptionAlreadyAdded(
"added option matched existing option name: " + matchname));
7078 if(!flag_name.empty()) {
7094 if(!help_name.empty()) {
7111 if(!flag_name.empty()) {
7113 flag_name, [versionString]() {
throw(
CLI::CallForVersion(versionString, 0)); }, version_help);
7128 if(!flag_name.empty()) {
7143 opt =
add_option(std::move(flag_name), std::move(fun), std::move(flag_description),
false);
7144 for(
const auto &fname : flag_defaults)
7145 opt->
fnames_.push_back(fname.first);
7148 opt =
add_option(std::move(flag_name), std::move(fun), std::move(flag_description),
false);
7152 auto pos_name = opt->
get_name(
true);
7154 throw IncorrectConstruction::PositionalFlag(pos_name);
7163 std::function<
void(
void)>
function,
7167 bool trigger{
false};
7169 if(result && trigger) {
7174 return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description));
7179 std::function<
void(std::int64_t)>
function,
7183 std::int64_t flag_count{0};
7185 function(flag_count);
7188 return _add_flag_internal(flag_name, std::move(fun), std::move(flag_description))
7195 bool config_required) {
7204 if(!option_name.empty()) {
7206 if(config_required) {
7209 if(!default_filename.empty()) {
7221 op->remove_needs(opt);
7222 op->remove_excludes(opt);
7232 if(iterator !=
std::end(options_)) {
7233 options_.erase(iterator);
7242 throw IncorrectConstruction(
"Subcommand name starts with invalid character, '!' and '-' are not allowed");
7244 for(
auto c : subcommand_name) {
7247 "'), all characters are allowed except"
7248 "'=',':','{','}', and ' '");
7252 CLI::App_p subcom = std::shared_ptr<App>(
new App(std::move(subcommand_description), subcommand_name,
this));
7261 if(!mstrg.empty()) {
7262 throw(
OptionAlreadyAdded(
"subcommand name or alias matches existing subcommand: " + mstrg));
7264 subcom->parent_ =
this;
7272 sub->remove_excludes(subcom);
7273 sub->remove_needs(subcom);
7276 auto iterator = std::find_if(
7278 if(iterator !=
std::end(subcommands_)) {
7279 subcommands_.erase(iterator);
7286 if(subcom ==
nullptr)
7289 if(subcomptr.get() == subcom)
7290 return subcomptr.get();
7303 auto uindex =
static_cast<unsigned>(index);
7311 if(subcom ==
nullptr)
7314 if(subcomptr.get() == subcom)
7321 if(subcomptr->check_name(subcom))
7328 auto uindex =
static_cast<unsigned>(index);
7337 if(app->name_.empty() && app->group_ == group_name) {
7347 cnt += opt->
count();
7350 cnt +=
sub->count_all();
7380 std::vector<std::string>
args;
7381 args.reserve(static_cast<std::size_t>(argc) - 1U);
7382 for(
auto i = static_cast<std::size_t>(argc) - 1U; i > 0U; --i)
7383 args.emplace_back(argv[i]);
7384 parse(std::move(args));
7389 if(program_name_included) {
7395 commandline = std::move(nstr.second);
7400 if(!commandline.empty()) {
7469 if(e.
get_name() ==
"CallForHelp") {
7474 if(e.
get_name() ==
"CallForAllHelp") {
7479 if(e.
get_name() ==
"CallForVersion") {
7480 out << e.what() << std::endl;
7493 std::vector<const App *> subcomms(
subcommands_.size());
7498 subcomms.erase(std::remove_if(
std::begin(subcomms),
7535 auto *other_app = *iterator;
7537 other_app->remove_excludes(
this);
7567 if(!selected_subcommands.empty()) {
7568 return selected_subcommands.at(0)->help(prev, mode);
7570 return formatter_->make_help(
this, prev, mode);
7591 std::vector<const Option *> options(
options_.size());
7596 options.erase(std::remove_if(
std::begin(options),
7606 std::vector<Option *> options(
options_.size());
7625 for(
auto &subc : subcommands_) {
7627 if(subc->get_name().empty()) {
7628 auto *opt = subc->get_option_no_throw(option_name);
7629 if(opt !=
nullptr) {
7638 for(
const Option_p &opt : options_) {
7643 for(
const auto &subc : subcommands_) {
7645 if(subc->get_name().empty()) {
7646 auto *opt = subc->get_option_no_throw(option_name);
7647 if(opt !=
nullptr) {
7659 if(
aliases_.empty() || !with_aliases) {
7663 for(
const auto &lalias :
aliases_) {
7664 dispname.push_back(
',');
7665 dispname.push_back(
' ');
7666 dispname.append(lalias);
7682 if(local_name == name_to_check) {
7692 if(les == name_to_check) {
7700 std::vector<std::string> groups;
7713 std::vector<std::string> miss_list;
7714 for(
const std::pair<detail::Classifier, std::string> &miss :
missing_) {
7715 miss_list.push_back(std::get<1>(miss));
7721 if(
sub->name_.empty() && !
sub->missing_.empty()) {
7722 for(
const std::pair<detail::Classifier, std::string> &miss :
sub->missing_) {
7723 miss_list.push_back(std::get<1>(miss));
7731 std::vector<std::string> output =
sub->remaining(recurse);
7739 std::vector<std::string> miss_list =
remaining(recurse);
7745 auto remaining_options =
static_cast<std::size_t
>(std::count_if(
7752 remaining_options +=
sub->remaining_size(recurse);
7755 return remaining_options;
7766 opt->get_required();
7768 if(pcount - pcount_req > 1) {
7773 std::size_t nameless_subs{0};
7776 if(app->get_name().empty())
7800 if(app->has_automatic_name_) {
7803 if(app->name_.empty()) {
7804 app->fallthrough_ =
false;
7805 app->prefix_command_ =
false;
7808 app->parent_ =
this;
7821 if(subc->parent_ ==
this) {
7822 subc->run_callback(
true, suppress_final_callback);
7827 if(subc->name_.empty() && subc->count_all() > 0) {
7828 subc->run_callback(
true, suppress_final_callback);
7846 if(
com !=
nullptr) {
7854 bool ignore_used_subcommands)
const {
7864 if(dummy1[0] >=
'0' && dummy1[0] <=
'9') {
7873 if((current ==
"++") && !
name_.empty() &&
parent_ !=
nullptr)
7882 auto config_files =
config_ptr_->
as<std::vector<std::string>>();
7883 if(config_files.empty() || config_files.front().empty()) {
7884 if(config_required) {
7885 throw FileError::Missing(
"no specified config file");
7889 for(
auto rit = config_files.rbegin(); rit != config_files.rend(); ++rit) {
7890 const auto &config_file = *rit;
7900 if(config_required || file_given)
7903 }
else if(config_required || file_given) {
7904 throw FileError::Missing(config_file);
7919 if(_dupenv_s(&buffer, &sz, opt->
envname_.c_str()) == 0 && buffer !=
nullptr) {
7926 if(buffer !=
nullptr)
7930 if(!ename_string.empty()) {
7937 if(
sub->get_name().empty() || !
sub->parse_complete_callback_)
7938 sub->_process_env();
7946 if(
sub->get_name().empty() &&
sub->parse_complete_callback_) {
7947 if(
sub->count_all() > 0) {
7948 sub->_process_callbacks();
7949 sub->run_callback();
7960 if(!
sub->parse_complete_callback_) {
7961 sub->_process_callbacks();
7970 if(help_ptr !=
nullptr && help_ptr->
count() > 0)
7971 trigger_help =
true;
7972 if(help_all_ptr !=
nullptr && help_all_ptr->
count() > 0)
7973 trigger_all_help =
true;
7978 sub->_process_help_flags(trigger_help, trigger_all_help);
7981 }
else if(trigger_all_help) {
7983 }
else if(trigger_help) {
7990 bool excluded{
false};
7993 if(opt->
count() > 0) {
7999 if(subc->count_all() > 0) {
8001 excluder = subc->get_display_name();
8013 bool missing_needed{
false};
8016 if(opt->
count() == 0) {
8017 missing_needed =
true;
8022 if(subc->count_all() == 0) {
8023 missing_needed =
true;
8024 missing_need = subc->get_display_name();
8027 if(missing_needed) {
8035 std::size_t used_options = 0;
8038 if(opt->
count() != 0) {
8047 if(opt->
count() > 0 && opt_req->
count() == 0)
8068 if(
sub->name_.empty() &&
sub->count_all() > 0) {
8078 return ptr->get_name(
false,
true);
8082 if(!subc_list.empty()) {
8092 if(
sub->name_.empty() &&
sub->required_ ==
false) {
8093 if(
sub->count_all() == 0) {
8106 if(
sub->count() > 0 ||
sub->name_.empty()) {
8107 sub->_process_requirements();
8110 if(
sub->required_ &&
sub->count_all() == 0) {
8141 if(num_left_over > 0) {
8147 if(
sub->count() > 0)
8148 sub->_process_extras();
8155 if(num_left_over > 0) {
8162 if(
sub->count() > 0)
8163 sub->_process_extras(args);
8170 if(
sub->get_name().empty())
8171 sub->increment_parsed();
8178 bool positional_only =
false;
8180 while(!args.empty()) {
8208 bool positional_only =
false;
8210 while(!
args.empty()) {
8233 throw ConfigError::Extras(item.fullname());
8238 if(level < item.
parents.size()) {
8249 if(item.
name ==
"++") {
8260 if(item.
name ==
"--") {
8270 if(item.
name.size() == 1) {
8289 throw ConfigError::NotConfigurable(item.
fullname());
8295 if(item.
inputs.size() <= 1) {
8307 throw ConversionError::TooManyInputsFlag(item.
fullname());
8320 switch(classifier) {
8323 positional_only =
true;
8348 positional_only =
true;
8353 throw HorribleError(
"unrecognized classifier (you should not see this!)");
8360 std::size_t retval = 0;
8387 auto arg_rem = args.size();
8389 if(arg_rem <= remreq) {
8395 pos = opt->_validate(pos, 0);
8429 pos = opt->_validate(pos, 0);
8453 if((subc->name_.empty()) && (!subc->disabled_)) {
8454 if(subc->_parse_positional(args,
false)) {
8455 if(!subc->pre_parse_called_) {
8456 subc->_trigger_pre_parse(args.size());
8469 if(haltOnSubcommand) {
8479 com = parent_app->_find_subcommand(args.back(),
true,
false);
8480 if(
com !=
nullptr && (
com->parent_->require_subcommand_max_ == 0 ||
8481 com->parent_->require_subcommand_max_ >
com->parent_->parsed_subcommands_.size())) {
8496 while(!args.empty()) {
8507 for(
const App_p &
com : subcommands_) {
8508 if(
com->disabled_ && ignore_disabled)
8511 auto *subc =
com->_find_subcommand(subc_name, ignore_disabled, ignore_used);
8512 if(subc !=
nullptr) {
8516 if(
com->check_name(subc_name)) {
8517 if((!*
com) || !ignore_used)
8530 if(
com !=
nullptr) {
8536 auto *parent_app =
com->parent_;
8537 while(parent_app !=
this) {
8538 parent_app->_trigger_pre_parse(args.size());
8540 parent_app->parsed_subcommands_.push_back(
com);
8542 parent_app = parent_app->parent_;
8548 throw HorribleError(
"Subcommand " + args.back() +
" missing");
8560 switch(current_type) {
8563 throw HorribleError(
"Long parsed but missing (you should not see this):" + args.back());
8567 throw HorribleError(
"Short parsed but missing! You should not see this");
8571 throw HorribleError(
"windows option parsed but missing! You should not see this");
8578 throw HorribleError(
"parsing got called with invalid option! You should not see this");
8583 return opt->check_lname(arg_name);
8585 return opt->check_sname(arg_name);
8587 return opt->check_lname(arg_name) || opt->check_sname(arg_name);
8593 if(subc->name_.empty() && !subc->disabled_) {
8594 if(subc->_parse_arg(args, current_type)) {
8595 if(!subc->pre_parse_called_) {
8596 subc->_trigger_pre_parse(args.size());
8623 if(op->get_inject_separator()) {
8624 if(!op->results().empty() && !op->results().back().empty()) {
8631 int min_num = (
std::min)(op->get_type_size_min(), op->get_items_expected_min());
8632 int max_num = op->get_items_expected_max();
8636 auto tmax = op->get_type_size_max();
8641 int result_count = 0;
8644 auto res = op->get_flag_value(arg_name, value);
8645 op->add_result(res);
8647 }
else if(!value.empty()) {
8648 op->add_result(value, result_count);
8650 collected += result_count;
8652 }
else if(!rest.empty()) {
8653 op->add_result(rest, result_count);
8656 collected += result_count;
8660 while(min_num > collected && !args.empty()) {
8663 op->add_result(current_, result_count);
8665 collected += result_count;
8668 if(min_num > collected) {
8669 throw ArgumentMismatch::TypedAtLeast(op->get_name(), min_num, op->get_type_name());
8673 if(max_num > collected || op->get_allow_extra_args()) {
8676 while((collected < max_num || op->get_allow_extra_args()) && !args.empty() &&
8679 if(remreqpos >= args.size()) {
8684 arg = op->_validate(arg, 0);
8689 op->add_result(args.back(), result_count);
8692 collected += result_count;
8699 if(min_num == 0 && max_num > 0 && collected == 0) {
8700 auto res = op->get_flag_value(arg_name,
std::string{});
8701 op->add_result(res);
8706 if(min_num > 0 && (collected % op->get_type_size_max()) != 0) {
8707 if(op->get_type_size_max() != op->get_type_size_min()) {
8710 throw ArgumentMismatch::PartialType(op->get_name(), op->get_type_size_min(), op->get_type_name());
8713 if(op->get_trigger_on_parse()) {
8718 args.push_back(rest);
8730 if(!
name_.empty()) {
8745 auto *fallthrough_parent =
parent_;
8746 while((fallthrough_parent->parent_ !=
nullptr) && (fallthrough_parent->get_name().empty())) {
8747 fallthrough_parent = fallthrough_parent->
parent_;
8749 return fallthrough_parent;
8753 const App &base)
const {
8759 if(subc.get() != &subcom) {
8760 if(subc->disabled_) {
8764 if(subc->check_name(subcom.
get_name())) {
8768 if(!subc->get_name().empty()) {
8770 return subc->get_name();
8773 for(
const auto &les : subcom.
aliases_) {
8774 if(subc->check_name(les)) {
8779 for(
const auto &les : subc->aliases_) {
8785 if(subc->get_name().empty()) {
8787 if(!cmpres.empty()) {
8794 if(!cmpres.empty()) {
8805 missing_.emplace_back(val_type, val);
8810 if(subc->name_.empty() && subc->allow_extras_) {
8811 subc->missing_.emplace_back(val_type, val);
8816 missing_.emplace_back(val_type, val);
8820 if(opt ==
nullptr) {
8826 if(app == subc.get()) {
8843 const auto &opt_p = *iterator;
8845 return (*v == *opt_p);
8848 app->
options_.push_back(std::move(*iterator));
8865 for(
auto &app : apps_to_enable) {
8866 app->enabled_by_default(
false);
8867 app->disabled_by_default();
8871 for(
const auto &app : apps_to_enable) {
8872 app->disabled(
false);
8884 for(
auto &app : apps_to_enable) {
8885 app->disabled_by_default(
false);
8886 app->enabled_by_default();
8890 for(
const auto &app : apps_to_enable) {
8898 std::cout << opt->
get_name() <<
" is deprecated please use '" << replacement
8903 deprecate_warning.application_index(0);
8904 opt->
check(deprecate_warning);
8905 if(!replacement.empty()) {
8918 auto *opt2 = app->
add_option(option_copy->get_name(
false,
true),
"option has been retired and has no effect")
8920 ->default_str(
"RETIRED")
8921 ->type_size(option_copy->get_type_size_min(), option_copy->get_type_size_max())
8922 ->expected(option_copy->get_expected_min(), option_copy->get_expected_max())
8923 ->allow_extra_args(option_copy->get_allow_extra_args());
8926 std::cout <<
"WARNING " << opt2->
get_name() <<
" is retired and has no effect\n";
8930 retired_warning.application_index(0);
8931 opt2->check(retired_warning);
8939 if(opt !=
nullptr) {
8943 auto *opt2 = app->
add_option(option_name,
"option has been retired and has no effect")
8948 std::cout <<
"WARNING " << opt2->
get_name() <<
" is retired and has no effect\n";
8952 retired_warning.application_index(0);
8953 opt2->check(retired_warning);
8958 namespace FailureMessage {
8962 std::vector<std::string> names;
8973 header +=
"Run with " +
detail::join(names,
" or ") +
" for more information.\n";
8980 header += app->
help();
8996 char arrayStart =
'[',
8997 char arrayEnd =
']',
8998 char stringQuote =
'"',
8999 char characterQuote =
'\'');
9017 if(arg ==
"true" || arg ==
"false" || arg ==
"nan" || arg ==
"inf") {
9021 if(arg.compare(0, 2,
"0x") != 0 && arg.compare(0, 2,
"0X") != 0) {
9028 if(arg.size() == 1) {
9029 return std::string(1, characterQuote) + arg + characterQuote;
9032 if(arg.front() ==
'0') {
9034 if(std::all_of(arg.begin() + 2, arg.end(), [](
char x) {
9039 }
else if(arg[1] ==
'o') {
9040 if(std::all_of(arg.begin() + 2, arg.end(), [](
char x) {
return (
x >=
'0' &&
x <=
'7'); })) {
9043 }
else if(arg[1] ==
'b') {
9044 if(std::all_of(arg.begin() + 2, arg.end(), [](
char x) {
return (
x ==
'0' ||
x ==
'1'); })) {
9049 if(arg.find_first_of(stringQuote) == std::string::npos) {
9050 return std::string(1, stringQuote) + arg + stringQuote;
9052 return characterQuote + arg + characterQuote;
9060 char characterQuote) {
9062 if(args.size() > 1 && arrayStart !=
'\0') {
9063 joined.push_back(arrayStart);
9065 std::size_t
start = 0;
9066 for(
const auto &arg : args) {
9068 joined.push_back(sepChar);
9069 if(!std::isspace<char>(sepChar, std::locale())) {
9070 joined.push_back(
' ');
9075 if(args.size() > 1 && arrayEnd !=
'\0') {
9076 joined.push_back(arrayEnd);
9083 std::vector<std::string> parents;
9085 if(section.find(parentSeparator) != std::string::npos) {
9088 parents = {section};
9091 if(name.find(parentSeparator) != std::string::npos) {
9092 std::vector<std::string> plist =
detail::split(name, parentSeparator);
9093 name = plist.back();
9096 parents.insert(parents.end(), plist.begin(), plist.end());
9100 for(
auto &parent : parents) {
9111 if(!output.empty() && output.back().name ==
"--") {
9112 std::size_t msize = (parents.size() > 1U) ? parents.size() : 2;
9113 while(output.back().parents.size() >= msize) {
9114 output.push_back(output.back());
9115 output.back().parents.pop_back();
9118 if(parents.size() > 1) {
9119 std::size_t common = 0;
9120 std::size_t mpair = (
std::min)(output.back().parents.size(), parents.size() - 1);
9121 for(std::size_t ii = 0; ii < mpair; ++ii) {
9122 if(output.back().parents[ii] != parents[ii]) {
9127 if(common == mpair) {
9130 while(output.back().parents.size() > common + 1) {
9131 output.push_back(output.back());
9132 output.back().parents.pop_back();
9135 for(std::size_t ii = common; ii < parents.size() - 1; ++ii) {
9136 output.emplace_back();
9137 output.back().parents.assign(parents.begin(), parents.begin() +
static_cast<std::ptrdiff_t
>(ii) + 1);
9138 output.back().name =
"++";
9141 }
else if(parents.size() > 1) {
9142 for(std::size_t ii = 0; ii < parents.size() - 1; ++ii) {
9143 output.emplace_back();
9144 output.back().parents.assign(parents.begin(), parents.begin() +
static_cast<std::ptrdiff_t
>(ii) + 1);
9145 output.back().name =
"++";
9150 output.emplace_back();
9151 output.back().parents = std::move(parents);
9152 output.back().name =
"++";
9160 std::vector<ConfigItem> output;
9163 bool inSection{
false};
9164 char aStart = (isINIArray) ?
'[' :
arrayStart;
9165 char aEnd = (isINIArray) ?
']' :
arrayEnd;
9166 char aSep = (isINIArray &&
arraySeparator ==
' ') ?
',' : arraySeparator;
9167 int currentSectionIndex{0};
9168 while(getline(input, line)) {
9169 std::vector<std::string> items_buffer;
9173 std::size_t len = line.length();
9178 if(line.front() ==
'[' && line.back() ==
']') {
9179 if(currentSection !=
"default") {
9181 output.emplace_back();
9183 output.back().name =
"--";
9185 currentSection = line.substr(1, len - 2);
9187 if(currentSection.size() > 1 && currentSection.front() ==
'[' && currentSection.back() ==
']') {
9188 currentSection = currentSection.substr(1, currentSection.size() - 2);
9191 currentSection =
"default";
9196 if(currentSection == previousSection) {
9197 ++currentSectionIndex;
9199 currentSectionIndex = 0;
9200 previousSection = currentSection;
9206 if(line.front() ==
';' || line.front() ==
'#' || line.front() ==
commentChar) {
9212 if(pos != std::string::npos) {
9216 if(cloc != std::string::npos) {
9217 item.erase(cloc, std::string::npos);
9220 if(item.size() > 1 && item.front() == aStart) {
9221 for(
std::string multiline; item.back() != aEnd && std::getline(input, multiline);) {
9226 }
else if((isDefaultArray || isINIArray) && item.find_first_of(aSep) != std::string::npos) {
9228 }
else if((isDefaultArray || isINIArray) && item.find_first_of(
' ') != std::string::npos) {
9231 items_buffer = {item};
9236 if(cloc != std::string::npos) {
9237 name.erase(cloc, std::string::npos);
9241 items_buffer = {
"true"};
9247 for(
auto &it : items_buffer) {
9262 parents.erase(parents.begin());
9265 if(!output.empty() && name == output.back().name && parents == output.back().parents) {
9266 output.back().inputs.insert(output.back().inputs.end(), items_buffer.begin(), items_buffer.end());
9268 output.emplace_back();
9269 output.back().parents = std::move(parents);
9270 output.back().name = std::move(name);
9271 output.back().inputs = std::move(items_buffer);
9274 if(currentSection !=
"default") {
9277 output.emplace_back();
9279 output.back().name =
"--";
9280 while(output.back().parents.size() > 1) {
9281 output.push_back(output.back());
9282 output.back().parents.pop_back();
9290 std::stringstream out;
9293 commentLead.push_back(
' ');
9295 std::vector<std::string> groups = app->
get_groups();
9296 bool defaultUsed =
false;
9297 groups.insert(groups.begin(),
std::string(
"Options"));
9301 for(
auto &group : groups) {
9302 if(group ==
"Options" || group.empty()) {
9308 if(write_description && group !=
"Options" && !group.empty()) {
9309 out <<
'\n' << commentLead << group <<
" Options\n";
9316 if(!(group ==
"Options" && opt->
get_group().empty())) {
9324 if(value.empty() && default_also) {
9334 if(!value.empty()) {
9347 auto subcommands = app->get_subcommands({});
9348 for(
const App *subcom : subcommands) {
9349 if(subcom->get_name().empty()) {
9350 if(write_description && !subcom->get_group().empty()) {
9351 out <<
'\n' << commentLead << subcom->get_group() <<
" Options\n";
9353 out << to_config(subcom, default_also, write_description, prefix);
9357 for(
const App *subcom : subcommands) {
9358 if(!subcom->get_name().empty()) {
9359 if(subcom->get_configurable() && app->got_subcommand(subcom)) {
9360 if(!prefix.empty() || app->get_parent() ==
nullptr) {
9361 out <<
'[' << prefix << subcom->get_name() <<
"]\n";
9363 std::string subname = app->get_name() + parentSeparatorChar + subcom->get_name();
9364 const auto *p = app->get_parent();
9365 while(p->get_parent() !=
nullptr) {
9366 subname = p->get_name() + parentSeparatorChar + subname;
9367 p = p->get_parent();
9369 out <<
'[' << subname <<
"]\n";
9371 out << to_config(subcom, default_also, write_description,
"");
9374 subcom, default_also, write_description, prefix + subcom->get_name() + parentSeparatorChar);
9389 std::stringstream out;
9391 out <<
"\n" << group <<
":\n";
9392 for(
const Option *opt : opts) {
9400 std::vector<const Option *> opts =
9410 std::stringstream out;
9411 std::vector<std::string> groups = app->
get_groups();
9415 std::vector<const Option *> opts = app->
get_options([app, mode, &group](
const Option *opt) {
9422 if(!group.empty() && !opts.empty()) {
9425 if(group != groups.back())
9438 desc +=
" REQUIRED ";
9440 if((max_options == min_options) && (min_options > 0)) {
9441 if(min_options == 1) {
9442 desc +=
" \n[Exactly 1 of the following options is required]";
9444 desc +=
" \n[Exactly " +
std::to_string(min_options) +
"options from the following list are required]";
9446 }
else if(max_options > 0) {
9447 if(min_options > 0) {
9449 " of the follow options are required]";
9451 desc +=
" \n[At most " +
std::to_string(max_options) +
" of the following options are allowed]";
9453 }
else if(min_options > 0) {
9454 desc +=
" \n[At least " +
std::to_string(min_options) +
" of the following options are required]";
9456 return (!desc.empty()) ? desc +
"\n" :
std::string{};
9460 std::stringstream out;
9462 out <<
get_label(
"Usage") <<
":" << (name.empty() ?
"" :
" ") << name;
9464 std::vector<std::string> groups = app->
get_groups();
9467 std::vector<const Option *> non_pos_options =
9469 if(!non_pos_options.empty())
9470 out <<
" [" <<
get_label(
"OPTIONS") <<
"]";
9476 if(!positionals.empty()) {
9478 std::vector<std::string> positional_names(positionals.size());
9479 std::transform(positionals.begin(), positionals.end(), positional_names.begin(), [
this](
const Option *opt) {
9490 out <<
" " << (app->get_require_subcommand_min() == 0 ?
"[" :
"")
9491 << get_label(app->get_require_subcommand_max() < 2 || app->get_require_subcommand_min() > 1 ?
"SUBCOMMAND"
9493 << (app->get_require_subcommand_min() == 0 ?
"]" :
"");
9503 if(footer.empty()) {
9506 return "\n" + footer +
"\n";
9513 if(mode == AppFormatMode::Sub)
9514 return make_expanded(app);
9516 std::stringstream out;
9523 out << make_description(app);
9524 out << make_usage(app, name);
9525 out << make_positionals(app);
9526 out << make_groups(app, mode);
9527 out << make_subcommands(app, mode);
9528 out << make_footer(app);
9534 std::stringstream out;
9539 std::vector<std::string> subcmd_groups_seen;
9540 for(
const App *
com : subcommands) {
9543 out << make_expanded(
com);
9548 if(!group_key.empty() &&
9549 std::find_if(subcmd_groups_seen.begin(), subcmd_groups_seen.end(), [&group_key](
std::string a) {
9551 }) == subcmd_groups_seen.end())
9552 subcmd_groups_seen.push_back(group_key);
9556 for(
const std::string &group : subcmd_groups_seen) {
9557 out <<
"\n" << group <<
":\n";
9560 for(
const App *new_com : subcommands_group) {
9561 if(new_com->get_name().empty())
9563 if(mode != AppFormatMode::All) {
9564 out << make_subcommand(new_com);
9566 out << new_com->help(new_com->get_name(), AppFormatMode::Sub);
9576 std::stringstream out;
9582 std::stringstream out;
9585 out << make_description(sub);
9589 out << make_positionals(sub);
9590 out << make_groups(sub, AppFormatMode::Sub);
9591 out << make_subcommands(sub, AppFormatMode::Sub);
9595 tmp = tmp.substr(0, tmp.size() - 1);
9609 std::stringstream out;
9625 out <<
" " << get_label(
"REQUIRED");
9628 out <<
" (" << get_label(
"Env") <<
":" << opt->
get_envname() <<
")";
9630 out <<
" " << get_label(
"Needs") <<
":";
9632 out <<
" " << op->get_name();
9635 out <<
" " << get_label(
"Excludes") <<
":";
9637 out <<
" " << op->get_name();
9647 std::stringstream out;
9648 out << make_option_name(opt,
true);
9654 return opt->
get_required() ? out.str() :
"[" + out.str() +
"]";
CLI11_NODISCARD int get_type_size_min() const
The minimum number of arguments the option expects.
Anything that can error in Parse.
App * footer(std::function< std::string()> footer_function)
Set footer.
void copy_to(T *other) const
Copy the contents to another similar class (one based on OptionBase)
CLI11_NODISCARD bool get_validate_optional_arguments() const
Get the status of validating optional vector arguments.
Option(std::string option_name, std::string option_description, callback_t callback, App *parent)
Making an option by hand is not defined, it must be made by the App class.
CLI11_INLINE std::string fix_newlines(const std::string &leader, std::string input)
App * allow_config_extras(bool allow=true)
ignore extras in config files
App * validate_positionals(bool validate=true)
Set the subcommand to validate positional arguments before assigning.
void clear()
Clear the parsed results (mostly for testing)
void _process_requirements()
Verify required options and cross requirements. Subcommands too (only if selected).
CLI11_NODISCARD std::string help(std::string prev="", AppFormatMode mode=AppFormatMode::Normal) const
Option * envname(std::string name)
Sets environment variable to read if no option given.
Check for an existing path.
std::string simple(const App *app, const Error &e)
Printout a clean, simple message on error (the default in CLI11 1.5+)
void results(T &output) const
Get the results as a specified type.
App * excludes(Option *opt)
Sets excluded options for the subcommand.
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
the results have been validated
std::vector< std::pair< detail::Classifier, std::string >> missing_t
std::string ignore_case(std::string item)
Helper function to allow ignore_case to be passed to IsMember or Transform.
std::string find_and_modify(std::string str, std::string trigger, Callable modify)
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
CLI11_NODISCARD bool get_configurable() const
The status of configurable.
static auto parse_arg(App *app, Args &&...args) -> typename std::result_of< decltype(&App::_parse_arg)(App, Args...)>::type
Wrap _parse_short, perfectly forward arguments and return.
App * disabled_by_default(bool disable=true)
Set the subcommand to be disabled by default, so on clear(), at the start of each parse it is disable...
bool from_stream(const std::string &istring, T &obj)
Templated operation to get a value from a stream.
path_type
CLI enumeration of different file types.
CLI11_NODISCARD const std::vector< std::string > & get_fnames() const
Get the flag names with specified default values.
Error(std::string name, std::string msg, ExitCodes exit_code)
cvex test(vector P=0;int unbound=3;export float s=0;export vector Cf=0;)
CLI11_NODISCARD bool get_ignore_underscore() const
Check the status of ignore_underscore.
CRTP * take_all()
Set the multi option policy to take all arguments.
std::vector< std::pair< std::string, std::string > > default_flag_values_
CLI11_INLINE bool split_long(const std::string ¤t, std::string &name, std::string &value)
App * preparse_callback(std::function< void(std::size_t)> pp_callback)
GT_API const UT_StringHolder filename
Thrown when validation of results fails.
CLI11_NODISCARD const App * get_parent() const
Get the parent of this subcommand (or nullptr if main app) (const version)
void run_callback()
Process the callback.
OptionDefaults * option_defaults()
Get the OptionDefault object, to set option defaults.
This class is simply to allow tests access to App's protected functions.
CLI11_NODISCARD bool get_validate_positionals() const
Get the status of validating positionals.
std::string envname_
If given, check the environment for this option.
Option * description(std::string option_description)
Set the description.
CLI11_NODISCARD results_t reduced_results() const
Get a copy of the results.
bool _parse_positional(std::vector< std::string > &args, bool haltOnSubcommand)
constexpr std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size()
0 if the index > tuple size
Option * add_option(std::string option_name)
Add option with no description or variable assignment.
CLI11_NODISCARD int get_items_expected_min() const
The total min number of expected string values to be used.
bool _parse_single_config(const ConfigItem &item, std::size_t level=0)
Fill in a single config option.
std::string group_
The group membership INHERITABLE.
std::vector< std::string > parents
This is the list of parents.
CLI11_INLINE bool valid_name_string(const std::string &str)
Verify an option/subcommand name.
Option * add_flag_callback(std::string flag_name, std::function< void(void)> function, std::string flag_description="")
Add option for callback that is triggered with a true flag and takes no arguments.
CLI11_NODISCARD App * _find_subcommand(const std::string &subc_name, bool ignore_disabled, bool ignore_used) const noexcept
CLI11_NODISCARD bool get_allow_windows_style_options() const
Check the status of the allow windows style options.
std::vector< std::string > snames_
A list of the short names (-a) without the leading dashes.
CLI11_INLINE std::string & remove_quotes(std::string &str)
remove quotes at the front and back of a string either '"' or '\''
void add_options(Option *opt)
Add an existing option to the Option_group.
char commentChar
the character used for comments
CLI11_NODISCARD Validator application_index(int app_index) const
Specify the application index of a validator.
CLI11_NODISCARD int get_type_size() const
The number of arguments the option expects.
Option * add_flag_function(std::string flag_name, std::function< void(std::int64_t)> function, std::string flag_description="")
Add option for callback with an integer value.
std::set< Option * > exclude_options_
CLI11_NODISCARD char get_delimiter() const
Get the current delimiter char.
Option * add_option(Option *opt)
Add an existing option to the Option_group.
OIIO_NAMESPACE_BEGIN typedef std::ifstream ifstream
CLI11_NODISCARD std::size_t get_require_option_max() const
Get the required max option value.
std::string remove_underscore(std::string str)
remove underscores from a string
CLI11_NODISCARD App * get_option_group(std::string group_name) const
Check to see if an option group is part of this App.
Option * config_ptr_
Pointer to the config option.
Error(std::string name, std::string msg, int exit_code=static_cast< int >(ExitCodes::BaseClass))
CLI11_NODISCARD std::string get_default_str() const
The default value (for help printing)
the callback has been executed
CLI11_INLINE std::vector< std::string > split(const std::string &s, char delim)
Split a string by a delim.
Option * add_option(std::string option_name, AssignTo &variable, std::string option_description="")
Add option for assigning to a variable.
PUGI__FN const char_t * local_name(const xpath_node &node)
CLI11_NODISCARD config_extras_mode get_allow_config_extras() const
Get the status of allow extras.
std::set< Option * > excludes_
A list of options that are excluded with this option.
App * require_subcommand(int value)
CRTP * always_capture_default(bool value=true)
CLI11_NODISCARD const std::string & _compare_subcommand_names(const App &subcom, const App &base) const
Helper function to run through all possible comparisons of subcommand names to check there is no over...
std::shared_ptr< App > App_p
std::function< std::string()> desc_function_
This is the description function, if empty the description_ will be used.
CLI11_NODISCARD const std::string & get_name() const
Get the name of the current app.
bool remove_option(Option *opt)
Removes an option from the App. Takes an option pointer. Returns true if found and removed...
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
This will only trigger for actual void type.
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
Option * option_text(std::string text)
The number of arguments the option expects.
Check for an existing file (returns error message if check fails)
OIIO_UTIL_API bool remove(string_view path, std::string &err)
std::vector< std::pair< std::string, T >> TransformPairs
definition of the default transformation object
Thrown when parsing an INI file and it is missing.
OptionDefaults option_defaults_
The default values for options, customizable and changeable INHERITABLE.
just get all the passed argument regardless
Option * default_val(const X &val)
option_state
enumeration for the option state machine
GLsizei const GLchar *const * string
App * required(bool require=true)
Remove the error when extras are left over on the command line.
GLsizei const GLfloat * value
option_state current_option_state_
Whether the callback has run (needed for INI parsing)
CLI11_NODISCARD std::size_t get_require_option_min() const
Get the required min option value.
bool operator==(const Option &other) const
If options share any of the same names, they are equal (not counting positional)
bool active_
Enable for Validator to allow it to be disabled if need be.
void _parse_config(const std::vector< ConfigItem > &args)
CLI11_INLINE void deprecate_option(Option *opt, const std::string &replacement="")
Helper function to mark an option as deprecated.
CLI11_NODISCARD bool get_allow_extra_args() const
Get the current value of allow extra args.
results_t results_
complete Results of parsing
Thrown when conversion call back fails, such as when an int fails to coerce to a string.
std::vector< ConfigItem > from_config(std::istream &input) const override
Convert a configuration into an app.
void _process()
Process callbacks and such.
void parse_from_stream(std::istream &input)
bool positionals_at_end_
specify that positional arguments come at the end of the argument sequence not inheritable ...
CLI11_NODISCARD std::size_t count_all() const
bool allow_windows_style_options_
Allow '/' for options for Windows like options. Defaults to true on Windows, false otherwise...
Option * add_result(std::string s)
Puts a result at the end.
Option * set_version_flag(std::string flag_name="", const std::string &versionString="", const std::string &version_help="Display program version information and exit")
Set a version flag and version display string, replace the existing one if present.
CLI11_NODISCARD std::set< Option * > get_excludes() const
The set of options excluded.
Validator & name(std::string validator_name)
Specify the type string.
Check to see if something is bool (fail check by default)
std::vector< const Option * > get_options(const std::function< bool(const Option *)> filter={}) const
Get the list of options (user facing function, so returns raw pointers), has optional filter function...
Thrown when counting a non-existent option.
CRTP * mandatory(bool value=true)
Support Plumbum term.
bool validate_positionals_
If set to true positional options are validated before assigning INHERITABLE.
CLI11_NODISCARD const std::string & get_option_text() const
The number of arguments the option expects.
Thrown when an excludes option is present.
CLI11_NODISCARD std::size_t count() const
CLI11_NODISCARD const std::vector< Option * > & parse_order() const
This gets a vector of pointers with the original parse order.
CRTP * take_last()
Set the multi option policy to take last.
std::shared_ptr< FormatterBase > formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer) ...
CLI11_NODISCARD std::size_t count() const
Count the total number of times an option was passed.
App * require_subcommand(std::size_t min, std::size_t max)
void parse(int argc, const char *const *argv)
CRTP * join(char delim)
Set the multi option policy to join with a specific delimiter.
CLI11_NODISCARD std::string get_envname() const
The environment variable associated to this value.
bool has_default_flag_values(const std::string &flags)
check if the flag definitions has possible false flags
CLI11_NODISCARD const std::vector< std::string > & get_lnames() const
Get the long names.
CLI11_NODISCARD const std::string & get_single_name() const
Get a single name for the option, first of lname, pname, sname, envname.
Option * add_flag(std::string flag_name, T &flag_description)
Validate the input as a particular type.
GLboolean GLboolean GLboolean GLboolean a
CLI11_NODISCARD MultiOptionPolicy get_multi_option_policy() const
The status of the multi option policy.
void reverse(I begin, I end)
CLI11_NODISCARD bool get_disabled() const
Get the status of disabled.
CLI11_NODISCARD std::vector< std::string > remaining_for_passthrough(bool recurse=false) const
This returns the missing options in a form ready for processing by another command line program...
std::string operator()(std::string &str) const
GA_API const UT_StringHolder com
std::uint32_t parsed_
Counts the number of times this command/subcommand was parsed.
Validator & description(std::string validator_desc)
Specify the type string.
CLI11_NODISCARD const std::vector< std::string > & get_aliases() const
Get the aliases of the current app.
bool has_automatic_name_
If set to true the name was automatically generated from the command line vs a user set name...
CLI11_NODISCARD const Option * get_version_ptr() const
Get a pointer to the version option. (const)
CLI11_NODISCARD std::set< Option * > get_needs() const
The set of options needed.
bool valid_later_char(T c)
Verify following characters of an option.
Option * disable_flag_override(bool value=true)
Disable flag overrides values, e.g. –flag=is not allowed.
std::string name
This is the name.
enabler
Simple empty scoped class.
App * clear_aliases()
clear all the aliases of the current App
CLI11_NODISCARD bool get_trigger_on_parse() const
The status of trigger on parse.
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
std::function< std::string()> footer_callback_
This is a function that generates a footer to put after all other options in help output...
CLI11_NODISCARD bool get_ignore_case() const
The status of ignore case.
App * immediate_callback(bool immediate=true)
Set the subcommand callback to be executed immediately on subcommand completion.
FileOnDefaultPath(std::string default_path, bool enableErrorReturn=true)
Option * default_function(const std::function< std::string()> &func)
Set a capture function for the default. Mostly used by App.
typename std::enable_if< B, T >::type enable_if_t
App * configurable(bool value=true)
Specify that the subcommand can be triggered by a config file.
App * add_subcommand(App *subcom)
Add an existing subcommand to be a member of an option_group.
CLI11_INLINE std::vector< std::string > split_up(std::string str, char delimiter= '\0')
bool flag_like_
Specify that the option should act like a flag vs regular option.
ExistingDirectoryValidator()
std::string to_string(T &&value)
Convert an object to a string (streaming must be supported for that type)
CLI11_NODISCARD bool get_required() const
Get the status of required.
Thrown when an option is set to conflicting values (non-vector and multi args, for example) ...
Set of overloads to get the type size of an object.
App * final_callback(std::function< void()> app_callback)
bool inject_separator_
flag indicating a separator needs to be injected after each argument call
ConfigBase * maxLayers(uint8_t layers)
Specify the maximum number of parents.
**But if you need a result
std::vector< std::string > generate_parents(const std::string §ion, std::string &name, char parentSeparator)
Option * allow_extra_args(bool value=true)
CLI11_NODISCARD std::size_t get_require_subcommand_max() const
Get the required max subcommand value.
Bound(T max_val)
Range of one value is 0 to value.
void _move_option(Option *opt, App *app)
function that could be used by subclasses of App to shift options around into subcommands ...
const detail::IPV4Validator ValidIPV4
Check for an IP4 address.
OptionDefaults * delimiter(char value= '\0')
set a delimiter character to split up single arguments to treat as multiple inputs ...
GLfloat GLfloat GLfloat v2
int expected_min_
The minimum number of expected values.
CRTP * take_first()
Set the multi option policy to take last.
T * add_option_group(std::string group_name, std::string group_description="")
creates an option group as part of the given app
CLI11_INLINE std::string & add_quotes_if_needed(std::string &str)
Add quotes if the string contains spaces.
bool disabled_
If set to true the subcommand is disabled and cannot be used, ignored for main app.
Check for input streamability.
bool configurable_
Allow this option to be given in a configuration file.
const detail::NonexistentPathValidator NonexistentPath
Check for an non-existing path.
const Range PositiveNumber((std::numeric_limits< double >::min)(),(std::numeric_limits< double >::max)(),"POSITIVE")
Check for a positive valued number (val>0.0), <double>::min here is the smallest positive number...
CLI11_NODISCARD std::string get_flag_value(const std::string &name, std::string input_value) const
Option * get_config_ptr()
Get a pointer to the config option.
Option * excludes(std::string opt_name)
Can find a string if needed.
std::string help(const App *app, const Error &e)
Printout the full help string on error (if this fn is set, the old default for CLI11) ...
std::vector< std::string > results_t
const detail::ExistingFileValidator ExistingFile
Check for existing file (returns error message if check fails)
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
void run_callback(bool final_mode=false, bool suppress_final_callback=false)
Internal function to run (App) callback, bottom up.
const Option * operator[](const char *option_name) const
Shortcut bracket operator for getting a pointer to an option.
ConfigBase * index(int16_t sectionIndex)
specify a particular index in the section to use (-1) for all sections to use
std::string & trim(std::string &str)
Trim whitespace from string.
CLI11_INLINE std::ostream & format_help(std::ostream &out, std::string name, const std::string &description, std::size_t wid)
Print a two part "help" string.
MultiOptionPolicy multi_option_policy_
Policy for handling multiple arguments beyond the expected Max.
App * footer(std::string footer_string)
Set footer.
OptionDefaults * disable_flag_override(bool value=true)
Disable overriding flag values with an '=' segment.
Option * ignore_underscore(bool value=true)
std::function< void()> final_callback_
This is a function that runs when all processing has completed.
bool is_separator(const std::string &str)
check if a string is a container segment separator (empty or "%%")
virtual ~App()=default
virtual destructor
bool remove_needs(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
Option * excludes(Option *opt)
Sets excluded options.
typename T::value_type type
typename T::value_type value_type
std::string trim_copy(const std::string &str)
Make a copy of the string and then trim it.
results_t proc_results_
results after reduction
CLI11_INLINE std::string & ltrim(std::string &str)
Trim whitespace from left of string.
take only the first Expected number of arguments
std::string generate_map(const T &map, bool key_only=false)
Generate a string representation of a map.
CLI11_NODISCARD bool get_required() const
True if this is a required option.
Thrown on construction of a bad name.
CLI11_NODISCARD bool get_immediate_callback() const
Get the status of disabled.
CLI11_NODISCARD const std::vector< std::string > & get_snames() const
Get the short names.
CLI11_INLINE bool split_windows_style(const std::string ¤t, std::string &name, std::string &value)
Thrown when validation fails before parsing.
Option * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times (or another policy)
std::string to_config(const App *, bool default_also, bool write_description, std::string prefix) const override
Convert an app into a configuration.
CLI11_NODISCARD std::string version() const
Displays a version string.
Validator & non_modifying(bool no_modify=true)
Specify whether the Validator can be modifying or not.
This is a successful completion on parsing, supposed to exit.
CLI11_NODISCARD bool get_configurable() const
Check the status of the allow windows style options.
CLI11_NODISCARD std::string get_name(bool positional=false, bool all_options=false) const
Gets a comma separated list of names. Will include / prefer the positional name if positional is true...
Option * trigger_on_parse(bool value=true)
Set the value of trigger_on_parse which specifies that the option callback should be triggered on eve...
CLI11_NODISCARD bool _valid_subcommand(const std::string ¤t, bool ignore_used=true) const
Check to see if a subcommand is valid. Give up immediately if subcommand max has been reached...
CLI11_NODISCARD callback_t get_callback() const
Get the callback function.
CLI11_NODISCARD bool check_lname(std::string name) const
Requires "--" to be removed from string.
bool got_subcommand(const App *subcom) const
Check to see if given subcommand was selected.
Option * get_option(std::string option_name)
Get an option by name (non-const version)
Option * add_option_no_stream(std::string option_name, AssignTo &variable, std::string option_description="")
Add option for assigning to a variable.
CLI11_INLINE std::vector< std::string > split_names(std::string current)
CLI11_NODISCARD std::shared_ptr< FormatterBase > get_formatter() const
Access the formatter.
Option * help_all_ptr_
A pointer to the help all flag if there is one INHERITABLE.
Option * each(const std::function< void(std::string)> &func)
Adds a user supplied function to run on each item passed in (communicate though lambda capture) ...
bool lexical_cast(const std::string &input, T &output)
Integer conversion.
App * needs(App *app)
Counts the number of times the given option was passed.
App * ignore_underscore(bool value=true)
Ignore underscore. Subcommands inherit value.
App * description(std::string app_description)
Set the description of the app.
void inject_separator(bool value=true)
Set the value of the separator injection flag.
AsSizeValue(bool kb_is_1000)
Check for an non-existing path.
bool allow_extras_
If true, allow extra arguments (ie, don't throw an error). INHERITABLE.
bool force_callback_
flag indicating that the option should force the callback regardless if any results present ...
CLI11_INLINE std::size_t escape_detect(std::string &str, std::size_t offset)
typename std::pointer_traits< T >::element_type type
CLI11_NODISCARD bool get_modifying() const
Get a boolean if the validator is allowed to modify the input returns true if it can modify the input...
startup_mode default_startup
auto checked_to_string(T &&value) -> decltype(to_string(std::forward< T >(value)))
special template overload
Option * needs(std::string opt_name)
Can find a string if needed.
bool ignore_underscore_
Ignore underscores when matching (option, not value)
Option * capture_default_str()
Capture the default value from the original value (if it can be captured)
Validator(std::string validator_desc)
Construct a Validator with just the description string.
ConfigBase * comment(char cchar)
Specify the configuration for comment characters.
typename T::value_type value_type
bool fallthrough_
Allow subcommand fallthrough, so that parent commands can collect commands after subcommand. INHERITABLE.
void _process_env()
Get envname options if not yet passed. Runs on all subcommands.
void _process_help_flags(bool trigger_help=false, bool trigger_all_help=false) const
const TypeValidator< double > Number("NUMBER")
Check for a number.
std::string & sectionRef()
get a reference to the configuration section
std::string rjoin(const T &v, std::string delim=",")
Join a string in reverse order.
Option * run_callback_for_default(bool value=true)
std::size_t require_option_min_
Minimum required options (not inheritable!)
ImageBuf OIIO_API sub(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
std::ostream & operator<<(std::ostream &in, const T &item)
output streaming for enumerations
std::string ignore_underscore(std::string item)
Helper function to allow ignore_underscore to be passed to IsMember or Transform. ...
std::function< bool(const results_t &)> callback_t
callback function definition
App * disabled(bool disable=true)
Disable the subcommand or option group.
int exit(const Error &e, std::ostream &out=std::cout, std::ostream &err=std::cerr) const
Print a nice error message and return the exit code.
std::size_t require_subcommand_max_
Max number of subcommands allowed (parsing stops after this number). 0 is unlimited INHERITABLE...
App * alias(std::string app_name)
Set an alias for the app.
CLI11_NODISCARD bool get_enabled_by_default() const
Get the status of disabled by default.
CLI11_NODISCARD bool get_positionals_at_end() const
Check the status of the allow windows style options.
bool integral_conversion(const std::string &input, T &output) noexcept
Convert to an unsigned integral.
App * require_subcommand()
The argumentless form of require subcommand requires 1 or more subcommands.
CLI11_NODISCARD Validator name(std::string validator_name) const
Specify the type string.
std::set< App * > exclude_subcommands_
this is a list of subcommands that are exclusionary to this one
Option * type_name_fn(std::function< std::string()> typefun)
Set the type function to run when displayed on this option.
AsNumberWithUnit::Options operator|(const AsNumberWithUnit::Options &a, const AsNumberWithUnit::Options &b)
definition of the default transformation object
Used when printed as part of expanded subcommand.
std::string option_text_
If given, replace the text that describes the option type and usage in the help text.
Option * default_flag_modifiers(Option *opt)
helper functions for adding in appropriate flag modifiers for add_flag
bool allow_extra_args_
Specify that extra args beyond type_size_max should be allowed.
forward declare the subtype_count_min structure
std::vector< std::string > lnames_
A list of the long names (--long) without the leading dashes.
Check to see if something is a shared pointer.
CLI11_INLINE void TriggerOff(App *trigger_app, App *app_to_enable)
Helper function to disable one option group/subcommand when another is used.
bool trigger_on_result_
flag indicating that the option should trigger the validation and callback chain on each result when ...
Validator & operation(std::function< std::string(std::string &)> op)
Set the Validator operation function.
App * get_subcommand(const App *subcom) const
#define CLI11_ERROR_SIMPLE(name)
CLI11_NODISCARD const std::string & section() const
get the section
Option * set_config(std::string option_name="", std::string default_filename="", const std::string &help_message="Read an ini file", bool config_required=false)
Set a configuration ini file option, or clear it if no name passed.
std::integral_constant< bool, value > type
const Option * operator[](const std::string &option_name) const
Shortcut bracket operator for getting a pointer to an option.
Option * ignore_case(bool value=true)
std::set< App * > need_subcommands_
Option * get_version_ptr()
Get a pointer to the version option.
Option * transform(Validator Validator, const std::string &Validator_name="")
Adds a transforming Validator with a built in type name.
std::string value_string(const T &value)
get a string as a convertible value for arithmetic types
bool always_capture_default_
Automatically capture default value.
CLI11_INLINE path_type check_path(const char *file) noexcept
get the type of the path from a file name
typename std::remove_const< typename value_type::second_type >::type second_type
std::function< std::string(std::string)> filter_fn_t
bool validate_optional_arguments_
If set to true optional vector arguments are validated before assigning INHERITABLE.
ConfigINI generates a "standard" INI compliant output.
bool prefix_command_
If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE.
char delimiter_
Specify a delimiter character for vector arguments.
template to get the underlying value type if it exists or use a default
CLI11_NODISCARD int get_items_expected() const
The total min number of expected string values to be used.
-h or –help on command line
std::size_t require_option_max_
Max number of options allowed. 0 is unlimited (not inheritable)
CLI11_NODISCARD std::size_t get_require_subcommand_min() const
Get the required min subcommand value.
Construction errors (not in parsing)
void _process_extras()
Throw an error if anything is left over and should not be.
std::string join(const T &v, std::string delim=",")
Simple function to join a string.
CLI11_NODISCARD std::shared_ptr< ConfigBase > get_config_formatter_base() const
Access the config formatter as a configBase pointer.
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Validator & active(bool active_val=true)
Specify whether the Validator is active or not.
std::string ignore_space(std::string item)
Helper function to allow checks to ignore spaces to be passed to IsMember or Transform.
typename std::conditional< B, T, F >::type conditional_t
A copy of std::conditional_t from C++14 - same reasoning as enable_if_t, it does not hurt to redefine...
bool ignore_underscore_
If true, the program should ignore underscores INHERITABLE.
std::size_t require_subcommand_min_
Minimum required subcommands (not inheritable!)
std::vector< std::string > fnames_
a list of flag names with specified default values;
bool remove_excludes(Option *opt)
Remove needs link from an option. Returns true if the option really was in the needs list...
App * enabled_by_default(bool enable=true)
std::string name_
Subcommand name or program name (from parser if name is empty)
config_extras_mode allow_config_extras_
std::enable_if< std::is_integral< T >::value, bool >::type checked_multiply(T &a, T b)
Performs a *= b; if it doesn't cause integer overflow. Returns false otherwise.
CLI11_NODISCARD int get_expected_min() const
The number of times the option expects to be included.
bool pre_parse_called_
Flag indicating that the pre_parse_callback has been triggered.
void _move_to_missing(detail::Classifier val_type, const std::string &val)
Helper function to place extra values in the most appropriate position.
App * needs(Option *opt)
Counts the number of times the given option was passed.
Option * check(Validator validator, const std::string &validator_name="")
Adds a Validator with a built in type name.
char arrayEnd
the character used to end an array '\0' is a default to not use
std::string operator()(const std::string &str) const
Option * help_ptr_
A pointer to the help flag if there is one INHERITABLE.
std::function< void(std::size_t)> pre_parse_callback_
This is a function that runs prior to the start of parsing.
constexpr enabler dummy
An instance to use in EnableIf.
CLI11_NODISCARD std::string get_name() const
CLI11_NODISCARD bool get_prefix_command() const
Get the prefix command status.
App * require_option()
The argumentless form of require option requires 1 or more options be used.
typename std::remove_const< value_type >::type second_type
App * add_subcommand(std::string subcommand_name="", std::string subcommand_description="")
Add a subcommand. Inherits INHERITABLE and OptionDefaults, and help flag.
Thrown when an option already exists.
App(std::string app_description, std::string app_name, App *parent)
Special private constructor for subcommand.
Option * add_option(std::string option_name, T &option_description)
Add option with description but with no variable assignment or callback.
CLI11_NODISCARD const std::string & get_group() const
Get the group of this subcommand.
Validate the given string is a legal ipv4 address.
std::int64_t to_flag_value(std::string val)
Convert a flag into an integer value typically binary flags.
Option * set_help_flag(std::string flag_name="", const std::string &help_description="")
Set a help flag, replace the existing one if present.
char arraySeparator
the character used to separate elements in an array
png_const_structrp png_const_inforp int * unit
uint8_t maximumLayers
the maximum number of layers to allow
SYS_FORCE_INLINE const char * c_str() const
CLI11_NODISCARD bool check_name(std::string name_to_check) const
Check the name, case insensitive and underscore insensitive if set.
Option * add_flag(std::string flag_name, std::vector< T > &flag_results, std::string flag_description="")
Vector version to capture multiple flags.
Thrown when a required option is missing.
typename std::remove_const< typename value_type::first_type >::type first_type
ConfigBase ConfigTOML
the default Config is the TOML file format
IsMember(T &&set)
This checks to see if an item is in a set (empty function)
CLI11_NODISCARD int get_expected() const
The number of times the option expects to be included.
Does not output a diagnostic in CLI11_PARSE, but allows main() to return with a specific error code...
std::unique_ptr< Option > Option_p
char valueDelimiter
the character used separate the name from the value
CLI11_NODISCARD int get_items_expected_max() const
Get the maximum number of items expected to be returned and used for the callback.
Class wrapping some of the accessors of Validator.
GLuint const GLchar * name
All errors derive from this one.
std::vector< App_p > subcommands_
Storage for subcommand list.
bool _parse_arg(std::vector< std::string > &args, detail::Classifier current_type)
std::string ini_join(const std::vector< std::string > &args, char sepChar= ',', char arrayStart= '[', char arrayEnd= ']', char stringQuote= '"', char characterQuote = '\'')
Comma separated join, adds quotes if needed.
name_(std::move(validator_name))
CLI11_NODISCARD bool parsed() const
Check to see if this subcommand was parsed, true only if received on command line.
App * prefix_command(bool allow=true)
Do not parse anything after the first unrecognized option and return.
static auto parse_subcommand(App *app, Args &&...args) -> typename std::result_of< decltype(&App::_parse_subcommand)(App, Args...)>::type
Wrap _parse_subcommand, perfectly forward arguments and return.
CLI11_NODISCARD bool get_run_callback_for_default() const
Get the current value of run_callback_for_default.
CLI11_INLINE void TriggerOn(App *trigger_app, App *app_to_enable)
Helper function to enable one option group/subcommand when another is used.
std::set< Option * > needs_
A list of options that are required with this option.
App * fallthrough(bool value=true)
Option * needs(Option *opt)
Sets required options.
void _process_callbacks()
Process callbacks. Runs on all subcommands.
GLsizei const GLchar *const * strings
GLboolean GLboolean GLboolean b
std::function< void()> parse_complete_callback_
This is a function that runs when parsing has finished.
App(std::string app_description="", std::string app_name="")
Create a new program. Pass in the same arguments as main(), along with a help string.
GA_API const UT_StringHolder transform
Option * needs(A opt, B opt1, ARG...args)
Any number supported, any mix of string and Opt.
CLI11_NODISCARD std::vector< App * > get_subcommands() const
Range(T max_val, const std::string &validator_name=std::string{})
Range of one value is 0 to value.
bool configurable_
if set to true the subcommand can be triggered via configuration files INHERITABLE ...
IsMember(T set, F filter_function)
std::vector< Option_p > options_
The list of options, stored locally.
CLI11_NODISCARD bool get_disable_flag_override() const
The status of configurable.
CLI11_NODISCARD std::size_t _count_remaining_positionals(bool required_only=false) const
Count the required remaining positional arguments.
Thrown when extra values are found in an INI file.
char arrayStart
the character used to start an array '\0' is a default to not use
int16_t & indexRef()
get a reference to the configuration index
CLI11_NODISCARD int16_t index() const
get the section index
App * require_option(std::size_t min, std::size_t max)
CLI11_INLINE bool split_short(const std::string ¤t, std::string &name, std::string &rest)
Option * excludes(A opt, B opt1, ARG...args)
Any number supported, any mix of string and Opt.
CLI11_NODISCARD const Option * get_config_ptr() const
Get a pointer to the config option. (const)
OptionDefaults * ignore_case(bool value=true)
Ignore the case of the option name.
-v or –version on command line
ConfigBase * section(const std::string §ionName)
specify a particular section of the configuration file to use
bool run_callback_for_default_
Control option to run the callback to set the default.
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
Thrown when the wrong number of arguments has been received.
typename make_void< Ts...>::type void_t
A copy of std::void_t from C++17 - same reasoning as enable_if_t, it does not hurt to redefine...
static App * get_fallthrough_parent(App *app)
Wrap the fallthrough parent function to make sure that is working correctly.
take only the last Expected number of arguments
Option * add_option_function(std::string option_name, const std::function< void(const ArgType &)> &func, std::string option_description="")
Add option for a callback of a specific type.
a subset of results has been generated
bool empty() const
method name that maches std::string
CLI11_INLINE std::ostream & format_aliases(std::ostream &out, const std::vector< std::string > &aliases, std::size_t wid)
Print subcommand aliases.
AsNumberWithUnit(std::map< std::string, Number > mapping, Options opts=DEFAULT, const std::string &unit_name="UNIT")
IsMember(T &&set, filter_fn_t filter_fn_1, filter_fn_t filter_fn_2, Args &&...other)
You can pass in as many filter functions as you like, they nest (string only currently) ...
CLI11_NODISCARD std::size_t count(std::string option_name) const
Counts the number of times the given option was passed.
CLI11_NODISCARD bool get_ignore_underscore() const
The status of ignore_underscore.
std::function< std::string(const App *, const Error &e)> failure_message_
The error message printing function INHERITABLE.
CRTP * group(const std::string &name)
Changes the group membership.
Option * get_option_no_throw(std::string option_name) noexcept
Get an option by name (noexcept non-const version)
Validator(std::string validator_desc, std::function< std::string(std::string &)> func)
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
CLI11_NODISCARD bool get_disabled_by_default() const
Get the status of disabled by default.
std::string to_lower(std::string str)
Return a lower case version of a string.
CLI11_NODISCARD bool nonpositional() const
True if option has at least one non-positional name.
std::vector< Option * > parse_order_
This is a list of pointers to options with the original parse order.
OIIO_API string_view getenv(string_view name, string_view defaultval)
CLI11_NODISCARD int get_application_index() const
Get the current value of the application index.
CLI11_INLINE std::tuple< std::vector< std::string >, std::vector< std::string >, std::string > get_names(const std::vector< std::string > &input)
Get a vector of short names, one of long names, and a single name.
ConfigBase * valueSeparator(char vSep)
Specify the delimiter between a name and value.
Produce a range (factory). Min and max are inclusive.
NonexistentPathValidator()
CLI11_INLINE std::ptrdiff_t find_member(std::string name, const std::vector< std::string > names, bool ignore_case=false, bool ignore_underscore=false)
Check if a string is a member of a list of strings and optionally ignore case or ignore underscores...
CLI11_NODISCARD std::string get_display_name(bool with_aliases=false) const
Get a display name for an app.
CLI11_NODISCARD bool get_force_callback() const
The status of force_callback.
std::string convert_arg_for_ini(const std::string &arg, char stringQuote= '"', char characterQuote = '\'')
OptionDefaults * ignore_underscore(bool value=true)
Ignore underscores in the option name.
Usd_Term operator!(Usd_PrimFlags flag)
bool lexical_assign(const std::string &input, AssignTo &output)
Assign a value through lexical cast operations.
Option * type_name(std::string typeval)
Set a custom option typestring.
Option * type_size(int option_type_size)
Set a custom option size.
Extension of App to better manage groups of options.
CLI11_NODISCARD detail::Classifier _recognize(const std::string ¤t, bool ignore_used_subcommands=true) const
Selects a Classifier enum based on the type of the current argument.
std::vector< std::string > inputs
Listing of inputs.
CLI11_NODISCARD bool check_sname(std::string name) const
Requires "-" to be removed from string.
App * allow_extras(bool allow=true)
Remove the error when extras are left over on the command line.
Validator operator!() const
Create a validator that fails when a given validator succeeds.
std::string name_
The name for search purposes of the Validator.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Validator & application_index(int app_index)
Specify the application index of a validator.
bool disable_flag_override_
Disable overriding flag values with '=value'.
MultiOptionPolicy
Enumeration of the multiOption Policy selection.
CLI11_NODISCARD bool _has_remaining_positionals() const
Count the required remaining positional arguments.
GLenum GLsizei GLsizei GLint * values
int expected_max_
The maximum number of expected values.
App * name(std::string app_name="")
Set a name for the app (empty will use parser to set the name)
App * allow_windows_style_options(bool value=true)
CLI11_INLINE void retire_option(App *app, Option *opt)
Helper function to mark an option as retired.
std::string configSection
Specify the configuration section that should be used.
Option * default_str(std::string val)
Set the default value string representation (does not change the contained value) ...
CLI11_NODISCARD int get_type_size_max() const
The maximum number of arguments the option expects.
std::vector< std::string > aliases_
Alias names for the subcommand.
App * parse_complete_callback(std::function< void()> pc_callback)
Option * version_ptr_
A pointer to a version flag if there is one.
Throw an error if any extra arguments were given.
App * _get_fallthrough_parent()
Get the appropriate parent to fallthrough to which is the first one that has a name or the main app...
CRTP * required(bool value=true)
Set the option as required.
typename std::remove_const< value_type >::type first_type
ConfigBase * arrayDelimiter(char aSep)
Specify the delimiter character for an array.
std::string group_
The group membership.
CLI11_NODISCARD const results_t & results() const
Get the current complete results set.
This can be specialized to override the type deduction for IsMember.
App & operator=(const App &)=delete
Create a new program. Pass in the same arguments as main(), along with a help string.
App * ignore_case(bool value=true)
Ignore case. Subcommands inherit value.
TypeValidator(const std::string &validator_name)
static auto first(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the first value (really just the underlying value)
Option * add_flag(std::string flag_name, T &flag_result, std::string flag_description="")
CLI11_NODISCARD bool get_always_capture_default() const
Return true if this will automatically capture the default value for help printing.
Range(T min_val, T max_val, const std::string &validator_name=std::string{})
void _parse_stream(std::istream &input)
Internal function to parse a stream.
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
A copy of std::void_t from C++17 (helper for C++11 and C++14)
App * formatter_fn(std::function< std::string(const App *, std::string, AppFormatMode)> fmt)
Set the help formatter.
void _trigger_pre_parse(std::size_t remaining_args)
Trigger the pre_parse callback if needed.
#define PXR_NAMESPACE_CLOSE_SCOPE
CLI11_NODISCARD bool get_allow_extras() const
Get the status of allow extras.
Bound(T min_val, T max_val)
ConfigBase * quoteCharacter(char qString, char qChar)
Specify the quote characters used around strings and characters.
CLI11_NODISCARD bool check_fname(std::string name) const
Requires "--" to be removed from string.
bool remove_subcommand(App *subcom)
Removes a subcommand from the App. Takes a subcommand pointer. Returns true if found and removed...
App * formatter(std::shared_ptr< FormatterBase > fmt)
Set the help formatter.
std::shared_ptr< Config > config_formatter_
This is the formatter for help printing. Default provided. INHERITABLE (same pointer) ...
std::vector< Validator > validators_
A list of Validators to run on each value parsed.
static auto second(Q &&pair_value) -> decltype(std::forward< Q >(pair_value))
Get the second value (really just the underlying value)
Validator operator|(const Validator &other) const
CLI11_NODISCARD bool got_subcommand(std::string subcommand_name) const
Check with name instead of pointer to see if subcommand was selected.
Validator * get_validator(const std::string &Validator_name="")
Get a named Validator.
This class provides a converter for configuration files.
IsMember(std::initializer_list< T > values, Args &&...args)
This allows in-place construction using an initializer list.
**If you just want to fire and args
CLI11_NODISCARD const Option * get_option(std::string option_name) const
Get an option by name.
CLI11_NODISCARD bool get_inject_separator() const
Return the inject_separator flag.
App * excludes(App *app)
Sets excluded subcommands for the subcommand.
CLI::App_p get_subcommand_ptr(App *subcom) const
Check to see if a subcommand is part of this command and get a shared_ptr to it.
CLI11_INLINE std::pair< std::string, std::string > split_program_name(std::string commandline)
Check to see if something is copyable pointer.
Option * set_help_all_flag(std::string help_name="", const std::string &help_description="")
Set a help all flag, replaced the existing one if present.
CLI11_NODISCARD const Option * get_help_ptr() const
Get a pointer to the help flag. (const)
std::function< std::string(std::string &)> func_
CLI11_INLINE std::string & rtrim(std::string &str)
Trim whitespace from right of string.
CLI11_NODISCARD const Option * get_help_all_ptr() const
Get a pointer to the help all flag. (const)
auto smart_deref(T value) -> decltype(*value)
CLI11_NODISCARD const std::string & get_description() const
Get the description.
config_extras_mode
enumeration of modes of how to deal with extras in config files
CLI11_NODISCARD const std::string & get_name() const
Get the name of the Validator.
bool required_
If set to true the subcommand is required to be processed and used, ignored for main app...
std::string description_
Description of the current program/subcommand.
static auto second(Q &&pair_value) -> decltype(std::get< 1 >(std::forward< Q >(pair_value)))
Get the second value (really just the underlying value)
bool _parse_single(std::vector< std::string > &args, bool &positional_only)
The normal, detailed help.
CLI11_NODISCARD std::string config_to_str(bool default_also=false, bool write_description=false) const
App * silent(bool silence=true)
silence the subcommand from showing up in the processed list
char stringQuote
the character to use around strings
virtual CLI11_NODISCARD std::string to_flag(const ConfigItem &item) const
Get a flag value.
App * callback(std::function< void()> app_callback)
void failure_message(std::function< std::string(const App *, const Error &e)> function)
Provide a function to print a help message. The function gets access to the App pointer and error...
void _parse(std::vector< std::string > &args)
Internal parse function.
Option * add_option(std::string option_name, callback_t option_callback, std::string option_description="", bool defaulted=false, std::function< std::string()> func={})
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
callback_t callback_
Options store a callback to do all the work.
CLI11_NODISCARD bool get_positional() const
True if the argument can be given directly.
App * require_option(int value)
Adaptor for set-like structure: This just wraps a normal container in a few utilities that do almost ...
CLI11_NODISCARD bool get_active() const
Get a boolean if the validator is active.
CLI11_NODISCARD std::string get_description() const
Generate type description information for the Validator.
The option is currently collecting parsed results.
App * get_parent()
Get the parent of this subcommand (or nullptr if main app)
CLI11_NODISCARD std::string get_type_name() const
Get the full typename for this option.
Option * add_flag(std::string flag_name)
Add a flag with no description or variable assignment.
merge all the arguments together into a single string via the delimiter character default(' ') ...
CLI11_NODISCARD std::string get_description() const
Get the app or subcommand description.
App * parent_
link back up to the parent App for fallthrough
Option * force_callback(bool value=true)
Set the value of force_callback.
CLI11_NODISCARD bool has_description() const
True if option has description.
std::enable_if< std::is_signed< T >::value, T >::type overflowCheck(const T &a, const T &b)
Do a check for overflow on signed numbers.
App * config_formatter(std::shared_ptr< Config > fmt)
Set the config formatter.
CLI11_NODISCARD std::string fullname() const
The list of parents and name joined by ".".
bool ignore_case_
Ignore the case when matching (option, not value)
App * allow_config_extras(config_extras_mode mode)
ignore extras in config files
CLI11_NODISCARD std::vector< std::string > remaining(bool recurse=false) const
This returns the missing options from the current subcommand.
SIM_API const UT_StringHolder distance
sum all the arguments together if numerical or concatenate directly without delimiter ...
const Range NonNegativeNumber((std::numeric_limits< double >::max)(),"NONNEGATIVE")
Check for a non negative number.
std::string description_
The description for help strings.
char parentSeparatorChar
the separator used to separator parent layers
CLI11_NODISCARD bool get_fallthrough() const
Check the status of fallthrough.
App * validate_optional_arguments(bool validate=true)
Set the subcommand to validate optional vector arguments before assigning.
Usually something like –help-all on command line.
This converter works with INI/TOML files; to write INI files use ConfigINI.
Option_group(std::string group_description, std::string group_name, App *parent)
startup_mode
Storage for subcommand list.
Option * expected(int value)
Set the number of expected arguments.
Option & operator=(const Option &)=delete
Count the total number of times an option was passed.
int type_size_min_
The minimum number of arguments an option should be expecting.
void add_options(Option *opt, Args...args)
Add a bunch of options to the group.
CLI11_NODISCARD const std::string & get_group() const
Get the group of this option.
bool remove_excludes(Option *opt)
Removes an option from the excludes list of this subcommand.
static auto first(Q &&pair_value) -> decltype(std::get< 0 >(std::forward< Q >(pair_value)))
Get the first value (really just the underlying value)
bool valid_alias_name_string(const std::string &str)
Verify an app name.
std::vector< App * > parsed_subcommands_
This is a list of the subcommands collected, in order.
CLI11_INLINE std::string find_and_replace(std::string str, std::string from, std::string to)
Find and replace a substring with another substring.
void clear()
Reset the parsed data.
bool required_
True if this is a required option.
std::string type_name()
get the type name for a type that has a value_type member
GA_API const UT_StringHolder rest
std::function< std::string()> default_function_
Run this function to capture a default (ignore if empty)
bool isalpha(const std::string &str)
Verify that str consists of letters only.
bool ignore_case_
If true, the program name is not case sensitive INHERITABLE.
CLI11_NODISCARD std::size_t remaining_size(bool recurse=false) const
This returns the number of remaining options, minus the – separator.
Validator operator&(const Validator &other) const
App * parent_
A pointer to the parent if this is a subcommand.
App * group(std::string group_name)
Changes the group membership.
bool valid_first_char(T c)
CLI11_NODISCARD std::vector< ConfigItem > from_file(const std::string &name) const
Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure...
CRTP * configurable(bool value=true)
Allow in a configuration file.
CLI11_NODISCARD T as() const
Return the results as the specified type.
Thrown when a requires option is missing.
This will only trigger for actual void type.
CLI11_NODISCARD int get_exit_code() const
CLI11_NODISCARD std::vector< std::string > get_groups() const
Get the groups available directly from this option (in order)
CLI11_NODISCARD bool get_silent() const
Get the status of silence.
int16_t configIndex
Specify the configuration index to use for arrayed sections.
constexpr int expected_max_vector_size
App * positionals_at_end(bool value=true)
Specify that the positional arguments are only at the end of the sequence.
CLI11_INLINE std::vector< std::pair< std::string, std::string > > get_default_flag_values(const std::string &str)
extract default flag values either {def} or starting with a !
CRTP * delimiter(char value= '\0')
Allow in a configuration file.
CLI11_NODISCARD int get_expected_max() const
The max number of times the option expects to be included.
Option * get_help_ptr()
Get a pointer to the help flag.
#define CLI11_ERROR_DEF(parent, name)
CLI11_NODISCARD Validator active(bool active_val=true) const
Specify whether the Validator is active or not.
Some validators that are provided.
CLI11_NODISCARD bool get_ignore_case() const
Check the status of ignore_case.
typename element_type< T >::type::value_type type
CLI11_NODISCARD bool check_name(const std::string &name) const
Check a name. Requires "-" or "--" for short / long, supports positional name.
std::string footer_
Footer to put after all options in the help output INHERITABLE.
const detail::ExistingDirectoryValidator ExistingDirectory
Check for an existing directory (returns error message if check fails)
std::function< std::string()> type_name_
std::string default_str_
A human readable default value, either manually set, captured, or captured by default.
void _process_config_file()
Read and process a configuration file (main app only)
bool remove_needs(Option *opt)
Removes an option from the needs list of this subcommand.
bool _parse_subcommand(std::vector< std::string > &args)
int application_index_
A Validator will only apply to an indexed value (-1 is all elements)
void checkParentSegments(std::vector< ConfigItem > &output, const std::string ¤tSection, char parentSeparator)
assuming non default segments do a check on the close and open of the segments in a configItem struct...
virtual void pre_callback()
Produce a bounded range (factory). Min and max are inclusive.
void increment_parsed()
Internal function to recursively increment the parsed counter on the current app as well unnamed subc...
std::string pname_
A positional name.
Verify items are in a set.
Creates a command line program, with very few defaults.
std::string generate_set(const T &set)
Generate a string representation of a set.
Check for an existing directory (returns error message if check fails)
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
CLI11_NODISCARD const std::string & matching_name(const Option &other) const
If options share any of the same names, find it.
ConfigBase * arrayBounds(char aStart, char aEnd)
Specify the start and end characters for an array.
Holds values to load into Options.
CLI11_INLINE void remove_default_flag_values(std::string &flags)
static constexpr bool value
CLI11_NODISCARD bool get_callback_run() const
See if the callback has been run already.
std::set< Option * > need_options_
CLI11_NODISCARD std::shared_ptr< Config > get_config_formatter() const
Access the config formatter.
CLI11_NODISCARD bool empty() const
True if the option was not passed.
OptionDefaults * multi_option_policy(MultiOptionPolicy value=MultiOptionPolicy::Throw)
Take the last argument if given multiple times.
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
char characterQuote
the character to use around single characters
ConfigBase * parentSeparator(char sep)
Specify the separator to use for parent layers.
CLI11_NODISCARD std::string get_footer() const
Generate and return the footer.
const detail::ExistingPathValidator ExistingPath
Check for an existing path.
CRTP * join()
Set the multi option policy to join.
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.