36 #define ARGS_VERSION "6.2.4"
37 #define ARGS_VERSION_MAJOR 6
38 #define ARGS_VERSION_MINOR 2
39 #define ARGS_VERSION_PATCH 4
49 #include <unordered_map>
50 #include <unordered_set>
51 #include <type_traits>
55 #if defined(_MSC_VER) && _MSC_VER <= 1800
59 #ifdef ARGS_TESTNAMESPACE
75 template <
typename Option>
76 auto get(Option &option_) -> decltype(option_.Get())
89 inline std::string::size_type
Glyphs(
const std::string &string_)
91 std::string::size_type length = 0;
92 for (
const char c: string_)
94 if ((c & 0xc0) != 0x80)
113 template <
typename It>
114 inline std::vector<std::string>
Wrap(It begin,
116 const std::string::size_type width,
117 std::string::size_type firstlinewidth = 0,
118 std::string::size_type firstlineindent = 0)
120 std::vector<std::string> output;
121 std::string line(firstlineindent,
' ');
124 if (firstlinewidth == 0)
126 firstlinewidth = width;
129 auto currentwidth = firstlinewidth;
131 for (
auto it = begin; it != end; ++it)
142 output.push_back(line);
145 currentwidth = width;
151 auto itemsize =
Glyphs(*it);
152 if ((line.length() + 1 + itemsize) > currentwidth)
156 output.push_back(line);
159 currentwidth = width;
177 output.push_back(line);
185 template <
typename T>
186 std::string Join(
const T& array,
const std::string &delimiter)
189 for (
auto &element : array)
212 inline std::vector<std::string>
Wrap(
const std::string &in,
const std::string::size_type width, std::string::size_type firstlinewidth = 0)
215 const auto newlineloc = in.find(
'\n');
216 if (newlineloc != in.npos)
218 auto first =
Wrap(std::string(in, 0, newlineloc), width);
219 auto second =
Wrap(std::string(in, newlineloc + 1), width);
222 std::make_move_iterator(std::begin(second)),
223 std::make_move_iterator(std::end(second)));
227 std::istringstream stream(in);
228 std::string::size_type indent = 0;
239 return Wrap(std::istream_iterator<std::string>(stream), std::istream_iterator<std::string>(),
240 width, firstlinewidth, indent);
261 class Error :
public std::runtime_error
264 Error(
const std::string &problem) : std::runtime_error(problem) {}
327 Help(
const std::string &flag) :
Error(flag) {}
333 class SubparserError :
public Error
336 SubparserError() :
Error(
"") {}
337 virtual ~SubparserError() {}
355 const char shortFlag;
356 const std::string longFlag;
357 EitherFlag(
const std::string &flag) : isShort(
false), shortFlag(), longFlag(flag) {}
358 EitherFlag(
const char *flag) : isShort(
false), shortFlag(), longFlag(flag) {}
359 EitherFlag(
const char flag) : isShort(
true), shortFlag(flag), longFlag() {}
363 static std::unordered_set<std::string>
GetLong(std::initializer_list<EitherFlag> flags)
365 std::unordered_set<std::string> longFlags;
370 longFlags.insert(flag.longFlag);
378 static std::unordered_set<char>
GetShort(std::initializer_list<EitherFlag> flags)
380 std::unordered_set<char> shortFlags;
385 shortFlags.insert(flag.shortFlag);
391 std::string str()
const
393 return isShort ? std::string(1, shortFlag) : longFlag;
396 std::string str(
const std::string &shortPrefix,
const std::string &longPrefix)
const
398 return isShort ? shortPrefix + std::string(1, shortFlag) : longPrefix + longFlag;
413 const std::unordered_set<char> shortFlags;
414 const std::unordered_set<std::string> longFlags;
421 template <
typename ShortIt,
typename LongIt>
422 Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd) :
423 shortFlags(shortFlagsStart, shortFlagsEnd),
424 longFlags(longFlagsStart, longFlagsEnd)
426 if (shortFlags.empty() && longFlags.empty())
428 #ifndef ARGS_NOEXCEPT
436 Error GetError() const noexcept
438 return shortFlags.empty() && longFlags.empty() ? Error::Usage : Error::None;
446 template <
typename Short,
typename Long>
448 Matcher(std::begin(shortIn), std::end(shortIn), std::begin(longIn), std::end(longIn))
463 Matcher(std::initializer_list<EitherFlag> in) :
466 Matcher(
Matcher &&other) : shortFlags(std::move(other.shortFlags)), longFlags(std::move(other.longFlags))
475 return shortFlags.find(flag) != shortFlags.end();
480 bool Match(
const std::string &flag)
const
482 return longFlags.find(flag) != longFlags.end();
489 return flag.isShort ? Match(flag.shortFlag) : Match(flag.longFlag);
496 std::vector<EitherFlag> flagStrings;
497 flagStrings.reserve(shortFlags.size() + longFlags.size());
498 for (
const char flag: shortFlags)
500 flagStrings.emplace_back(flag);
502 for (
const std::string &flag: longFlags)
504 flagStrings.emplace_back(flag);
513 if (!longFlags.empty())
515 return *longFlags.begin();
518 if (!shortFlags.empty())
520 return *shortFlags.begin();
531 if (!shortFlags.empty())
533 return *shortFlags.begin();
536 if (!longFlags.empty())
538 return *longFlags.begin();
589 return static_cast<Options>(
static_cast<int>(lhs) |
static_cast<int>(rhs));
594 return static_cast<Options>(
static_cast<int>(lhs) &
static_cast<int>(rhs));
598 class PositionalBase;
600 class ArgumentParser;
608 unsigned int width = 80;
611 unsigned int progindent = 2;
614 unsigned int progtailindent = 4;
617 unsigned int descriptionindent = 4;
620 unsigned int flagindent = 6;
623 unsigned int helpindent = 40;
626 unsigned int eachgroupindent = 2;
630 unsigned int gutter = 1;
634 bool showTerminator =
true;
638 bool showProglineOptions =
true;
642 bool showProglinePositionals =
true;
666 bool showCommandChildren =
false;
670 bool showCommandFullHelp =
false;
674 std::string proglineOptions =
"{OPTIONS}";
678 std::string proglineCommand =
"COMMAND";
682 std::string proglineValueOpen =
" <";
686 std::string proglineValueClose =
">";
690 std::string proglineRequiredOpen =
"";
694 std::string proglineRequiredClose =
"";
698 std::string proglineNonrequiredOpen =
"[";
702 std::string proglineNonrequiredClose =
"]";
706 bool proglineShowFlags =
false;
710 bool proglinePreferShortFlags =
false;
718 std::string optionsString =
"OPTIONS:";
722 bool useValueNameOnce =
false;
726 bool showValueName =
true;
730 bool addNewlineBeforeDescription =
false;
734 std::string valueOpen =
"[";
738 std::string valueClose =
"]";
742 bool addChoices =
false;
746 std::string choiceString =
"\nOne of: ";
750 bool addDefault =
false;
754 std::string defaultString =
"\nDefault: ";
766 Nargs(
size_t min_,
size_t max_) : min{min_}, max{max_}
768 #ifndef ARGS_NOEXCEPT
776 Nargs(
size_t num_) : min{num_}, max{num_}
780 friend bool operator == (
const Nargs &lhs,
const Nargs &rhs)
782 return lhs.min == rhs.min && lhs.max == rhs.max;
785 friend bool operator != (
const Nargs &lhs,
const Nargs &rhs)
787 return !(lhs == rhs);
799 bool matched =
false;
800 const std::string help;
803 mutable Error error = Error::None;
804 mutable std::string errorMsg;
808 Base(
const std::string &help_,
Options options_ = {}) : options(options_), help(help_) {}
811 Options GetOptions()
const noexcept
816 bool IsRequired()
const noexcept
818 return (GetOptions() & Options::Required) != Options::None;
821 virtual bool Matched()
const noexcept
826 virtual void Validate(
const std::string &,
const std::string &)
const
830 operator bool()
const noexcept
835 virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(
const HelpParams &,
const unsigned indentLevel)
const
837 std::tuple<std::string, std::string, unsigned> description;
838 std::get<1>(description) = help;
839 std::get<2>(description) = indentLevel;
840 return { std::move(description) };
843 virtual std::vector<Command*> GetCommands()
848 virtual bool IsGroup()
const
863 virtual std::vector<FlagBase*> GetAllFlags()
868 virtual bool HasFlag()
const
873 virtual bool HasPositional()
const
878 virtual bool HasCommand()
const
883 virtual std::vector<std::string> GetProgramLine(
const HelpParams &)
const
893 options = options | Options::KickOut;
897 options =
static_cast<Options>(
static_cast<int>(options) & ~
static_cast<int>(Options::KickOut));
904 return (options & Options::KickOut) != Options::None;
907 virtual void Reset() noexcept
918 virtual Error GetError()
const
924 std::string GetErrorMsg()
const
936 const std::string name;
937 bool kickout =
false;
938 std::string defaultString;
939 bool defaultStringManual =
false;
940 std::vector<std::string> choicesStrings;
941 bool choicesStringManual =
false;
943 virtual std::string GetDefaultString(
const HelpParams&)
const {
return {}; }
945 virtual std::vector<std::string> GetChoicesStrings(
const HelpParams&)
const {
return {}; }
947 virtual std::string GetNameString(
const HelpParams&)
const {
return Name(); }
949 void AddDescriptionPostfix(std::string &dest,
const bool isManual,
const std::string &manual,
bool isGenerated,
const std::string &generated,
const std::string &str)
const
951 if (isManual && !manual.empty())
956 else if (!isManual && isGenerated && !generated.empty())
964 NamedBase(
const std::string &name_,
const std::string &help_,
Options options_ = {}) :
Base(help_, options_), name(name_) {}
972 defaultStringManual =
true;
980 return defaultStringManual ? defaultString : GetDefaultString(params);
988 choicesStringManual =
true;
989 choicesStrings = array;
996 return choicesStringManual ? choicesStrings : GetChoicesStrings(params);
999 virtual std::vector<std::tuple<std::string, std::string, unsigned>> GetDescription(
const HelpParams ¶ms,
const unsigned indentLevel)
const override
1001 std::tuple<std::string, std::string, unsigned> description;
1002 std::get<0>(description) = GetNameString(params);
1003 std::get<1>(description) = help;
1004 std::get<2>(description) = indentLevel;
1006 AddDescriptionPostfix(std::get<1>(description), choicesStringManual, detail::Join(choicesStrings,
", "), params.
addChoices, detail::Join(GetChoicesStrings(params),
", "), params.
choiceString);
1007 AddDescriptionPostfix(std::get<1>(description), defaultStringManual, defaultString, params.
addDefault, GetDefaultString(params), params.
defaultString);
1009 return { std::move(description) };
1012 virtual std::string Name()
const
1020 template<
typename T>
1021 using vector = std::vector<T, std::allocator<T>>;
1023 template<
typename K,
typename T>
1024 using unordered_map = std::unordered_map<K, T, std::hash<K>,
1025 std::equal_to<K>, std::allocator<std::pair<const K, T> > >;
1027 template<
typename S,
typename T>
1030 template<
typename SS,
typename TT>
1031 static auto test(
int)
1032 -> decltype( std::declval<SS&>() << std::declval<TT>(), std::true_type() );
1034 template<
typename,
typename>
1035 static auto test(...) -> std::false_type;
1038 using type = decltype(test<S,T>(0));
1041 template <
typename T>
1042 using IsConvertableToString =
typename is_streamable<std::ostringstream, T>::type;
1044 template <
typename T>
1045 typename std::enable_if<IsConvertableToString<T>::value, std::string>::type
1046 ToString(
const T &value)
1048 std::ostringstream s;
1053 template <
typename T>
1054 typename std::enable_if<!IsConvertableToString<T>::value, std::string>::type
1060 template <
typename T>
1061 std::vector<std::string> MapKeysToStrings(
const T &map)
1063 std::vector<std::string> res;
1064 using K =
typename std::decay<decltype(std::begin(map)->first)>::type;
1065 if (IsConvertableToString<K>::value)
1067 for (
const auto &p : map)
1069 res.push_back(detail::ToString(p.first));
1072 std::sort(res.begin(), res.end());
1085 virtual std::string GetNameString(
const HelpParams ¶ms)
const override
1087 const std::string postfix = !params.
showValueName || NumberOfArguments() == 0 ? std::string() : Name();
1090 const bool useValueNameOnce = flagStrings.size() == 1 ? false : params.
useValueNameOnce;
1091 for (
auto it = flagStrings.begin(); it != flagStrings.end(); ++it)
1094 if (it != flagStrings.begin())
1100 flags += flag.str();
1102 if (!postfix.empty() && (!useValueNameOnce || it + 1 == flagStrings.end()))
1113 FlagBase(
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const bool extraError_ =
false) :
NamedBase(name_, help_, extraError_ ? Options::Single :
Options()), matcher(std::move(matcher_)) {}
1115 FlagBase(
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
Options options_) :
NamedBase(name_, help_, options_), matcher(std::move(matcher_)) {}
1121 if (matcher.
Match(flag))
1123 if ((GetOptions() & Options::Single) != Options::None && matched)
1125 std::ostringstream problem;
1126 problem <<
"Flag '" << flag.str() <<
"' was passed multiple times, but is only allowed to be passed once";
1127 #ifdef ARGS_NOEXCEPT
1128 error = Error::Extra;
1129 errorMsg = problem.str();
1140 virtual std::vector<FlagBase*> GetAllFlags()
override
1145 const Matcher &GetMatcher()
const
1150 virtual void Validate(
const std::string &shortPrefix,
const std::string &longPrefix)
const override
1152 if (!Matched() && IsRequired())
1154 std::ostringstream problem;
1155 problem <<
"Flag '" << matcher.
GetLongOrAny().str(shortPrefix, longPrefix) <<
"' is required";
1156 #ifdef ARGS_NOEXCEPT
1157 error = Error::Required;
1158 errorMsg = problem.str();
1165 virtual std::vector<std::string> GetProgramLine(
const HelpParams ¶ms)
const override
1172 const std::string postfix = NumberOfArguments() == 0 ? std::string() : Name();
1175 if (!postfix.empty())
1184 virtual bool HasFlag()
const override
1189 #ifdef ARGS_NOEXCEPT
1191 virtual Error GetError()
const override
1193 const auto nargs = NumberOfArguments();
1194 if (nargs.min > nargs.max)
1196 return Error::Usage;
1199 const auto matcherError = matcher.GetError();
1200 if (matcherError != Error::None)
1202 return matcherError;
1219 virtual
void ParseValue(const std::vector<std::
string> &value) = 0;
1227 ValueFlagBase(
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const bool extraError_ =
false) :
FlagBase(name_, help_, std::move(matcher_), extraError_) {}
1240 std::vector<std::string> reply;
1244 template <
typename GroupClass>
1247 group_.AddCompletion(*
this);
1257 virtual void ParseValue(
const std::vector<std::string> &value_)
override
1259 syntax = value_.at(0);
1260 std::istringstream(value_.at(1)) >> cword;
1267 return detail::Join(reply,
"\n");
1270 virtual void Reset() noexcept
override
1272 ValueFlagBase::Reset();
1296 virtual void ParseValue(
const std::string &value_) = 0;
1298 virtual void Reset() noexcept
override
1302 #ifdef ARGS_NOEXCEPT
1303 error = Error::None;
1310 return Ready() ? this :
nullptr;
1313 virtual bool HasPositional()
const override
1318 virtual std::vector<std::string> GetProgramLine(
const HelpParams ¶ms)
const override
1324 virtual void Validate(
const std::string &,
const std::string &)
const override
1326 if (IsRequired() && !Matched())
1328 std::ostringstream problem;
1329 problem <<
"Option '" << Name() <<
"' is required";
1330 #ifdef ARGS_NOEXCEPT
1331 error = Error::Required;
1332 errorMsg = problem.str();
1345 std::vector<Base*> children;
1346 std::function<bool(
const Group &)> validator;
1353 static bool Xor(
const Group &group)
1358 static bool AtLeastOne(
const Group &group)
1363 static bool AtMostOne(
const Group &group)
1368 static bool All(
const Group &group)
1373 static bool AllOrNone(
const Group &group)
1375 return (All(group) ||
None(group));
1378 static bool AllChildGroups(
const Group &group)
1380 return std::none_of(std::begin(group.
Children()), std::end(group.
Children()), [](
const Base* child) ->
bool {
1381 return child->IsGroup() && !child->Matched();
1385 static bool DontCare(
const Group &)
1390 static bool CareTooMuch(
const Group &)
1401 Group(
const std::string &help_ = std::string(),
const std::function<
bool(
const Group &)> &validator_ = Validators::DontCare,
Options options_ = {}) :
Base(help_, options_), validator(validator_) {}
1403 Group(
Group &group_,
const std::string &help_ = std::string(),
const std::function<
bool(
const Group &)> &validator_ = Validators::DontCare,
Options options_ = {}) :
Base(help_, options_), validator(validator_)
1413 children.emplace_back(&child);
1430 for (
Base *child: Children())
1432 if (
FlagBase *match = child->Match(flag))
1440 virtual std::vector<FlagBase*> GetAllFlags()
override
1442 std::vector<FlagBase*> res;
1443 for (
Base *child: Children())
1445 auto childRes = child->GetAllFlags();
1446 res.insert(res.end(), childRes.begin(), childRes.end());
1451 virtual void Validate(
const std::string &shortPrefix,
const std::string &longPrefix)
const override
1453 for (Base *child: Children())
1455 child->Validate(shortPrefix, longPrefix);
1465 for (
Base *child: Children())
1467 if (
auto next = child->GetNextPositional())
1481 return std::any_of(Children().begin(), Children().end(), [](
Base *child) {
return child->HasFlag(); });
1490 return std::any_of(Children().begin(), Children().end(), [](
Base *child) {
return child->HasPositional(); });
1499 return std::any_of(Children().begin(), Children().end(), [](
Base *child) {
return child->HasCommand(); });
1507 return static_cast<std::vector<Base *>::size_type
>(
1508 std::count_if(std::begin(Children()), std::end(Children()), [](
const Base *child){
return child->Matched();}));
1515 return validator(*
this);
1527 virtual std::vector<std::tuple<std::string, std::string, unsigned>>
GetDescription(
const HelpParams ¶ms,
const unsigned int indent)
const override
1529 std::vector<std::tuple<std::string, std::string, unsigned int>> descriptions;
1532 unsigned addindent = 0;
1535 descriptions.emplace_back(help,
"", indent);
1539 for (
Base *child: Children())
1541 if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)
1546 auto groupDescriptions = child->GetDescription(params, indent + addindent);
1547 descriptions.insert(
1548 std::end(descriptions),
1549 std::make_move_iterator(std::begin(groupDescriptions)),
1550 std::make_move_iterator(std::end(groupDescriptions)));
1552 return descriptions;
1559 std::vector <std::string> names;
1560 for (
Base *child: Children())
1562 if ((child->GetOptions() & Options::HiddenFromUsage) != Options::None)
1567 auto groupNames = child->GetProgramLine(params);
1570 std::make_move_iterator(std::begin(groupNames)),
1571 std::make_move_iterator(std::end(groupNames)));
1576 virtual std::vector<Command*> GetCommands()
override
1578 std::vector<Command*> res;
1579 for (
const auto &child : Children())
1581 auto subparsers = child->GetCommands();
1582 res.insert(std::end(res), std::begin(subparsers), std::end(subparsers));
1587 virtual bool IsGroup()
const override
1592 virtual void Reset() noexcept
override
1596 for (
auto &child: Children())
1600 #ifdef ARGS_NOEXCEPT
1601 error = Error::None;
1606 #ifdef ARGS_NOEXCEPT
1608 virtual Error GetError()
const override
1610 if (error != Error::None)
1615 auto it = std::find_if(Children().begin(), Children().end(), [](
const Base *child){
return child->GetError() != Error::None;});
1616 if (it == Children().end())
1621 return (*it)->GetError();
1659 std::vector<std::string>
args;
1660 std::vector<std::string> kicked;
1664 bool isParsed =
false;
1668 :
Group({}, Validators::AllChildGroups),
args(std::move(args_)), parser(&parser_), helpParams(helpParams_), command(command_)
1718 std::string description;
1720 std::string proglinePostfix;
1722 std::function<void(
Subparser&)> parserCoroutine;
1723 bool commandIsRequired =
true;
1724 Command *selectedCommand =
nullptr;
1726 mutable std::vector<std::tuple<std::string, std::string, unsigned>> subparserDescription;
1727 mutable std::vector<std::string> subparserProgramLine;
1728 mutable bool subparserHasFlag =
false;
1729 mutable bool subparserHasPositional =
false;
1730 mutable bool subparserHasCommand =
false;
1731 #ifdef ARGS_NOEXCEPT
1732 mutable Error subparserError = Error::None;
1741 RaiiSubparser(
ArgumentParser &parser_, std::vector<std::string> args_);
1746 command.subparser = oldSubparser;
1762 std::function<void(
Subparser&)> &GetCoroutine()
1764 return selectedCommand !=
nullptr ? selectedCommand->GetCoroutine() : parserCoroutine;
1770 while (res->selectedCommand !=
nullptr)
1772 res = res->selectedCommand;
1778 const Command &SelectedCommand()
const
1781 while (res->selectedCommand !=
nullptr)
1783 res = res->selectedCommand;
1789 void UpdateSubparserHelp(
const HelpParams ¶ms)
const
1791 if (parserCoroutine)
1793 RaiiSubparser coro(*
this, params);
1794 #ifndef ARGS_NOEXCEPT
1797 parserCoroutine(coro.Parser());
1799 catch (args::SubparserError&)
1803 parserCoroutine(coro.Parser());
1809 Command(
Group &base_, std::string name_, std::string help_, std::function<
void(
Subparser&)> coroutine_ = {})
1810 : name(std::move(name_)), help(std::move(help_)), parserCoroutine(std::move(coroutine_))
1818 {
return proglinePostfix; }
1823 { this->proglinePostfix = proglinePostfix_; }
1828 {
return description; }
1833 { this->description = description_; }
1843 { this->epilog = epilog_; }
1860 { commandIsRequired = value; }
1862 virtual bool IsGroup()
const override
1866 {
return Base::Matched(); }
1868 operator bool() const noexcept
1869 {
return Matched(); }
1871 void Match() noexcept
1874 void SelectCommand(Command *c) noexcept
1876 selectedCommand = c;
1886 if (selectedCommand !=
nullptr)
1888 if (
auto *res = selectedCommand->Match(flag))
1893 for (
auto *child: Children())
1895 if ((child->GetOptions() & Options::Global) != Options::None)
1897 if (
auto *res = child->Match(flag))
1907 if (subparser !=
nullptr)
1909 return subparser->
Match(flag);
1912 return Matched() ? Group::Match(flag) :
nullptr;
1915 virtual std::vector<FlagBase*> GetAllFlags()
override
1917 std::vector<FlagBase*> res;
1924 for (
auto *child: Children())
1926 if (selectedCommand ==
nullptr || (child->GetOptions() & Options::Global) != Options::None)
1928 auto childFlags = child->GetAllFlags();
1929 res.insert(res.end(), childFlags.begin(), childFlags.end());
1933 if (selectedCommand !=
nullptr)
1935 auto childFlags = selectedCommand->GetAllFlags();
1936 res.insert(res.end(), childFlags.begin(), childFlags.end());
1939 if (subparser !=
nullptr)
1941 auto childFlags = subparser->GetAllFlags();
1942 res.insert(res.end(), childFlags.begin(), childFlags.end());
1950 if (selectedCommand !=
nullptr)
1957 for (
auto *child: Children())
1959 if ((child->GetOptions() & Options::Global) != Options::None)
1961 if (
auto *res = child->GetNextPositional())
1971 if (subparser !=
nullptr)
1976 return Matched() ? Group::GetNextPositional() :
nullptr;
1981 return subparserHasFlag || Group::HasFlag();
1986 return subparserHasPositional || Group::HasPositional();
1994 std::vector<std::string> GetCommandProgramLine(
const HelpParams ¶ms)
const
1996 UpdateSubparserHelp(params);
1998 auto res = Group::GetProgramLine(params);
1999 res.insert(res.end(), subparserProgramLine.begin(), subparserProgramLine.end());
2001 if (!params.
proglineCommand.empty() && (Group::HasCommand() || subparserHasCommand))
2006 if (!Name().empty())
2008 res.insert(res.begin(), Name());
2016 if (!ProglinePostfix().empty())
2019 for (
char c : ProglinePostfix())
2025 res.push_back(line);
2031 res.push_back(
"\n");
2042 res.push_back(line);
2056 return GetCommandProgramLine(params);
2059 virtual std::vector<Command*> GetCommands()
override
2061 if (selectedCommand !=
nullptr)
2063 return selectedCommand->GetCommands();
2068 return Group::GetCommands();
2074 virtual std::vector<std::tuple<std::string, std::string, unsigned>>
GetDescription(
const HelpParams ¶ms,
const unsigned int indent)
const override
2076 std::vector<std::tuple<std::string, std::string, unsigned>> descriptions;
2077 unsigned addindent = 0;
2079 UpdateSubparserHelp(params);
2085 std::ostringstream s;
2087 for (
const auto &progline: GetCommandProgramLine(params))
2101 descriptions.emplace_back(s.str(),
"", indent);
2105 descriptions.emplace_back(Name(), help, indent);
2110 return descriptions;
2118 descriptions.emplace_back(
"",
"", indent + addindent);
2119 descriptions.emplace_back(Description().empty() ?
Help() : Description(),
"", indent + addindent);
2120 descriptions.emplace_back(
"",
"", indent + addindent);
2123 for (
Base *child: Children())
2125 if ((child->GetOptions() & Options::HiddenFromDescription) != Options::None)
2130 auto groupDescriptions = child->GetDescription(params, indent + addindent);
2131 descriptions.insert(
2132 std::end(descriptions),
2133 std::make_move_iterator(std::begin(groupDescriptions)),
2134 std::make_move_iterator(std::end(groupDescriptions)));
2137 for (
auto childDescription: subparserDescription)
2139 std::get<2>(childDescription) += indent + addindent;
2140 descriptions.push_back(std::move(childDescription));
2145 descriptions.emplace_back(
"",
"", indent + addindent);
2146 if (!Epilog().empty())
2148 descriptions.emplace_back(Epilog(),
"", indent + addindent);
2149 descriptions.emplace_back(
"",
"", indent + addindent);
2153 return descriptions;
2156 virtual void Validate(
const std::string &shortprefix,
const std::string &longprefix)
const override
2163 auto onValidationError = [&]
2165 std::ostringstream problem;
2166 problem <<
"Group validation failed somewhere!";
2167 #ifdef ARGS_NOEXCEPT
2168 error = Error::Validation;
2169 errorMsg = problem.str();
2171 throw ValidationError(problem.str());
2175 for (Base *child: Children())
2177 if (child->IsGroup() && !child->Matched())
2179 onValidationError();
2182 child->Validate(shortprefix, longprefix);
2185 if (subparser !=
nullptr)
2187 subparser->Validate(shortprefix, longprefix);
2190 onValidationError();
2194 if (selectedCommand ==
nullptr && commandIsRequired && (Group::HasCommand() || subparserHasCommand))
2196 std::ostringstream problem;
2197 problem <<
"Command is required";
2198 #ifdef ARGS_NOEXCEPT
2199 error = Error::Validation;
2200 errorMsg = problem.str();
2202 throw ValidationError(problem.str());
2207 virtual void Reset() noexcept
override
2210 selectedCommand =
nullptr;
2211 subparserProgramLine.clear();
2212 subparserDescription.clear();
2213 subparserHasFlag =
false;
2214 subparserHasPositional =
false;
2215 subparserHasCommand =
false;
2216 #ifdef ARGS_NOEXCEPT
2217 subparserError = Error::None;
2221 #ifdef ARGS_NOEXCEPT
2223 virtual Error GetError()
const override
2230 if (error != Error::None)
2235 if (subparserError != Error::None)
2237 return subparserError;
2240 return Group::GetError();
2252 std::string longprefix;
2253 std::string shortprefix;
2255 std::string longseparator;
2257 std::string terminator;
2259 bool allowJoinedShortValue =
true;
2260 bool allowJoinedLongValue =
true;
2261 bool allowSeparateShortValue =
true;
2262 bool allowSeparateLongValue =
true;
2265 bool readCompletion =
false;
2268 enum class OptionType
2275 OptionType ParseOption(
const std::string &s,
bool allowEmpty =
false)
2277 if (s.find(longprefix) == 0 && (allowEmpty || s.length() > longprefix.length()))
2279 return OptionType::LongFlag;
2282 if (s.find(shortprefix) == 0 && (allowEmpty || s.length() > shortprefix.length()))
2284 return OptionType::ShortFlag;
2287 return OptionType::Positional;
2290 template <
typename It>
2291 bool Complete(
FlagBase &flag, It it, It end)
2294 if (!readCompletion || (++nextIt != end))
2299 const auto &chunk = *it;
2302 AddCompletionReply(chunk, choice);
2305 #ifndef ARGS_NOEXCEPT
2321 template <
typename It>
2323 const bool allowSeparate,
const bool allowJoined,
2324 const bool hasJoined,
const std::string &joinedArg,
2325 const bool canDiscardJoined, std::vector<std::string> &values)
2331 if (hasJoined && !allowJoined && nargs.min != 0)
2333 return "Flag '" + arg +
"' was passed a joined argument, but these are disallowed";
2338 if (!canDiscardJoined || nargs.max != 0)
2340 values.push_back(joinedArg);
2342 }
else if (!allowSeparate)
2346 return "Flag '" + arg +
"' was passed a separate argument, but these are disallowed";
2353 while (valueIt != end &&
2354 values.size() < nargs.max &&
2355 (values.size() < nargs.min || ParseOption(*valueIt) == OptionType::Positional))
2357 if (Complete(flag, valueIt, end))
2363 values.push_back(*valueIt);
2369 if (values.size() > nargs.max)
2371 return "Passed an argument into a non-argument flag: " + arg;
2372 }
else if (values.size() < nargs.min)
2374 if (nargs.min == 1 && nargs.max == 1)
2376 return "Flag '" + arg +
"' requires an argument but received none";
2377 }
else if (nargs.min == 1)
2379 return "Flag '" + arg +
"' requires at least one argument but received none";
2380 }
else if (nargs.min != nargs.max)
2382 return "Flag '" + arg +
"' requires at least " + std::to_string(nargs.min) +
2383 " arguments but received " + std::to_string(values.size());
2386 return "Flag '" + arg +
"' requires " + std::to_string(nargs.min) +
2387 " arguments but received " + std::to_string(values.size());
2394 template <
typename It>
2395 bool ParseLong(It &it, It end)
2397 const auto &chunk = *it;
2398 const auto argchunk = chunk.substr(longprefix.size());
2400 const auto separator = longseparator.empty() ? argchunk.npos : argchunk.find(longseparator);
2402 const auto arg = (separator != argchunk.npos ?
2403 std::string(argchunk, 0, separator)
2405 const auto joined = (separator != argchunk.npos ?
2406 argchunk.substr(separator + longseparator.size())
2409 if (
auto flag = Match(arg))
2411 std::vector<std::string> values;
2412 const std::string errorMessage = ParseArgsValues(*flag, arg, it, end, allowSeparateLongValue, allowJoinedLongValue,
2413 separator != argchunk.npos, joined,
false, values);
2414 if (!errorMessage.empty())
2416 #ifndef ARGS_NOEXCEPT
2419 error = Error::Parse;
2420 errorMsg = errorMessage;
2425 if (!readCompletion)
2437 const std::string errorMessage(
"Flag could not be matched: " + arg);
2438 #ifndef ARGS_NOEXCEPT
2439 throw ParseError(errorMessage);
2441 error = Error::Parse;
2442 errorMsg = errorMessage;
2450 template <
typename It>
2451 bool ParseShort(It &it, It end)
2453 const auto &chunk = *it;
2454 const auto argchunk = chunk.substr(shortprefix.size());
2455 for (
auto argit = std::begin(argchunk); argit != std::end(argchunk); ++argit)
2457 const auto arg = *argit;
2459 if (
auto flag = Match(arg))
2461 const std::string value(argit + 1, std::end(argchunk));
2462 std::vector<std::string> values;
2463 const std::string errorMessage = ParseArgsValues(*flag, std::string(1, arg), it, end,
2464 allowSeparateShortValue, allowJoinedShortValue,
2465 !value.empty(), value, !value.empty(), values);
2467 if (!errorMessage.empty())
2469 #ifndef ARGS_NOEXCEPT
2470 throw ParseError(errorMessage);
2472 error = Error::Parse;
2473 errorMsg = errorMessage;
2478 if (!readCompletion)
2489 if (!values.empty())
2495 const std::string errorMessage(
"Flag could not be matched: '" + std::string(1, arg) +
"'");
2496 #ifndef ARGS_NOEXCEPT
2497 throw ParseError(errorMessage);
2499 error = Error::Parse;
2500 errorMsg = errorMessage;
2509 bool AddCompletionReply(
const std::string &cur,
const std::string &choice)
2511 if (cur.empty() || choice.find(cur) == 0)
2513 if (completion->syntax ==
"bash" && ParseOption(choice) == OptionType::LongFlag && choice.find(longseparator) != std::string::npos)
2515 completion->reply.push_back(choice.substr(choice.find(longseparator) + 1));
2518 completion->reply.push_back(choice);
2526 template <
typename It>
2527 bool Complete(It it, It end)
2530 if (!readCompletion || (++nextIt != end))
2535 const auto &chunk = *it;
2536 auto pos = GetNextPositional();
2537 std::vector<Command *> commands = GetCommands();
2538 const auto optionType = ParseOption(chunk,
true);
2540 if (!commands.empty() && (chunk.empty() || optionType == OptionType::Positional))
2542 for (
auto &cmd : commands)
2544 if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)
2546 AddCompletionReply(chunk, cmd->Name());
2551 bool hasPositionalCompletion =
true;
2553 if (!commands.empty())
2555 for (
auto &cmd : commands)
2557 if ((cmd->GetOptions() & Options::HiddenFromCompletion) == Options::None)
2559 AddCompletionReply(chunk, cmd->Name());
2564 if ((pos->GetOptions() & Options::HiddenFromCompletion) == Options::None)
2566 auto choices = pos->HelpChoices(helpParams);
2567 hasPositionalCompletion = !choices.empty() || optionType != OptionType::Positional;
2568 for (
auto &choice : choices)
2570 AddCompletionReply(chunk, choice);
2575 if (hasPositionalCompletion)
2577 auto flags = GetAllFlags();
2578 for (
auto flag : flags)
2580 if ((flag->GetOptions() & Options::HiddenFromCompletion) != Options::None)
2585 auto &matcher = flag->GetMatcher();
2586 if (!AddCompletionReply(chunk, matcher.
GetShortOrAny().str(shortprefix, longprefix)))
2590 if (AddCompletionReply(chunk, flagName.str(shortprefix, longprefix)))
2598 if (optionType == OptionType::LongFlag && allowJoinedLongValue)
2600 const auto separator = longseparator.empty() ? chunk.npos : chunk.find(longseparator);
2601 if (separator != chunk.npos)
2603 std::string arg(chunk, 0, separator);
2604 if (
auto flag = this->Match(arg.substr(longprefix.size())))
2606 for (
auto &choice : flag->
HelpChoices(helpParams))
2608 AddCompletionReply(chunk, arg + longseparator + choice);
2612 }
else if (optionType == OptionType::ShortFlag && allowJoinedShortValue)
2614 if (chunk.size() > shortprefix.size() + 1)
2616 auto arg = chunk.at(shortprefix.size());
2618 if (
auto flag = this->Match(arg))
2620 for (
auto &choice : flag->
HelpChoices(helpParams))
2622 AddCompletionReply(chunk, shortprefix + arg + choice);
2630 #ifndef ARGS_NOEXCEPT
2631 throw Completion(completion->
Get());
2637 template <
typename It>
2638 It Parse(It begin, It end)
2640 bool terminated =
false;
2641 std::vector<Command *> commands = GetCommands();
2644 for (
auto it = begin; it != end; ++it)
2646 if (Complete(it, end))
2651 const auto &chunk = *it;
2653 if (!terminated && chunk == terminator)
2656 }
else if (!terminated && ParseOption(chunk) == OptionType::LongFlag)
2658 if (!ParseLong(it, end))
2662 }
else if (!terminated && ParseOption(chunk) == OptionType::ShortFlag)
2664 if (!ParseShort(it, end))
2668 }
else if (!terminated && !commands.empty())
2670 auto itCommand = std::find_if(commands.begin(), commands.end(), [&chunk](Command *c) { return c->Name() == chunk; });
2671 if (itCommand == commands.end())
2673 const std::string errorMessage(
"Unknown command: " + chunk);
2674 #ifndef ARGS_NOEXCEPT
2675 throw ParseError(errorMessage);
2677 error = Error::Parse;
2678 errorMsg = errorMessage;
2683 SelectCommand(*itCommand);
2685 if (
const auto &coroutine = GetCoroutine())
2688 RaiiSubparser coro(*
this, std::vector<std::string>(it, end));
2689 coroutine(coro.Parser());
2690 #ifdef ARGS_NOEXCEPT
2692 if (error != Error::None)
2697 if (!coro.Parser().IsParsed())
2699 error = Error::Usage;
2703 if (!coro.Parser().IsParsed())
2705 throw UsageError(
"Subparser::Parse was not called");
2712 commands = GetCommands();
2715 auto pos = GetNextPositional();
2718 pos->ParseValue(chunk);
2726 const std::string errorMessage(
"Passed in argument, but no positional arguments were ready to receive it: " + chunk);
2727 #ifndef ARGS_NOEXCEPT
2728 throw ParseError(errorMessage);
2730 error = Error::Parse;
2731 errorMsg = errorMessage;
2737 if (!readCompletion && completion !=
nullptr && completion->Matched())
2739 #ifdef ARGS_NOEXCEPT
2740 error = Error::Completion;
2742 readCompletion =
true;
2744 const auto argsLeft =
static_cast<size_t>(std::distance(it, end));
2745 if (completion->cword == 0 || argsLeft <= 1 || completion->cword >= argsLeft)
2747 #ifndef ARGS_NOEXCEPT
2748 throw Completion(
"");
2752 std::vector<std::string> curArgs(++it, end);
2753 curArgs.resize(completion->cword);
2755 if (completion->syntax ==
"bash")
2758 for (
size_t idx = 0; idx < curArgs.size(); )
2760 if (idx > 0 && curArgs[idx] ==
"=")
2762 curArgs[idx - 1] +=
"=";
2764 const auto signedIdx =
static_cast<std::ptrdiff_t
>(idx);
2765 if (idx + 1 < curArgs.size())
2767 curArgs[idx - 1] += curArgs[idx + 1];
2768 curArgs.erase(curArgs.begin() + signedIdx, curArgs.begin() + signedIdx + 2);
2771 curArgs.erase(curArgs.begin() + signedIdx);
2780 #ifndef ARGS_NOEXCEPT
2783 Parse(curArgs.begin(), curArgs.end());
2784 throw Completion(
"");
2786 catch (Completion &)
2792 throw Completion(
"");
2795 return Parse(curArgs.begin(), curArgs.end());
2800 Validate(shortprefix, longprefix);
2805 HelpParams helpParams;
2807 ArgumentParser(
const std::string &description_,
const std::string &epilog_ = std::string())
2809 Description(description_);
2815 SetArgumentSeparations(
true,
true,
true,
true);
2819 void AddCompletion(CompletionFlag &completionFlag)
2821 completion = &completionFlag;
2822 Add(completionFlag);
2828 {
return helpParams.programName; }
2831 void Prog(
const std::string &prog_)
2832 { this->helpParams.programName = prog_; }
2837 {
return longprefix; }
2842 this->longprefix = longprefix_;
2843 this->helpParams.longPrefix = longprefix_;
2849 {
return shortprefix; }
2854 this->shortprefix = shortprefix_;
2855 this->helpParams.shortPrefix = shortprefix_;
2861 {
return longseparator; }
2866 if (longseparator_.empty())
2868 const std::string errorMessage(
"longseparator can not be set to empty");
2869 #ifdef ARGS_NOEXCEPT
2870 error = Error::Usage;
2871 errorMsg = errorMessage;
2877 this->longseparator = longseparator_;
2878 this->helpParams.longSeparator = allowJoinedLongValue ? longseparator_ :
" ";
2885 {
return terminator; }
2889 { this->terminator = terminator_; }
2896 bool &allowJoinedShortValue_,
2897 bool &allowJoinedLongValue_,
2898 bool &allowSeparateShortValue_,
2899 bool &allowSeparateLongValue_)
const
2901 allowJoinedShortValue_ = this->allowJoinedShortValue;
2902 allowJoinedLongValue_ = this->allowJoinedLongValue;
2903 allowSeparateShortValue_ = this->allowSeparateShortValue;
2904 allowSeparateLongValue_ = this->allowSeparateLongValue;
2915 const bool allowJoinedShortValue_,
2916 const bool allowJoinedLongValue_,
2917 const bool allowSeparateShortValue_,
2918 const bool allowSeparateLongValue_)
2920 this->allowJoinedShortValue = allowJoinedShortValue_;
2921 this->allowJoinedLongValue = allowJoinedLongValue_;
2922 this->allowSeparateShortValue = allowSeparateShortValue_;
2923 this->allowSeparateLongValue = allowSeparateLongValue_;
2925 this->helpParams.longSeparator = allowJoinedLongValue ? longseparator :
" ";
2926 this->helpParams.shortSeparator = allowJoinedShortValue ?
"" :
" ";
2931 void Help(std::ostream &help_)
const
2933 auto &command = SelectedCommand();
2934 const auto &commandDescription = command.Description().empty() ? command.Help() : command.Description();
2935 const auto description_text =
Wrap(commandDescription, helpParams.width - helpParams.descriptionindent);
2936 const auto epilog_text =
Wrap(command.Epilog(), helpParams.width - helpParams.descriptionindent);
2938 const bool hasoptions = command.HasFlag();
2939 const bool hasarguments = command.HasPositional();
2941 std::vector<std::string> prognameline;
2942 prognameline.push_back(helpParams.usageString);
2943 prognameline.push_back(Prog());
2944 auto commandProgLine = command.GetProgramLine(helpParams);
2945 prognameline.insert(prognameline.end(), commandProgLine.begin(), commandProgLine.end());
2947 const auto proglines =
Wrap(prognameline.begin(), prognameline.end(),
2948 helpParams.width - (helpParams.progindent + helpParams.progtailindent),
2949 helpParams.width - helpParams.progindent);
2950 auto progit = std::begin(proglines);
2951 if (progit != std::end(proglines))
2953 help_ << std::string(helpParams.progindent,
' ') << *progit <<
'\n';
2956 for (; progit != std::end(proglines); ++progit)
2958 help_ << std::string(helpParams.progtailindent,
' ') << *progit <<
'\n';
2963 if (!description_text.empty())
2965 for (
const auto &line: description_text)
2967 help_ << std::string(helpParams.descriptionindent,
' ') << line <<
"\n";
2972 bool lastDescriptionIsNewline =
false;
2974 if (!helpParams.optionsString.empty())
2976 help_ << std::string(helpParams.progindent,
' ') << helpParams.optionsString <<
"\n\n";
2979 for (
const auto &desc: command.GetDescription(helpParams, 0))
2981 lastDescriptionIsNewline = std::get<0>(desc).empty() && std::get<1>(desc).empty();
2982 const auto groupindent = std::get<2>(desc) * helpParams.eachgroupindent;
2983 const auto flags =
Wrap(std::get<0>(desc), helpParams.width - (helpParams.flagindent + helpParams.helpindent + helpParams.gutter));
2984 const auto info =
Wrap(std::get<1>(desc), helpParams.width - (helpParams.helpindent + groupindent));
2986 std::string::size_type flagssize = 0;
2987 for (
auto flagsit = std::begin(flags); flagsit != std::end(flags); ++flagsit)
2989 if (flagsit != std::begin(flags))
2993 help_ << std::string(groupindent + helpParams.flagindent,
' ') << *flagsit;
2994 flagssize =
Glyphs(*flagsit);
2997 auto infoit = std::begin(info);
2999 if ((helpParams.flagindent + flagssize + helpParams.gutter) > helpParams.helpindent || infoit == std::end(info) || helpParams.addNewlineBeforeDescription)
3005 help_ << std::string(helpParams.helpindent - (helpParams.flagindent + flagssize),
' ') << *infoit <<
'\n';
3008 for (; infoit != std::end(info); ++infoit)
3010 help_ << std::string(groupindent + helpParams.helpindent,
' ') << *infoit <<
'\n';
3013 if (hasoptions && hasarguments && helpParams.showTerminator)
3015 lastDescriptionIsNewline =
false;
3016 for (
const auto &item:
Wrap(std::string(
"\"") + terminator +
"\" can be used to terminate flag options and force all following arguments to be treated as positional options", helpParams.width - helpParams.flagindent))
3018 help_ << std::string(helpParams.flagindent,
' ') << item <<
'\n';
3022 if (!lastDescriptionIsNewline)
3027 for (
const auto &line: epilog_text)
3029 help_ << std::string(helpParams.descriptionindent,
' ') << line <<
"\n";
3039 std::ostringstream help_;
3044 virtual void Reset() noexcept
override
3048 readCompletion =
false;
3057 template <
typename It>
3062 #ifdef ARGS_NOEXCEPT
3064 if (error != Error::None)
3069 return Parse(begin, end);
3077 template <
typename T>
3080 return ParseArgs(std::begin(
args), std::end(
args));
3089 bool ParseCLI(
const int argc,
const char *
const * argv)
3095 const std::vector<std::string>
args(argv + 1, argv + argc);
3096 return ParseArgs(
args) == std::end(
args);
3099 template <
typename T>
3100 bool ParseCLI(
const T &
args)
3102 return ParseArgs(
args) == std::end(
args);
3106 inline Command::RaiiSubparser::RaiiSubparser(ArgumentParser &parser_, std::vector<std::string> args_)
3107 : command(parser_.SelectedCommand()), parser(std::move(args_), parser_, command, parser_.helpParams), oldSubparser(command.subparser)
3109 command.subparser = &parser;
3112 inline Command::RaiiSubparser::RaiiSubparser(
const Command &command_,
const HelpParams ¶ms_): command(command_), parser(command, params_), oldSubparser(command.subparser)
3114 command.subparser = &parser;
3122 command.subparserHasFlag =
HasFlag();
3126 if (parser ==
nullptr)
3128 #ifndef ARGS_NOEXCEPT
3129 throw args::SubparserError();
3131 error = Error::Subparser;
3136 auto it = parser->Parse(
args.begin(),
args.end());
3138 kicked.assign(it,
args.end());
3140 #ifdef ARGS_NOEXCEPT
3141 command.subparserError = GetError();
3145 inline std::ostream &operator<<(std::ostream &os,
const ArgumentParser &parser)
3156 Flag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
Options options_):
FlagBase(name_, help_, std::move(matcher_), options_)
3179 virtual void ParseValue(
const std::vector<std::string>&)
override
3191 HelpFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
Options options_ = {}):
Flag(group_, name_, help_, std::move(matcher_), options_) {}
3197 #ifdef ARGS_NOEXCEPT
3198 error = Error::Help;
3218 const int startcount;
3222 CounterFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const int startcount_ = 0,
Options options_ = {}):
3223 Flag(group_, name_, help_, std::move(matcher_), options_), startcount(startcount_), count(startcount_) {}
3229 auto me = FlagBase::Match(arg);
3244 virtual void Reset() noexcept
override
3256 std::function<void(
const std::vector<std::string> &)> action;
3260 ActionFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
Nargs nargs_, std::function<
void(
const std::vector<std::string> &)> action_,
Options options_ = {}):
3261 FlagBase(name_, help_, std::move(matcher_), options_), action(std::move(action_)), nargs(nargs_)
3266 ActionFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_, std::function<
void(
const std::string &)> action_,
Options options_ = {}):
3267 FlagBase(name_, help_, std::move(matcher_), options_), nargs(1)
3270 action = [action_](
const std::vector<std::string> &a) {
return action_(a.at(0)); };
3273 ActionFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_, std::function<
void()> action_,
Options options_ = {}):
3274 FlagBase(name_, help_, std::move(matcher_), options_), nargs(0)
3277 action = [action_](
const std::vector<std::string> &) {
return action_(); };
3283 virtual void ParseValue(
const std::vector<std::string> &value)
override
3295 template <
typename T>
3296 typename std::enable_if<!std::is_assignable<T, std::string>::value,
bool>::type
3297 operator ()(
const std::string &name,
const std::string &value, T &destination)
3299 std::istringstream ss(value);
3300 bool failed = !(ss >> destination);
3307 if (ss.rdbuf()->in_avail() > 0 || failed)
3309 #ifdef ARGS_NOEXCEPT
3313 std::ostringstream problem;
3314 problem <<
"Argument '" << name <<
"' received invalid value type '" << value <<
"'";
3321 template <
typename T>
3322 typename std::enable_if<std::is_assignable<T, std::string>::value,
bool>::type
3323 operator()(
const std::string &,
const std::string &value, T &destination)
3325 destination = value;
3344 virtual std::string GetDefaultString(
const HelpParams&)
const override
3346 return detail::ToString(defaultValue);
3354 ValueFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const T &defaultValue_,
Options options_):
ValueFlagBase(name_, help_, std::move(matcher_), options_), value(defaultValue_), defaultValue(defaultValue_)
3359 ValueFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const T &defaultValue_ = T(),
const bool extraError_ =
false):
ValueFlag(group_, name_, help_, std::move(matcher_), defaultValue_, extraError_ ?
Options::Single :
Options::None)
3363 ValueFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
Options options_):
ValueFlag(group_, name_, help_, std::move(matcher_), T(), options_)
3369 virtual void ParseValue(
const std::vector<std::string> &values_)
override
3371 const std::string &value_ = values_.at(0);
3373 #ifdef ARGS_NOEXCEPT
3374 if (!reader(name, value_, this->value))
3376 error = Error::Parse;
3379 reader(name, value_, this->value);
3383 virtual void Reset() noexcept
override
3385 ValueFlagBase::Reset();
3386 value = defaultValue;
3400 return defaultValue;
3411 typename Reader = ValueReader>
3419 ImplicitValueFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const T &implicitValue_,
const T &defaultValue_ = T(),
Options options_ = {})
3420 :
ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(implicitValue_)
3425 :
ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), defaultValue_, options_), implicitValue(defaultValue_)
3430 :
ValueFlag<T, Reader>(group_, name_, help_, std::move(matcher_), {}, options_), implicitValue()
3441 virtual void ParseValue(
const std::vector<std::string> &value_)
override
3445 this->value = implicitValue;
3461 template <
typename...>
class List = detail::vector,
3462 typename Reader = ValueReader>
3468 const List<T> defaultValues;
3474 typedef List<T> Container;
3475 typedef T value_type;
3476 typedef typename Container::allocator_type allocator_type;
3477 typedef typename Container::pointer pointer;
3478 typedef typename Container::const_pointer const_pointer;
3479 typedef T& reference;
3480 typedef const T& const_reference;
3481 typedef typename Container::size_type size_type;
3482 typedef typename Container::difference_type difference_type;
3483 typedef typename Container::iterator iterator;
3484 typedef typename Container::const_iterator const_iterator;
3485 typedef std::reverse_iterator<iterator> reverse_iterator;
3486 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
3489 :
FlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), defaultValues(defaultValues_),nargs(nargs_)
3501 virtual void ParseValue(
const std::vector<std::string> &values_)
override
3505 for (
const std::string &value : values_)
3508 #ifdef ARGS_NOEXCEPT
3509 if (!reader(name, value, v))
3511 error = Error::Parse;
3514 reader(name, value, v);
3516 values.insert(std::end(values), v);
3520 List<T> &Get() noexcept
3525 iterator begin() noexcept
3527 return values.begin();
3530 const_iterator begin() const noexcept
3532 return values.begin();
3535 const_iterator cbegin() const noexcept
3537 return values.cbegin();
3540 iterator end() noexcept
3542 return values.end();
3545 const_iterator end() const noexcept
3547 return values.end();
3550 const_iterator cend() const noexcept
3552 return values.cend();
3555 virtual void Reset() noexcept
override
3558 values = defaultValues;
3561 virtual FlagBase *Match(
const EitherFlag &arg)
override
3563 const bool wasMatched = Matched();
3564 auto me = FlagBase::Match(arg);
3565 if (me && !wasMatched)
3581 template <
typename...>
class List = detail::vector,
3582 typename Reader = ValueReader>
3586 using Container = List<T>;
3588 const Container defaultValues;
3593 typedef T value_type;
3594 typedef typename Container::allocator_type allocator_type;
3595 typedef typename Container::pointer pointer;
3596 typedef typename Container::const_pointer const_pointer;
3597 typedef T& reference;
3598 typedef const T& const_reference;
3599 typedef typename Container::size_type size_type;
3600 typedef typename Container::difference_type difference_type;
3601 typedef typename Container::iterator iterator;
3602 typedef typename Container::const_iterator const_iterator;
3603 typedef std::reverse_iterator<iterator> reverse_iterator;
3604 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
3606 ValueFlagList(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const Container &defaultValues_ = Container(),
Options options_ = {}):
3607 ValueFlagBase(name_, help_, std::move(matcher_), options_), values(defaultValues_), defaultValues(defaultValues_)
3614 virtual void ParseValue(
const std::vector<std::string> &values_)
override
3616 const std::string &value_ = values_.at(0);
3619 #ifdef ARGS_NOEXCEPT
3620 if (!reader(name, value_, v))
3622 error = Error::Parse;
3625 reader(name, value_, v);
3627 values.insert(std::end(values), v);
3637 virtual std::string Name()
const override
3639 return name + std::string(
"...");
3642 virtual void Reset() noexcept
override
3644 ValueFlagBase::Reset();
3645 values = defaultValues;
3648 virtual FlagBase *Match(
const EitherFlag &arg)
override
3650 const bool wasMatched = Matched();
3651 auto me = FlagBase::Match(arg);
3652 if (me && !wasMatched)
3659 iterator begin() noexcept
3661 return values.begin();
3664 const_iterator begin() const noexcept
3666 return values.begin();
3669 const_iterator cbegin() const noexcept
3671 return values.cbegin();
3674 iterator end() noexcept
3676 return values.end();
3679 const_iterator end() const noexcept
3681 return values.end();
3684 const_iterator cend() const noexcept
3686 return values.cend();
3700 typename Reader = ValueReader,
3701 template <
typename...>
class Map = detail::unordered_map>
3705 const Map<K, T> map;
3707 const T defaultValue;
3711 virtual std::vector<std::string> GetChoicesStrings(
const HelpParams &)
const override
3713 return detail::MapKeysToStrings(map);
3718 MapFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const Map<K, T> &map_,
const T &defaultValue_,
Options options_):
ValueFlagBase(name_, help_, std::move(matcher_), options_), map(map_), value(defaultValue_), defaultValue(defaultValue_)
3723 MapFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const Map<K, T> &map_,
const T &defaultValue_ = T(),
const bool extraError_ =
false):
MapFlag(group_, name_, help_, std::move(matcher_), map_, defaultValue_, extraError_ ?
Options::Single :
Options::None)
3727 MapFlag(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const Map<K, T> &map_,
Options options_):
MapFlag(group_, name_, help_, std::move(matcher_), map_, T(), options_)
3733 virtual void ParseValue(
const std::vector<std::string> &values_)
override
3735 const std::string &value_ = values_.at(0);
3738 #ifdef ARGS_NOEXCEPT
3739 if (!reader(name, value_, key))
3741 error = Error::Parse;
3744 reader(name, value_, key);
3746 auto it = map.find(key);
3747 if (it == std::end(map))
3749 std::ostringstream problem;
3750 problem <<
"Could not find key '" << key <<
"' in map for arg '" << name <<
"'";
3751 #ifdef ARGS_NOEXCEPT
3753 errorMsg = problem.str();
3759 this->value = it->second;
3770 virtual void Reset() noexcept
override
3772 ValueFlagBase::Reset();
3773 value = defaultValue;
3788 template <
typename...>
class List = detail::vector,
3789 typename Reader = ValueReader,
3790 template <
typename...>
class Map = detail::unordered_map>
3794 using Container = List<T>;
3795 const Map<K, T> map;
3797 const Container defaultValues;
3801 virtual std::vector<std::string> GetChoicesStrings(
const HelpParams &)
const override
3803 return detail::MapKeysToStrings(map);
3807 typedef T value_type;
3808 typedef typename Container::allocator_type allocator_type;
3809 typedef typename Container::pointer pointer;
3810 typedef typename Container::const_pointer const_pointer;
3811 typedef T& reference;
3812 typedef const T& const_reference;
3813 typedef typename Container::size_type size_type;
3814 typedef typename Container::difference_type difference_type;
3815 typedef typename Container::iterator iterator;
3816 typedef typename Container::const_iterator const_iterator;
3817 typedef std::reverse_iterator<iterator> reverse_iterator;
3818 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
3820 MapFlagList(
Group &group_,
const std::string &name_,
const std::string &help_,
Matcher &&matcher_,
const Map<K, T> &map_,
const Container &defaultValues_ = Container()):
ValueFlagBase(name_, help_, std::move(matcher_)), map(map_), values(defaultValues_), defaultValues(defaultValues_)
3827 virtual void ParseValue(
const std::vector<std::string> &values_)
override
3829 const std::string &value = values_.at(0);
3832 #ifdef ARGS_NOEXCEPT
3833 if (!reader(name, value, key))
3835 error = Error::Parse;
3838 reader(name, value, key);
3840 auto it = map.find(key);
3841 if (it == std::end(map))
3843 std::ostringstream problem;
3844 problem <<
"Could not find key '" << key <<
"' in map for arg '" << name <<
"'";
3845 #ifdef ARGS_NOEXCEPT
3847 errorMsg = problem.str();
3853 this->values.emplace_back(it->second);
3864 virtual std::string Name()
const override
3866 return name + std::string(
"...");
3869 virtual void Reset() noexcept
override
3871 ValueFlagBase::Reset();
3872 values = defaultValues;
3875 virtual FlagBase *Match(
const EitherFlag &arg)
override
3877 const bool wasMatched = Matched();
3878 auto me = FlagBase::Match(arg);
3879 if (me && !wasMatched)
3886 iterator begin() noexcept
3888 return values.begin();
3891 const_iterator begin() const noexcept
3893 return values.begin();
3896 const_iterator cbegin() const noexcept
3898 return values.cbegin();
3901 iterator end() noexcept
3903 return values.end();
3906 const_iterator end() const noexcept
3908 return values.end();
3911 const_iterator cend() const noexcept
3913 return values.cend();
3924 typename Reader = ValueReader>
3929 const T defaultValue;
3932 Positional(
Group &group_,
const std::string &name_,
const std::string &help_,
const T &defaultValue_ = T(),
Options options_ = {}):
PositionalBase(name_, help_, options_), value(defaultValue_), defaultValue(defaultValue_)
3943 virtual void ParseValue(
const std::string &value_)
override
3945 #ifdef ARGS_NOEXCEPT
3946 if (!reader(name, value_, this->value))
3948 error = Error::Parse;
3951 reader(name, value_, this->value);
3964 virtual void Reset() noexcept
override
3966 PositionalBase::Reset();
3967 value = defaultValue;
3979 template <
typename...>
class List = detail::vector,
3980 typename Reader = ValueReader>
3984 using Container = List<T>;
3986 const Container defaultValues;
3990 typedef T value_type;
3991 typedef typename Container::allocator_type allocator_type;
3992 typedef typename Container::pointer pointer;
3993 typedef typename Container::const_pointer const_pointer;
3994 typedef T& reference;
3995 typedef const T& const_reference;
3996 typedef typename Container::size_type size_type;
3997 typedef typename Container::difference_type difference_type;
3998 typedef typename Container::iterator iterator;
3999 typedef typename Container::const_iterator const_iterator;
4000 typedef std::reverse_iterator<iterator> reverse_iterator;
4001 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
4003 PositionalList(
Group &group_,
const std::string &name_,
const std::string &help_,
const Container &defaultValues_ = Container(),
Options options_ = {}):
PositionalBase(name_, help_, options_), values(defaultValues_), defaultValues(defaultValues_)
4014 virtual void ParseValue(
const std::string &value_)
override
4017 #ifdef ARGS_NOEXCEPT
4018 if (!reader(name, value_, v))
4020 error = Error::Parse;
4023 reader(name, value_, v);
4025 values.insert(std::end(values), v);
4029 virtual std::string Name()
const override
4031 return name + std::string(
"...");
4041 virtual void Reset() noexcept
override
4043 PositionalBase::Reset();
4044 values = defaultValues;
4047 virtual PositionalBase *GetNextPositional()
override
4049 const bool wasMatched = Matched();
4050 auto me = PositionalBase::GetNextPositional();
4051 if (me && !wasMatched)
4058 iterator begin() noexcept
4060 return values.begin();
4063 const_iterator begin() const noexcept
4065 return values.begin();
4068 const_iterator cbegin() const noexcept
4070 return values.cbegin();
4073 iterator end() noexcept
4075 return values.end();
4078 const_iterator end() const noexcept
4080 return values.end();
4083 const_iterator cend() const noexcept
4085 return values.cend();
4099 typename Reader = ValueReader,
4100 template <
typename...>
class Map = detail::unordered_map>
4104 const Map<K, T> map;
4106 const T defaultValue;
4110 virtual std::vector<std::string> GetChoicesStrings(
const HelpParams &)
const override
4112 return detail::MapKeysToStrings(map);
4117 MapPositional(
Group &group_,
const std::string &name_,
const std::string &help_,
const Map<K, T> &map_,
const T &defaultValue_ = T(),
Options options_ = {}):
4118 PositionalBase(name_, help_, options_), map(map_), value(defaultValue_), defaultValue(defaultValue_)
4125 virtual void ParseValue(
const std::string &value_)
override
4128 #ifdef ARGS_NOEXCEPT
4129 if (!reader(name, value_, key))
4131 error = Error::Parse;
4134 reader(name, value_, key);
4136 auto it = map.find(key);
4137 if (it == std::end(map))
4139 std::ostringstream problem;
4140 problem <<
"Could not find key '" << key <<
"' in map for arg '" << name <<
"'";
4141 #ifdef ARGS_NOEXCEPT
4143 errorMsg = problem.str();
4149 this->value = it->second;
4162 virtual void Reset() noexcept
override
4164 PositionalBase::Reset();
4165 value = defaultValue;
4180 template <
typename...>
class List = detail::vector,
4181 typename Reader = ValueReader,
4182 template <
typename...>
class Map = detail::unordered_map>
4186 using Container = List<T>;
4188 const Map<K, T> map;
4190 const Container defaultValues;
4194 virtual std::vector<std::string> GetChoicesStrings(
const HelpParams &)
const override
4196 return detail::MapKeysToStrings(map);
4200 typedef T value_type;
4201 typedef typename Container::allocator_type allocator_type;
4202 typedef typename Container::pointer pointer;
4203 typedef typename Container::const_pointer const_pointer;
4204 typedef T& reference;
4205 typedef const T& const_reference;
4206 typedef typename Container::size_type size_type;
4207 typedef typename Container::difference_type difference_type;
4208 typedef typename Container::iterator iterator;
4209 typedef typename Container::const_iterator const_iterator;
4210 typedef std::reverse_iterator<iterator> reverse_iterator;
4211 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
4213 MapPositionalList(
Group &group_,
const std::string &name_,
const std::string &help_,
const Map<K, T> &map_,
const Container &defaultValues_ = Container(),
Options options_ = {}):
4214 PositionalBase(name_, help_, options_), map(map_), values(defaultValues_), defaultValues(defaultValues_)
4221 virtual void ParseValue(
const std::string &value_)
override
4224 #ifdef ARGS_NOEXCEPT
4225 if (!reader(name, value_, key))
4227 error = Error::Parse;
4230 reader(name, value_, key);
4232 auto it = map.find(key);
4233 if (it == std::end(map))
4235 std::ostringstream problem;
4236 problem <<
"Could not find key '" << key <<
"' in map for arg '" << name <<
"'";
4237 #ifdef ARGS_NOEXCEPT
4239 errorMsg = problem.str();
4245 this->values.emplace_back(it->second);
4257 virtual std::string Name()
const override
4259 return name + std::string(
"...");
4262 virtual void Reset() noexcept
override
4264 PositionalBase::Reset();
4265 values = defaultValues;
4268 virtual PositionalBase *GetNextPositional()
override
4270 const bool wasMatched = Matched();
4271 auto me = PositionalBase::GetNextPositional();
4272 if (me && !wasMatched)
4279 iterator begin() noexcept
4281 return values.begin();
4284 const_iterator begin() const noexcept
4286 return values.begin();
4289 const_iterator cbegin() const noexcept
4291 return values.cbegin();
4294 iterator end() noexcept
4296 return values.end();
4299 const_iterator end() const noexcept
4301 return values.end();
4304 const_iterator cend() const noexcept
4306 return values.cend();
A flag class that calls a function when it's matched.
Definition: args.hxx:3254
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:3280
virtual void ParseValue(const std::vector< std::string > &value) override
Parse values of this option.
Definition: args.hxx:3283
The main user facing command line argument parser class.
Definition: args.hxx:2248
void SetArgumentSeparations(const bool allowJoinedShortValue_, const bool allowJoinedLongValue_, const bool allowSeparateShortValue_, const bool allowSeparateLongValue_)
Change allowed option separation.
Definition: args.hxx:2914
void Prog(const std::string &prog_)
The program name for help generation.
Definition: args.hxx:2831
const std::string & LongPrefix() const
The prefix for long flags.
Definition: args.hxx:2836
It ParseArgs(It begin, It end)
Parse all arguments.
Definition: args.hxx:3058
void LongPrefix(const std::string &longprefix_)
The prefix for long flags.
Definition: args.hxx:2840
void LongSeparator(const std::string &longseparator_)
The separator for long flags.
Definition: args.hxx:2864
void Help(std::ostream &help_) const
Pass the help menu into an ostream.
Definition: args.hxx:2931
const std::string & LongSeparator() const
The separator for long flags.
Definition: args.hxx:2860
bool ParseCLI(const int argc, const char *const *argv)
Convenience function to parse the CLI from argc and argv.
Definition: args.hxx:3089
auto ParseArgs(const T &args) -> decltype(std::begin(args))
Parse all arguments.
Definition: args.hxx:3078
void Terminator(const std::string &terminator_)
The terminator that forcibly separates flags from positionals.
Definition: args.hxx:2888
void GetArgumentSeparations(bool &allowJoinedShortValue_, bool &allowJoinedLongValue_, bool &allowSeparateShortValue_, bool &allowSeparateLongValue_) const
Get the current argument separation parameters.
Definition: args.hxx:2895
const std::string & Prog() const
The program name for help generation.
Definition: args.hxx:2827
std::string Help() const
Generate a help menu as a string.
Definition: args.hxx:3037
void ShortPrefix(const std::string &shortprefix_)
The prefix for short flags.
Definition: args.hxx:2852
const std::string & Terminator() const
The terminator that forcibly separates flags from positionals.
Definition: args.hxx:2884
std::string ParseArgsValues(FlagBase &flag, const std::string &arg, It &it, It end, const bool allowSeparate, const bool allowJoined, const bool hasJoined, const std::string &joinedArg, const bool canDiscardJoined, std::vector< std::string > &values)
(INTERNAL) Parse flag's values
Definition: args.hxx:2322
const std::string & ShortPrefix() const
The prefix for short flags.
Definition: args.hxx:2848
Base class for all match types.
Definition: args.hxx:794
void KickOut(bool kickout_) noexcept
Sets a kick-out value for building subparsers.
Definition: args.hxx:889
bool KickOut() const noexcept
Gets the kick-out value for building subparsers.
Definition: args.hxx:902
Main class for building subparsers.
Definition: args.hxx:1712
const std::string & Description() const
The description that appears above options.
Definition: args.hxx:1827
virtual PositionalBase * GetNextPositional() override
Get the next ready positional, or nullptr if there is none.
Definition: args.hxx:1948
const std::string & Help() const
The description of command.
Definition: args.hxx:1852
const std::string & ProglinePostfix() const
The description that appears on the prog line after options.
Definition: args.hxx:1817
virtual std::vector< std::string > GetProgramLine(const HelpParams ¶ms) const override
Get the names of positional parameters.
Definition: args.hxx:2049
void Description(const std::string &description_)
The description that appears above options.
Definition: args.hxx:1832
virtual bool HasPositional() const override
Get whether this has any PositionalBase children.
Definition: args.hxx:1984
void Epilog(const std::string &epilog_)
The description that appears below options.
Definition: args.hxx:1842
void ProglinePostfix(const std::string &proglinePostfix_)
The description that appears on the prog line after options.
Definition: args.hxx:1822
const std::string & Epilog() const
The description that appears below options.
Definition: args.hxx:1837
const std::string & Name() const
The name of command.
Definition: args.hxx:1847
virtual bool HasCommand() const override
Get whether this has any Command children.
Definition: args.hxx:1989
virtual bool HasFlag() const override
Get whether this has any FlagBase children.
Definition: args.hxx:1979
virtual FlagBase * Match(const EitherFlag &flag) override
Return the first FlagBase that matches flag, or nullptr.
Definition: args.hxx:1884
virtual bool Matched() const noexcept override
Whether or not this group matches validation.
Definition: args.hxx:1865
void RequireCommand(bool value)
If value is true, parser will fail if no command was parsed.
Definition: args.hxx:1859
virtual std::vector< std::tuple< std::string, std::string, unsigned > > GetDescription(const HelpParams ¶ms, const unsigned int indent) const override
Get all the child descriptions for help generation.
Definition: args.hxx:2074
Definition: args.hxx:1238
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:1252
std::string Get() noexcept
Get the completion reply.
Definition: args.hxx:1265
virtual void ParseValue(const std::vector< std::string > &value_) override
Parse values of this option.
Definition: args.hxx:1257
An exception that contains autocompletion reply.
Definition: args.hxx:343
A flag class that simply counts the number of times it's matched.
Definition: args.hxx:3216
int & Get() noexcept
Get the count.
Definition: args.hxx:3239
Base error class.
Definition: args.hxx:262
Base class for all flag options.
Definition: args.hxx:1081
virtual void ParseValue(const std::vector< std::string > &value)=0
Parse values of this option.
virtual Nargs NumberOfArguments() const noexcept=0
Defines how many values can be consumed by this option.
Boolean argument matcher.
Definition: args.hxx:3154
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:3174
virtual void ParseValue(const std::vector< std::string > &) override
Parse values of this option.
Definition: args.hxx:3179
bool Get() const
Get whether this was matched.
Definition: args.hxx:3169
Class for using global options in ArgumentParser.
Definition: args.hxx:1631
Class for all kinds of validating groups, including ArgumentParser.
Definition: args.hxx:1343
virtual bool HasCommand() const override
Get whether this has any Command children.
Definition: args.hxx:1497
virtual FlagBase * Match(const EitherFlag &flag) override
Return the first FlagBase that matches flag, or nullptr.
Definition: args.hxx:1428
virtual bool HasPositional() const override
Get whether this has any PositionalBase children.
Definition: args.hxx:1488
Group(Group &group_, const std::string &help_=std::string(), const std::function< bool(const Group &)> &validator_=Validators::DontCare, Options options_={})
If help is empty, this group will not be printed in help output.
Definition: args.hxx:1403
virtual std::vector< std::tuple< std::string, std::string, unsigned > > GetDescription(const HelpParams ¶ms, const unsigned int indent) const override
Get all the child descriptions for help generation.
Definition: args.hxx:1527
std::vector< Base * >::size_type MatchedChildren() const
Count the number of matched children this group has.
Definition: args.hxx:1504
virtual bool HasFlag() const override
Get whether this has any FlagBase children.
Definition: args.hxx:1479
Group(const std::string &help_=std::string(), const std::function< bool(const Group &)> &validator_=Validators::DontCare, Options options_={})
If help is empty, this group will not be printed in help output.
Definition: args.hxx:1401
virtual bool Matched() const noexcept override
Whether or not this group matches validation.
Definition: args.hxx:1513
virtual std::vector< std::string > GetProgramLine(const HelpParams ¶ms) const override
Get the names of positional parameters.
Definition: args.hxx:1557
const std::vector< Base * > & Children() const
Get all this group's children.
Definition: args.hxx:1418
bool Get() const
Get validation.
Definition: args.hxx:1520
virtual PositionalBase * GetNextPositional() override
Get the next ready positional, or nullptr if there is none.
Definition: args.hxx:1463
void Add(Base &child)
Append a child to this Group.
Definition: args.hxx:1411
Help flag class.
Definition: args.hxx:3189
bool Get() const noexcept
Get whether this was matched.
Definition: args.hxx:3207
virtual void ParseValue(const std::vector< std::string > &)
Parse values of this option.
Definition: args.hxx:3195
An exception that indicates that the user has requested help.
Definition: args.hxx:325
An optional argument-accepting flag class.
Definition: args.hxx:3413
virtual void ParseValue(const std::vector< std::string > &value_) override
Parse values of this option.
Definition: args.hxx:3441
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:3436
Errors in map lookups.
Definition: args.hxx:307
A mapping value flag list class.
Definition: args.hxx:3792
Container & Get() noexcept
Get the value.
Definition: args.hxx:3859
virtual void ParseValue(const std::vector< std::string > &values_) override
Parse values of this option.
Definition: args.hxx:3827
A mapping value flag class.
Definition: args.hxx:3703
virtual void ParseValue(const std::vector< std::string > &values_) override
Parse values of this option.
Definition: args.hxx:3733
T & Get() noexcept
Get the value.
Definition: args.hxx:3765
A positional argument mapping list class.
Definition: args.hxx:4184
Container & Get() noexcept
Get the value.
Definition: args.hxx:4252
A positional argument mapping class.
Definition: args.hxx:4102
T & Get() noexcept
Get the value.
Definition: args.hxx:4157
A class of "matchers", specifying short and flags that can possibly be matched.
Definition: args.hxx:411
std::vector< EitherFlag > GetFlagStrings() const
(INTERNAL) Get all flag strings as a vector, with the prefixes embedded
Definition: args.hxx:494
EitherFlag GetShortOrAny() const
(INTERNAL) Get short flag if it exists or any long flag
Definition: args.hxx:529
Matcher(Short &&shortIn, Long &&longIn)
Specify short and long flags separately as iterables.
Definition: args.hxx:447
Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd)
Specify short and long flags separately as iterators.
Definition: args.hxx:422
bool Match(const std::string &flag) const
(INTERNAL) Check if there is a match of a long flag
Definition: args.hxx:480
EitherFlag GetLongOrAny() const
(INTERNAL) Get long flag if it exists or any short flag
Definition: args.hxx:511
bool Match(const char flag) const
(INTERNAL) Check if there is a match of a short flag
Definition: args.hxx:473
bool Match(const EitherFlag &flag) const
(INTERNAL) Check if there is a match of a flag
Definition: args.hxx:487
Matcher(std::initializer_list< EitherFlag > in)
Specify a mixed single initializer-list of both short and long flags.
Definition: args.hxx:463
Base class for all match types that have a name.
Definition: args.hxx:934
void HelpDefault(const std::string &str)
Sets default value string that will be added to argument description.
Definition: args.hxx:970
void HelpChoices(const std::vector< std::string > &array)
Sets choices strings that will be added to argument description.
Definition: args.hxx:986
std::string HelpDefault(const HelpParams ¶ms) const
Gets default value string that will be added to argument description.
Definition: args.hxx:978
std::vector< std::string > HelpChoices(const HelpParams ¶ms) const
Gets choices strings that will be added to argument description.
Definition: args.hxx:994
A variadic arguments accepting flag class.
Definition: args.hxx:3464
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:3496
virtual void ParseValue(const std::vector< std::string > &values_) override
Parse values of this option.
Definition: args.hxx:3501
Errors that occur during regular parsing.
Definition: args.hxx:280
Base class for positional options.
Definition: args.hxx:1283
A positional argument class that pushes the found values into a list.
Definition: args.hxx:3982
Container & Get() noexcept
Get the values.
Definition: args.hxx:4036
A positional argument class.
Definition: args.hxx:3926
T & Get() noexcept
Get the value.
Definition: args.hxx:3959
Errors that when a required flag is omitted.
Definition: args.hxx:298
Utility class for building subparsers with coroutines/callbacks.
Definition: args.hxx:1657
void Parse()
Continue parsing arguments for new command.
Definition: args.hxx:3117
const std::vector< std::string > & KickedOut() const noexcept
Returns a vector of kicked out arguments.
Definition: args.hxx:1701
bool IsParsed() const
(INTERNAL) Determines whether Parse was called or not.
Definition: args.hxx:1688
Errors that occur during usage.
Definition: args.hxx:271
Errors that are detected from group validation after parsing finishes.
Definition: args.hxx:289
Base class for value-accepting flag options.
Definition: args.hxx:1225
virtual Nargs NumberOfArguments() const noexcept override
Defines how many values can be consumed by this option.
Definition: args.hxx:1231
An argument-accepting flag class that pushes the found values into a list.
Definition: args.hxx:3584
Container & Get() noexcept
Get the values.
Definition: args.hxx:3632
virtual void ParseValue(const std::vector< std::string > &values_) override
Parse values of this option.
Definition: args.hxx:3614
An argument-accepting flag class.
Definition: args.hxx:3339
T & Get() noexcept
Get the value.
Definition: args.hxx:3391
const T & GetDefault() noexcept
Get the default value.
Definition: args.hxx:3398
virtual void ParseValue(const std::vector< std::string > &values_) override
Parse values of this option.
Definition: args.hxx:3369
Definition: args.hxx:1029
contains all the functionality of the args library
Options
Attributes for flags.
Definition: args.hxx:549
@ HiddenFromCompletion
Flag is excluded from auto completion.
@ Global
Flag is global and can be used in any subcommand.
@ Single
Flag can't be passed multiple times.
@ HiddenFromUsage
Flag is excluded from usage line.
@ Hidden
Flag is excluded from options help and usage line.
@ Required
Flag can't be omitted.
@ KickOut
Flag stops a parser.
@ HiddenFromDescription
Flag is excluded from options help.
auto get(Option &option_) -> decltype(option_.Get())
Getter to grab the value from the argument type.
Definition: args.hxx:76
std::string::size_type Glyphs(const std::string &string_)
(INTERNAL) Count UTF-8 glyphs
Definition: args.hxx:89
std::vector< std::string > Wrap(const std::string &in, const std::string::size_type width, std::string::size_type firstlinewidth=0)
(INTERNAL) Wrap a string into a vector of lines
Definition: args.hxx:212
A simple unified option type for unified initializer lists for the Matcher class.
Definition: args.hxx:353
static std::unordered_set< std::string > GetLong(std::initializer_list< EitherFlag > flags)
Get just the long flags from an initializer list of EitherFlags.
Definition: args.hxx:363
static std::unordered_set< char > GetShort(std::initializer_list< EitherFlag > flags)
Get just the short flags from an initializer list of EitherFlags.
Definition: args.hxx:378
Default validators.
Definition: args.hxx:1352
A simple structure of parameters for easy user-modifyable help menus.
Definition: args.hxx:605
std::string programName
The program name for help generation.
Definition: args.hxx:662
bool showCommandFullHelp
Show command's descriptions and epilog.
Definition: args.hxx:670
bool proglineShowFlags
Show flags in program line.
Definition: args.hxx:706
std::string usageString
Program line prefix.
Definition: args.hxx:714
std::string proglineNonrequiredClose
The postfix for progline non-required argument.
Definition: args.hxx:702
bool proglinePreferShortFlags
Use short flags in program lines when possible.
Definition: args.hxx:710
std::string proglineCommand
The prefix for progline when command has any subcommands.
Definition: args.hxx:678
std::string proglineOptions
The postfix for progline when showProglineOptions is true and command has any flags.
Definition: args.hxx:674
std::string longSeparator
The separator for long flags.
Definition: args.hxx:658
bool showValueName
Show value name.
Definition: args.hxx:726
std::string proglineValueOpen
The prefix for progline value.
Definition: args.hxx:682
std::string valueOpen
The prefix for option value.
Definition: args.hxx:734
std::string proglineNonrequiredOpen
The prefix for progline non-required argument.
Definition: args.hxx:698
bool showCommandChildren
Show command's flags.
Definition: args.hxx:666
bool showProglineOptions
Show the {OPTIONS} on the prog line when this is true.
Definition: args.hxx:638
std::string valueClose
The postfix for option value.
Definition: args.hxx:738
std::string longPrefix
The prefix for long flags.
Definition: args.hxx:650
std::string proglineRequiredClose
The postfix for progline required argument.
Definition: args.hxx:694
std::string shortPrefix
The prefix for short flags.
Definition: args.hxx:646
bool addDefault
Add default values to argument description.
Definition: args.hxx:750
std::string shortSeparator
The separator for short flags.
Definition: args.hxx:654
std::string proglineValueClose
The postfix for progline value.
Definition: args.hxx:686
bool useValueNameOnce
Display value name after all the long and short flags.
Definition: args.hxx:722
std::string defaultString
The prefix for default values.
Definition: args.hxx:754
std::string proglineRequiredOpen
The prefix for progline required argument.
Definition: args.hxx:690
bool addChoices
Add choices to argument description.
Definition: args.hxx:742
std::string choiceString
The prefix for choices.
Definition: args.hxx:746
A number of arguments which can be consumed by an option.
Definition: args.hxx:762
A default Reader class for argument classes.
Definition: args.hxx:3294