diff options
author | Taylor C. Richberger <Taywee@gmx.com> | 2016-05-10 16:40:57 -0600 |
---|---|---|
committer | Taylor C. Richberger <Taywee@gmx.com> | 2016-05-10 16:40:57 -0600 |
commit | eef2da1547ba10b61c232a0df19374c5efbb7597 (patch) | |
tree | bb25dab0d4b962607b02cae9fa230fb4e9847662 | |
parent | improve help generation (diff) | |
download | args.hxx-eef2da1547ba10b61c232a0df19374c5efbb7597.tar.xz |
rename everything4.0.0
-rw-r--r-- | CHANGELOG | 11 | ||||
-rw-r--r-- | CONTRIBUTING.md | 3 | ||||
-rw-r--r-- | Doxyfile | 2 | ||||
-rw-r--r-- | README.md | 108 | ||||
-rw-r--r-- | args.hxx | 356 | ||||
-rw-r--r-- | test.cxx | 74 |
6 files changed, 283 insertions, 271 deletions
@@ -0,0 +1,11 @@ +* 4.0.0 +Changed all wording: + +ArgFlag -> ValueFlag +Counter -> CounterFlag +PosArg -> Positional + +Argument now solely refers to command line arguments. +Value refers to the argument that flags or positionals can take and store. +Positional is a positional option, which contains a value. +Option refers to flags and positionals, which can contain values. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0231691..59f6696 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,4 @@ * Use Allman style * Don't use any non-standard-library libraries -* Keep everything in the args namespace
\ No newline at end of file +* Keep everything in the args namespace +* Keep it simple and fast @@ -38,7 +38,7 @@ PROJECT_NAME = "args" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 3.0.4 +PROJECT_NUMBER = 4.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -5,8 +5,9 @@ A simple, small, flexible, single-header C++11 argument parsing library, in about 1K lines of code. -This is designed to somewhat replicate the behavior of Python's argparse, but -in C++, with static type checking, and hopefully a lot faster. +This is designed to appear somewhat similar to Python's argparse, but in C++, +with static type checking, and hopefully a lot faster (also allowing fully +nestable group logic, where Python's argparse does not). UTF-8 support is limited at best. No normalization is performed, so non-ascii characters are very best kept out of flags, and combined glyphs are probably @@ -31,16 +32,16 @@ There are also somewhat extensive examples below. It: -* lets you handle flags, flag+arguments, and positional arguments simply and - elegently, with the full help of static typechecking. +* lets you handle flags, flag+value, and positional arguments simply and + elegently, with the full help of static typechecking. * allows you to use your own types in a pretty simple way. * lets you use count flags, and lists of all argument-accepting types. * Allows full validation of groups of required arguments, though output isn't - pretty when something fails group validation. User validation functions are - accepted. Groups are fully nestable. + pretty when something fails group validation. User validation functions are + accepted. Groups are fully nestable. * Generates pretty help for you, with some good tweakable parameters. * Lets you customize all prefixes and most separators, allowing you to create - an infinite number of different argument syntaxes + an infinite number of different argument syntaxes * Lets you parse, by default, any type that has a stream extractor operator for it. If this doesn't work for your uses, you can supply a function and parse the string yourself if you like. @@ -56,14 +57,13 @@ There are tons of things this library does not do! ## It will not ever: * Allow you to create subparsers like argparse in a master parser (you can do - this yourself with iterators and multiple parsers) -* Allow one argument flag to take a specific number of arguments - (like `--foo first second`). You can instead split that with a flag list - (`--foo first --foo second`) or a custom type extraction - (`--foo first,second`) + this yourself with iterators and multiple parsers) +* Allow one argument flag to take a specific number of arguments (like `--foo + first second`). You can instead split that with a flag list (`--foo first + --foo second`) or a custom type extraction (`--foo first,second`) * Allow you to intermix multiple different prefix types (eg. `++foo` and - `--foo` in the same parser), though shortopt and longopt prefixes can be - different. + `--foo` in the same parser), though shortopt and longopt prefixes can be + different. * Allow you to have argument flags only optionally accept arguments * Allow you to make flag arguments sensitive to order (like gnu find), or make them sensitive to relative ordering with positional flags. The only @@ -72,12 +72,12 @@ There are tons of things this library does not do! * List positional options or flag arguments to each of their own respective items * Allow you to use a positional argument list before any other positional - arguments (the last argument list will slurp all subsequent positional - arguments). The logic for allowing this would be a lot more code than I'd - like, and would make static checking much more difficult, requiring us to - sort std::string arguments and pair them to positional arguments before - assigning them, rather than what we currently do, which is assiging them as - we go for better simplicity and speed. + arguments (the last argument list will slurp all subsequent positional + arguments). The logic for allowing this would be a lot more code than I'd + like, and would make static checking much more difficult, requiring us to + sort std::string arguments and pair them to positional arguments before + assigning them, rather than what we currently do, which is assiging them as + we go for better simplicity and speed. # How do I install it? @@ -174,9 +174,9 @@ int main() { std::vector<std::string> arguments(carguments); args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<int> integer(parser, "integer", "The integer flag", args::Matcher{'i', "int"}); - args::ArgFlagList<char> characters(parser, "characters", "The character flag", args::Matcher{'c', "char"}); - args::PosArgList<double> numbers(parser, "numbers", "The numbers position list"); + args::ValueFlag<int> integer(parser, "integer", "The integer flag", args::Matcher{'i', "int"}); + args::ValueFlagList<char> characters(parser, "characters", "The character flag", args::Matcher{'c', "char"}); + args::PositionalList<double> numbers(parser, "numbers", "The numbers position list"); parser.ParseArgs(arguments); const int i = args::get(integer); const std::vector<char> c(args::get(characters)); @@ -409,10 +409,10 @@ int main(int argc, char **argv) { args::ArgumentParser parser("This is a test program.", "This goes after the options."); args::HelpFlag help(parser, "help", "Display this help menu", args::Matcher{'h', "help"}); - args::ArgFlag<int> integer(parser, "integer", "The integer flag", args::Matcher({'i'})); - args::ArgFlagList<char> characters(parser, "characters", "The character flag", args::Matcher({'c'})); - args::PosArg<std::string> foo(parser, "foo", "The foo position"); - args::PosArgList<double> numbers(parser, "numbers", "The numbers position list"); + args::ValueFlag<int> integer(parser, "integer", "The integer flag", args::Matcher({'i'})); + args::ValueFlagList<char> characters(parser, "characters", "The character flag", args::Matcher({'c'})); + args::Positional<std::string> foo(parser, "foo", "The foo position"); + args::PositionalList<double> numbers(parser, "numbers", "The numbers position list"); try { parser.ParseCLI(argc, argv); @@ -511,8 +511,8 @@ void DoublesReader(const std::string &name, const std::string &value, std::tuple int main(int argc, char **argv) { args::ArgumentParser parser("This is a test program."); - args::PosArg<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); - args::PosArg<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); + args::Positional<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); + args::Positional<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); try { parser.ParseCLI(argc, argv); @@ -589,27 +589,27 @@ int main(int argc, char **argv) { args::ArgumentParser parser("This is a test program with a really long description that is probably going to have to be wrapped across multiple different lines. This is a test to see how the line wrapping works", "This goes after the options. This epilog is also long enough that it will have to be properly wrapped to display correctly on the screen"); args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher{'h', "help"}); - args::ArgFlag<std::string> foo(parser, "FOO", "The foo flag.", args::Matcher{'a', 'b', 'c', "a", "b", "c", "the-foo-flag"}); - args::ArgFlag<std::string> bar(parser, "BAR", "The bar flag. This one has a lot of options, and will need wrapping in the description, along with its long flag list.", args::Matcher{'d', 'e', 'f', "d", "e", "f"}); - args::ArgFlag<std::string> baz(parser, "FOO", "The baz flag. This one has a lot of options, and will need wrapping in the description, even with its short flag list.", args::Matcher({"baz"})); - args::PosArg<std::string> pos1(parser, "POS1", "The pos1 argument."); - args::PosArgList<std::string> poslist1(parser, "POSLIST1", "The poslist1 argument."); - args::PosArg<std::string> pos2(parser, "POS2", "The pos2 argument."); - args::PosArgList<std::string> poslist2(parser, "POSLIST2", "The poslist2 argument."); - args::PosArg<std::string> pos3(parser, "POS3", "The pos3 argument."); - args::PosArgList<std::string> poslist3(parser, "POSLIST3", "The poslist3 argument."); - args::PosArg<std::string> pos4(parser, "POS4", "The pos4 argument."); - args::PosArgList<std::string> poslist4(parser, "POSLIST4", "The poslist4 argument."); - args::PosArg<std::string> pos5(parser, "POS5", "The pos5 argument."); - args::PosArgList<std::string> poslist5(parser, "POSLIST5", "The poslist5 argument."); - args::PosArg<std::string> pos6(parser, "POS6", "The pos6 argument."); - args::PosArgList<std::string> poslist6(parser, "POSLIST6", "The poslist6 argument."); - args::PosArg<std::string> pos7(parser, "POS7", "The pos7 argument."); - args::PosArgList<std::string> poslist7(parser, "POSLIST7", "The poslist7 argument."); - args::PosArg<std::string> pos8(parser, "POS8", "The pos8 argument."); - args::PosArgList<std::string> poslist8(parser, "POSLIST8", "The poslist8 argument."); - args::PosArg<std::string> pos9(parser, "POS9", "The pos9 argument."); - args::PosArgList<std::string> poslist9(parser, "POSLIST9", "The poslist9 argument."); + args::ValueFlag<std::string> foo(parser, "FOO", "The foo flag.", args::Matcher{'a', 'b', 'c', "a", "b", "c", "the-foo-flag"}); + args::ValueFlag<std::string> bar(parser, "BAR", "The bar flag. This one has a lot of options, and will need wrapping in the description, along with its long flag list.", args::Matcher{'d', 'e', 'f', "d", "e", "f"}); + args::ValueFlag<std::string> baz(parser, "FOO", "The baz flag. This one has a lot of options, and will need wrapping in the description, even with its short flag list.", args::Matcher({"baz"})); + args::Positional<std::string> pos1(parser, "POS1", "The pos1 argument."); + args::PositionalList<std::string> poslist1(parser, "POSLIST1", "The poslist1 argument."); + args::Positional<std::string> pos2(parser, "POS2", "The pos2 argument."); + args::PositionalList<std::string> poslist2(parser, "POSLIST2", "The poslist2 argument."); + args::Positional<std::string> pos3(parser, "POS3", "The pos3 argument."); + args::PositionalList<std::string> poslist3(parser, "POSLIST3", "The poslist3 argument."); + args::Positional<std::string> pos4(parser, "POS4", "The pos4 argument."); + args::PositionalList<std::string> poslist4(parser, "POSLIST4", "The poslist4 argument."); + args::Positional<std::string> pos5(parser, "POS5", "The pos5 argument."); + args::PositionalList<std::string> poslist5(parser, "POSLIST5", "The poslist5 argument."); + args::Positional<std::string> pos6(parser, "POS6", "The pos6 argument."); + args::PositionalList<std::string> poslist6(parser, "POSLIST6", "The poslist6 argument."); + args::Positional<std::string> pos7(parser, "POS7", "The pos7 argument."); + args::PositionalList<std::string> poslist7(parser, "POSLIST7", "The poslist7 argument."); + args::Positional<std::string> pos8(parser, "POS8", "The pos8 argument."); + args::PositionalList<std::string> poslist8(parser, "POSLIST8", "The poslist8 argument."); + args::Positional<std::string> pos9(parser, "POS9", "The pos9 argument."); + args::PositionalList<std::string> poslist9(parser, "POSLIST9", "The poslist9 argument."); try { parser.ParseCLI(argc, argv); @@ -697,10 +697,10 @@ int main(int argc, char **argv) parser.LongPrefix(""); parser.LongSeparator("="); args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher({"help"})); - args::ArgFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); - args::ArgFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); - args::ArgFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); - args::ArgFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); + args::ValueFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); + args::ValueFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); + args::ValueFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); + args::ValueFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); try { parser.ParseCLI(argc, argv); @@ -45,10 +45,10 @@ namespace args * If the Get() function of the type returns a reference, so does this, and * the value will be modifiable. */ - template <typename Arg> - auto get(Arg &arg) -> decltype(arg.Get()) + template <typename Option> + auto get(Option &option) -> decltype(option.Get()) { - return arg.Get(); + return option.Get(); } /** (INTERNAL) Count UTF-8 glyphs @@ -174,50 +174,50 @@ namespace args /** A simple unified option type for unified initializer lists for the Matcher class. */ - struct EitherOpt + struct EitherFlag { const bool isShort; - const char shortOpt; - const std::string longOpt; - EitherOpt(const std::string &opt) : isShort(false), shortOpt(), longOpt(opt) {} - EitherOpt(const char *opt) : isShort(false), shortOpt(), longOpt(opt) {} - EitherOpt(const char opt) : isShort(true), shortOpt(opt), longOpt() {} + const char shortFlag; + const std::string longFlag; + EitherFlag(const std::string &flag) : isShort(false), shortFlag(), longFlag(flag) {} + EitherFlag(const char *flag) : isShort(false), shortFlag(), longFlag(flag) {} + EitherFlag(const char flag) : isShort(true), shortFlag(flag), longFlag() {} - /** Get just the long options from an initializer list of EitherOpts + /** Get just the long flags from an initializer list of EitherFlags */ - static std::unordered_set<std::string> GetLong(std::initializer_list<EitherOpt> opts) + static std::unordered_set<std::string> GetLong(std::initializer_list<EitherFlag> flags) { - std::unordered_set<std::string> longOpts; - for (const EitherOpt &opt: opts) + std::unordered_set<std::string> longFlags; + for (const EitherFlag &flag: flags) { - if (!opt.isShort) + if (!flag.isShort) { - longOpts.insert(opt.longOpt); + longFlags.insert(flag.longFlag); } } - return longOpts; + return longFlags; } - /** Get just the short options from an initializer list of EitherOpts + /** Get just the short flags from an initializer list of EitherFlags */ - static std::unordered_set<char> GetShort(std::initializer_list<EitherOpt> opts) + static std::unordered_set<char> GetShort(std::initializer_list<EitherFlag> flags) { - std::unordered_set<char> shortOpts; - for (const EitherOpt &opt: opts) + std::unordered_set<char> shortFlags; + for (const EitherFlag &flag: flags) { - if (opt.isShort) + if (flag.isShort) { - shortOpts.insert(opt.shortOpt); + shortFlags.insert(flag.shortFlag); } } - return shortOpts; + return shortFlags; } }; - /** A class of "matchers", specifying short and long options that can - * possibly be matched. + /** A class of "matchers", specifying short and flags that can possibly be + * matched. * * This is supposed to be constructed and then passed in, not used directly * from user code. @@ -225,96 +225,96 @@ namespace args class Matcher { private: - const std::unordered_set<char> shortOpts; - const std::unordered_set<std::string> longOpts; + const std::unordered_set<char> shortFlags; + const std::unordered_set<std::string> longFlags; public: - /** Specify short and long opts separately as iterators + /** Specify short and long flags separately as iterators * - * ex: `args::Matcher(shortOpts.begin(), shortOpts.end(), longOpts.begin(), longOpts.end())` + * ex: `args::Matcher(shortFlags.begin(), shortFlags.end(), longFlags.begin(), longFlags.end())` */ template <typename ShortIt, typename LongIt> - Matcher(ShortIt shortOptsStart, ShortIt shortOptsEnd, LongIt longOptsStart, LongIt longOptsEnd) : - shortOpts(shortOptsStart, shortOptsEnd), - longOpts(longOptsStart, longOptsEnd) + Matcher(ShortIt shortFlagsStart, ShortIt shortFlagsEnd, LongIt longFlagsStart, LongIt longFlagsEnd) : + shortFlags(shortFlagsStart, shortFlagsEnd), + longFlags(longFlagsStart, longFlagsEnd) {} - /** Specify short and long opts separately as iterables + /** Specify short and long flags separately as iterables * - * ex: `args::Matcher(shortOpts, longOpts)` + * ex: `args::Matcher(shortFlags, longFlags)` */ template <typename Short, typename Long> Matcher(Short &&shortIn, Long &&longIn) : - shortOpts(std::begin(shortIn), std::end(shortIn)), longOpts(std::begin(longIn), std::end(longIn)) + shortFlags(std::begin(shortIn), std::end(shortIn)), longFlags(std::begin(longIn), std::end(longIn)) {} - /** Specify a mixed single initializer-list of both short and long opts + /** Specify a mixed single initializer-list of both short and long flags * * This is the fancy one. It takes a single initializer list of - * any number of any mixed kinds of options. Chars are - * automatically interpreted as short options, and strings are - * automatically interpreted as long options: + * any number of any mixed kinds of flags. Chars are + * automatically interpreted as short flags, and strings are + * automatically interpreted as long flags: * * args::Matcher{'a'} * args::Matcher{"foo"} * args::Matcher{'h', "help"} * args::Matcher{"foo", 'f', 'F', "FoO"} */ - Matcher(std::initializer_list<EitherOpt> in) : - shortOpts(EitherOpt::GetShort(in)), longOpts(EitherOpt::GetLong(in)) {} + Matcher(std::initializer_list<EitherFlag> in) : + shortFlags(EitherFlag::GetShort(in)), longFlags(EitherFlag::GetLong(in)) {} - Matcher(Matcher &&other) : shortOpts(std::move(other.shortOpts)), longOpts(std::move(other.longOpts)) + Matcher(Matcher &&other) : shortFlags(std::move(other.shortFlags)), longFlags(std::move(other.longFlags)) {} ~Matcher() {} - /** (INTERNAL) Check if there is a match of a short opt + /** (INTERNAL) Check if there is a match of a short flag */ - bool Match(const char opt) const + bool Match(const char flag) const { - return shortOpts.find(opt) != shortOpts.end(); + return shortFlags.find(flag) != shortFlags.end(); } - /** (INTERNAL) Check if there is a match of a long opt + /** (INTERNAL) Check if there is a match of a long flag */ - bool Match(const std::string &opt) const + bool Match(const std::string &flag) const { - return longOpts.find(opt) != longOpts.end(); + return longFlags.find(flag) != longFlags.end(); } - /** (INTERNAL) Get all option strings as a vector, with the prefixes embedded + /** (INTERNAL) Get all flag strings as a vector, with the prefixes embedded */ - std::vector<std::string> GetOptionStrings(const std::string &shortPrefix, const std::string &longPrefix) const + std::vector<std::string> GetFlagStrings(const std::string &shortPrefix, const std::string &longPrefix) const { - std::vector<std::string> optStrings; - optStrings.reserve(shortOpts.size() + longOpts.size()); - for (const char opt: shortOpts) + std::vector<std::string> flagStrings; + flagStrings.reserve(shortFlags.size() + longFlags.size()); + for (const char flag: shortFlags) { - optStrings.emplace_back(shortPrefix + std::string(1, opt)); + flagStrings.emplace_back(shortPrefix + std::string(1, flag)); } - for (const std::string &opt: longOpts) + for (const std::string &flag: longFlags) { - optStrings.emplace_back(longPrefix + opt); + flagStrings.emplace_back(longPrefix + flag); } - return optStrings; + return flagStrings; } - /** (INTERNAL) Get all option strings as a vector, with the prefixes and names embedded + /** (INTERNAL) Get all flag strings as a vector, with the prefixes and names embedded */ - std::vector<std::string> GetOptionStrings(const std::string &shortPrefix, const std::string &longPrefix, const std::string &name, const std::string &shortSeparator, const std::string longSeparator) const + std::vector<std::string> GetFlagStrings(const std::string &shortPrefix, const std::string &longPrefix, const std::string &name, const std::string &shortSeparator, const std::string longSeparator) const { const std::string bracedname(std::string("[") + name + "]"); - std::vector<std::string> optStrings; - optStrings.reserve(shortOpts.size() + longOpts.size()); - for (const char opt: shortOpts) + std::vector<std::string> flagStrings; + flagStrings.reserve(shortFlags.size() + longFlags.size()); + for (const char flag: shortFlags) { - optStrings.emplace_back(shortPrefix + std::string(1, opt) + shortSeparator + bracedname); + flagStrings.emplace_back(shortPrefix + std::string(1, flag) + shortSeparator + bracedname); } - for (const std::string &opt: longOpts) + for (const std::string &flag: longFlags) { - optStrings.emplace_back(longPrefix + opt + longSeparator + bracedname); + flagStrings.emplace_back(longPrefix + flag + longSeparator + bracedname); } - return optStrings; + return flagStrings; } }; @@ -377,7 +377,7 @@ namespace args } }; - /** Base class for all flag arguments + /** Base class for all flag options */ class FlagBase : public NamedBase { @@ -389,9 +389,9 @@ namespace args virtual ~FlagBase() {} - virtual FlagBase *Match(const std::string &arg) + virtual FlagBase *Match(const std::string &flag) { - if (matcher.Match(arg)) + if (matcher.Match(flag)) { matched = true; return this; @@ -399,9 +399,9 @@ namespace args return nullptr; } - virtual FlagBase *Match(const char arg) + virtual FlagBase *Match(const char flag) { - if (matcher.Match(arg)) + if (matcher.Match(flag)) { matched = true; return this; @@ -412,11 +412,11 @@ namespace args virtual std::tuple<std::string, std::string> GetDescription(const std::string &shortPrefix, const std::string &longPrefix, const std::string &shortSeparator, const std::string &longSeparator) const override { std::tuple<std::string, std::string> description; - const std::vector<std::string> optStrings(matcher.GetOptionStrings(shortPrefix, longPrefix)); + const std::vector<std::string> flagStrings(matcher.GetFlagStrings(shortPrefix, longPrefix)); std::ostringstream flagstream; - for (auto it = std::begin(optStrings); it != std::end(optStrings); ++it) + for (auto it = std::begin(flagStrings); it != std::end(flagStrings); ++it) { - if (it != std::begin(optStrings)) + if (it != std::begin(flagStrings)) { flagstream << ", "; } @@ -428,23 +428,23 @@ namespace args } }; - /** Base class for argument-accepting flag arguments + /** Base class for value-accepting flag options */ - class ArgFlagBase : public FlagBase + class ValueFlagBase : public FlagBase { public: - ArgFlagBase(const std::string &name, const std::string &help, Matcher &&matcher) : FlagBase(name, help, std::move(matcher)) {} - virtual ~ArgFlagBase() {} - virtual void ParseArg(const std::string &value) = 0; + ValueFlagBase(const std::string &name, const std::string &help, Matcher &&matcher) : FlagBase(name, help, std::move(matcher)) {} + virtual ~ValueFlagBase() {} + virtual void ParseValue(const std::string &value) = 0; virtual std::tuple<std::string, std::string> GetDescription(const std::string &shortPrefix, const std::string &longPrefix, const std::string &shortSeparator, const std::string &longSeparator) const override { std::tuple<std::string, std::string> description; - const std::vector<std::string> optStrings(matcher.GetOptionStrings(shortPrefix, longPrefix, name, shortSeparator, longSeparator)); + const std::vector<std::string> flagStrings(matcher.GetFlagStrings(shortPrefix, longPrefix, name, shortSeparator, longSeparator)); std::ostringstream flagstream; - for (auto it = std::begin(optStrings); it != std::end(optStrings); ++it) + for (auto it = std::begin(flagStrings); it != std::end(flagStrings); ++it) { - if (it != std::begin(optStrings)) + if (it != std::begin(flagStrings)) { flagstream << ", "; } @@ -456,7 +456,7 @@ namespace args } }; - /** Base class for positional arguments + /** Base class for positional options */ class PosBase : public NamedBase { @@ -472,7 +472,7 @@ namespace args return ready; } - virtual void ParseArg(const std::string &value) = 0; + virtual void ParseValue(const std::string &value) = 0; }; /** Class for all kinds of validating groups, including ArgumentParser @@ -491,27 +491,27 @@ namespace args } virtual ~Group() {} - /** Return the first FlagBase that matches arg, or nullptr + /** Return the first FlagBase that matches flag, or nullptr * - * \param arg The argument with prefixes stripped + * \param flag The flag with prefixes stripped * \return the first matching FlagBase pointer, or nullptr if there is no match */ - FlagBase *Match(const std::string &arg) + FlagBase *Match(const std::string &flag) { for (Base *child: children) { - FlagBase *flag = dynamic_cast<FlagBase *>(child); + FlagBase *flagBase = dynamic_cast<FlagBase *>(child); Group *group = dynamic_cast<Group *>(child); - if (flag) + if (flagBase) { - FlagBase *match = flag->Match(arg); + FlagBase *match = flagBase->Match(flag); if (match) { return match; } } else if (group) { - FlagBase *match = group->Match(arg); + FlagBase *match = group->Match(flag); if (match) { return match; @@ -521,27 +521,27 @@ namespace args return nullptr; } - /** Return the first FlagBase that matches arg, or nullptr + /** Return the first FlagBase that matches flag, or nullptr * - * \param arg The argument with prefixes stripped + * \param flag The flag with prefixes stripped * \return the first matching FlagBase pointer, or nullptr if there is no match */ - FlagBase *Match(const char arg) + FlagBase *Match(const char flag) { for (Base *child: children) { - FlagBase *flag = dynamic_cast<FlagBase *>(child); + FlagBase *flagBase = dynamic_cast<FlagBase *>(child); Group *group = dynamic_cast<Group *>(child); - if (flag) + if (flagBase) { - FlagBase *match = flag->Match(arg); + FlagBase *match = flagBase->Match(flag); if (match) { return match; } } else if (group) { - FlagBase *match = group->Match(arg); + FlagBase *match = group->Match(flag); if (match) { return match; @@ -551,7 +551,7 @@ namespace args return nullptr; } - /** Get the next ready positional parameter, or nullptr if there is none + /** Get the next ready positional, or nullptr if there is none * * \return the first ready PosBase pointer, or nullptr if there is no match */ @@ -776,10 +776,10 @@ namespace args std::string terminator; - bool allowJoinedShortArgument; - bool allowJoinedLongArgument; - bool allowSeparateShortArgument; - bool allowSeparateLongArgument; + bool allowJoinedShortValue; + bool allowJoinedLongValue; + bool allowSeparateShortValue; + bool allowSeparateLongValue; public: /** A simple structure of parameters for easy user-modifyable help menus @@ -825,17 +825,17 @@ namespace args bool showProglinePositionals = true; } helpParams; ArgumentParser(const std::string &description, const std::string &epilog = std::string()) : - Group("arguments", Group::Validators::AllChildGroups), + Group("options", Group::Validators::AllChildGroups), description(description), epilog(epilog), longprefix("--"), shortprefix("-"), longseparator("="), terminator("--"), - allowJoinedShortArgument(true), - allowJoinedLongArgument(true), - allowSeparateShortArgument(true), - allowSeparateLongArgument(true) {} + allowJoinedShortValue(true), + allowJoinedLongValue(true), + allowSeparateShortValue(true), + allowSeparateLongValue(true) {} /** The program name for help generation */ @@ -846,11 +846,11 @@ namespace args void Prog(const std::string &prog) { this->prog = prog; } - /** The description that appears on the prog line after options and positionals + /** The description that appears on the prog line after options */ const std::string &ProglinePostfix() const { return proglinePostfix; } - /** The description that appears on the prog line after options and positionals + /** The description that appears on the prog line after options */ void ProglinePostfix(const std::string &proglinePostfix) { this->proglinePostfix = proglinePostfix; } @@ -873,29 +873,29 @@ namespace args void Epilog(const std::string &epilog) { this->epilog = epilog; } - /** The prefix for long options + /** The prefix for long flags */ const std::string &LongPrefix() const { return longprefix; } - /** The prefix for long options + /** The prefix for long flags */ void LongPrefix(const std::string &longprefix) { this->longprefix = longprefix; } - /** The prefix for short options + /** The prefix for short flags */ const std::string &ShortPrefix() const { return shortprefix; } - /** The prefix for short options + /** The prefix for short flags */ void ShortPrefix(const std::string &shortprefix) { this->shortprefix = shortprefix; } - /** The separator for long options + /** The separator for long flags */ const std::string &LongSeparator() const { return longseparator; } - /** The separator for long options + /** The separator for long flags */ void LongSeparator(const std::string &longseparator) { @@ -906,11 +906,11 @@ namespace args this->longseparator = longseparator; } - /** The terminator that separates short options from long ones + /** The terminator that forcibly separates flags from positionals */ const std::string &Terminator() const { return terminator; } - /** The terminator that separates short options from long ones + /** The terminator that forcibly separates flags from positionals */ void Terminator(const std::string &terminator) { this->terminator = terminator; } @@ -920,34 +920,34 @@ namespace args * See SetArgumentSeparations for details on what each one means. */ void GetArgumentSeparations( - bool &allowJoinedShortArgument, - bool &allowJoinedLongArgument, - bool &allowSeparateShortArgument, - bool &allowSeparateLongArgument) const - { - allowJoinedShortArgument = this->allowJoinedShortArgument; - allowJoinedLongArgument = this->allowJoinedLongArgument; - allowSeparateShortArgument = this->allowSeparateShortArgument; - allowSeparateLongArgument = this->allowSeparateLongArgument; + bool &allowJoinedShortValue, + bool &allowJoinedLongValue, + bool &allowSeparateShortValue, + bool &allowSeparateLongValue) const + { + allowJoinedShortValue = this->allowJoinedShortValue; + allowJoinedLongValue = this->allowJoinedLongValue; + allowSeparateShortValue = this->allowSeparateShortValue; + allowSeparateLongValue = this->allowSeparateLongValue; } /** Change allowed option separation. * - * \param allowJoinedShortArgument Allow a short flag that accepts an argument to be passed its argument immediately next to it (ie. in the same argv field) - * \param allowJoinedLongArgument Allow a long flag that accepts an argument to be passed its argument separated by the longseparator (ie. in the same argv field) - * \param allowSeparateShortArgument Allow a short flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field) - * \param allowSeparateLongArgument Allow a long flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field) + * \param allowJoinedShortValue Allow a short flag that accepts an argument to be passed its argument immediately next to it (ie. in the same argv field) + * \param allowJoinedLongValue Allow a long flag that accepts an argument to be passed its argument separated by the longseparator (ie. in the same argv field) + * \param allowSeparateShortValue Allow a short flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field) + * \param allowSeparateLongValue Allow a long flag that accepts an argument to be passed its argument separated by whitespace (ie. in the next argv field) */ void SetArgumentSeparations( - const bool allowJoinedShortArgument, - const bool allowJoinedLongArgument, - const bool allowSeparateShortArgument, - const bool allowSeparateLongArgument) - { - this->allowJoinedShortArgument = allowJoinedShortArgument; - this->allowJoinedLongArgument = allowJoinedLongArgument; - this->allowSeparateShortArgument = allowSeparateShortArgument; - this->allowSeparateLongArgument = allowSeparateLongArgument; + const bool allowJoinedShortValue, + const bool allowJoinedLongValue, + const bool allowSeparateShortValue, + const bool allowSeparateLongValue) + { + this->allowJoinedShortValue = allowJoinedShortValue; + this->allowJoinedLongValue = allowJoinedLongValue; + this->allowSeparateShortValue = allowSeparateShortValue; + this->allowSeparateLongValue = allowSeparateLongValue; } /** Pass the help menu into an ostream @@ -1001,7 +1001,7 @@ namespace args } help << "\n"; help << std::string(helpParams.progindent, ' ') << "OPTIONS:\n\n"; - for (const auto &description: GetChildDescriptions(shortprefix, longprefix, allowJoinedShortArgument ? "" : " ", allowJoinedLongArgument ? longseparator : " ")) + for (const auto &description: GetChildDescriptions(shortprefix, longprefix, allowJoinedShortValue ? "" : " ", allowJoinedLongValue ? longseparator : " ")) { const unsigned int groupindent = std::get<2>(description) * helpParams.eachgroupindent; const std::vector<std::string> flags(Wrap(std::get<0>(description), helpParams.width - (helpParams.flagindent + helpParams.helpindent + helpParams.gutter))); @@ -1093,14 +1093,14 @@ namespace args FlagBase *base = Match(arg); if (base) { - ArgFlagBase *argbase = dynamic_cast<ArgFlagBase *>(base); + ValueFlagBase *argbase = dynamic_cast<ValueFlagBase *>(base); if (argbase) { if (separator != argchunk.npos) { - if (allowJoinedLongArgument) + if (allowJoinedLongValue) { - argbase->ParseArg(argchunk.substr(separator + longseparator.size())); + argbase->ParseValue(argchunk.substr(separator + longseparator.size())); } else { std::ostringstream problem; @@ -1117,9 +1117,9 @@ namespace args throw ParseError(problem.str().c_str()); } - if (allowSeparateLongArgument) + if (allowSeparateLongValue) { - argbase->ParseArg(*it); + argbase->ParseValue(*it); } else { std::ostringstream problem; @@ -1150,15 +1150,15 @@ namespace args Base *base = Match(arg); if (base) { - ArgFlagBase *argbase = dynamic_cast<ArgFlagBase *>(base); + ValueFlagBase *argbase = dynamic_cast<ValueFlagBase *>(base); if (argbase) { const std::string arg(++argit, std::end(argchunk)); if (!arg.empty()) { - if (allowJoinedShortArgument) + if (allowJoinedShortValue) { - argbase->ParseArg(arg); + argbase->ParseValue(arg); } else { std::ostringstream problem; @@ -1175,9 +1175,9 @@ namespace args throw ParseError(problem.str().c_str()); } - if (allowSeparateShortArgument) + if (allowSeparateShortValue) { - argbase->ParseArg(*it); + argbase->ParseValue(*it); } else { std::ostringstream problem; @@ -1200,7 +1200,7 @@ namespace args PosBase *pos = GetNextPos(); if (pos) { - pos->ParseArg(chunk); + pos->ParseValue(chunk); } else { std::ostringstream problem; @@ -1307,15 +1307,15 @@ namespace args /** A flag class that simply counts the number of times it's matched */ - class Counter : public Flag + class CounterFlag : public Flag { private: int count; public: - Counter(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const int startcount = 0): Flag(group, name, help, std::move(matcher)), count(startcount) {} + CounterFlag(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const int startcount = 0): Flag(group, name, help, std::move(matcher)), count(startcount) {} - virtual ~Counter() {} + virtual ~CounterFlag() {} virtual FlagBase *Match(const std::string &arg) override { @@ -1351,7 +1351,7 @@ namespace args * raises a ParseError if there are any characters left. */ template <typename T> - void ArgReader(const std::string &name, const std::string &value, T &destination) + void ValueReader(const std::string &name, const std::string &value, T &destination) { std::istringstream ss(value); ss >> destination; @@ -1364,13 +1364,13 @@ namespace args } } - /** std::string specialization for ArgReader + /** std::string specialization for ValueReader * * By default, stream extraction into a string splits on white spaces, and * it is more efficient to ust copy a string into the destination. */ template <> - void ArgReader<std::string>(const std::string &name, const std::string &value, std::string &destination) + void ValueReader<std::string>(const std::string &name, const std::string &value, std::string &destination) { destination.assign(value); } @@ -1380,22 +1380,22 @@ namespace args * \tparam T the type to extract the argument as * \tparam Reader The function used to read the argument, taking the name, value, and destination reference */ - template <typename T, void (*Reader)(const std::string &, const std::string &, T&) = ArgReader<T>> - class ArgFlag : public ArgFlagBase + template <typename T, void (*Reader)(const std::string &, const std::string &, T&) = ValueReader<T>> + class ValueFlag : public ValueFlagBase { private: T value; public: - ArgFlag(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const T &defaultValue = T()): ArgFlagBase(name, help, std::move(matcher)), value(defaultValue) + ValueFlag(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const T &defaultValue = T()): ValueFlagBase(name, help, std::move(matcher)), value(defaultValue) { group.Add(*this); } - virtual ~ArgFlag() {} + virtual ~ValueFlag() {} - virtual void ParseArg(const std::string &value) override + virtual void ParseValue(const std::string &value) override { Reader(name, value, this->value); } @@ -1417,22 +1417,22 @@ namespace args template < typename T, typename List = std::vector<T>, - void (*Reader)(const std::string &, const std::string &, T&) = ArgReader<T>> - class ArgFlagList : public ArgFlagBase + void (*Reader)(const std::string &, const std::string &, T&) = ValueReader<T>> + class ValueFlagList : public ValueFlagBase { private: List values; public: - ArgFlagList(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const List &defaultValues = List()): ArgFlagBase(name, help, std::move(matcher)), values(defaultValues) + ValueFlagList(Group &group, const std::string &name, const std::string &help, Matcher &&matcher, const List &defaultValues = List()): ValueFlagBase(name, help, std::move(matcher)), values(defaultValues) { group.Add(*this); } - virtual ~ArgFlagList() {} + virtual ~ValueFlagList() {} - virtual void ParseArg(const std::string &value) override + virtual void ParseValue(const std::string &value) override { values.emplace_back(); Reader(name, value, values.back()); @@ -1451,20 +1451,20 @@ namespace args * \tparam T the type to extract the argument as * \tparam Reader The function used to read the argument, taking the name, value, and destination reference */ - template <typename T, void (*Reader)(const std::string &, const std::string &, T&) = ArgReader<T>> - class PosArg : public PosBase + template <typename T, void (*Reader)(const std::string &, const std::string &, T&) = ValueReader<T>> + class Positional : public PosBase { private: T value; public: - PosArg(Group &group, const std::string &name, const std::string &help, const T &defaultValue = T()): PosBase(name, help), value(defaultValue) + Positional(Group &group, const std::string &name, const std::string &help, const T &defaultValue = T()): PosBase(name, help), value(defaultValue) { group.Add(*this); } - virtual ~PosArg() {} + virtual ~Positional() {} - virtual void ParseArg(const std::string &value) override + virtual void ParseValue(const std::string &value) override { Reader(name, value, this->value); ready = false; @@ -1488,21 +1488,21 @@ namespace args template < typename T, typename List = std::vector<T>, - void (*Reader)(const std::string &, const std::string &, T&) = ArgReader<T>> - class PosArgList : public PosBase + void (*Reader)(const std::string &, const std::string &, T&) = ValueReader<T>> + class PositionalList : public PosBase { private: List values; public: - PosArgList(Group &group, const std::string &name, const std::string &help, const List &defaultValues = List()): PosBase(name, help), values(defaultValues) + PositionalList(Group &group, const std::string &name, const std::string &help, const List &defaultValues = List()): PosBase(name, help), values(defaultValues) { group.Add(*this); } - virtual ~PosArgList() {} + virtual ~PositionalList() {} - virtual void ParseArg(const std::string &value) override + virtual void ParseValue(const std::string &value) override { values.emplace_back(); Reader(name, value, values.back()); @@ -52,9 +52,9 @@ TEST_CASE("Boolean flags work as expected, with clustering", "[args]") TEST_CASE("Count flag works as expected", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::Counter foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); - args::Counter bar(parser, "BAR", "test flag", args::Matcher{'b', "bar"}, 7); - args::Counter baz(parser, "BAZ", "test flag", args::Matcher{'z', "baz"}, 7); + args::CounterFlag foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::CounterFlag bar(parser, "BAR", "test flag", args::Matcher{'b', "bar"}, 7); + args::CounterFlag baz(parser, "BAZ", "test flag", args::Matcher{'z', "baz"}, 7); parser.ParseArgs(std::vector<std::string>{"--foo", "-fb", "--bar", "-b", "-f", "--foo"}); REQUIRE(foo); REQUIRE(bar); @@ -67,10 +67,10 @@ TEST_CASE("Count flag works as expected", "[args]") TEST_CASE("Argument flags work as expected, with clustering", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::ValueFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); args::Flag bar(parser, "BAR", "test flag", args::Matcher{'b', "bar"}); - args::ArgFlag<double> baz(parser, "BAZ", "test flag", args::Matcher{'a', "baz"}); - args::ArgFlag<char> bim(parser, "BAZ", "test flag", args::Matcher{'B', "bim"}); + args::ValueFlag<double> baz(parser, "BAZ", "test flag", args::Matcher{'a', "baz"}); + args::ValueFlag<char> bim(parser, "BAZ", "test flag", args::Matcher{'B', "bim"}); args::Flag bix(parser, "BAZ", "test flag", args::Matcher{'x', "bix"}); parser.ParseArgs(std::vector<std::string>{"-bftest", "--baz=7.555e2", "--bim", "c"}); REQUIRE(foo); @@ -93,10 +93,10 @@ TEST_CASE("Passing an argument to a non-argument flag throws an error", "[args]" TEST_CASE("Unified argument lists for match work", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::ValueFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); args::Flag bar(parser, "BAR", "test flag", args::Matcher{"bar", 'b'}); - args::ArgFlag<double> baz(parser, "BAZ", "test flag", args::Matcher{'a', "baz"}); - args::ArgFlag<char> bim(parser, "BAZ", "test flag", args::Matcher{'B', "bim"}); + args::ValueFlag<double> baz(parser, "BAZ", "test flag", args::Matcher{'a', "baz"}); + args::ValueFlag<char> bim(parser, "BAZ", "test flag", args::Matcher{'B', "bim"}); args::Flag bix(parser, "BAZ", "test flag", args::Matcher{"bix"}); parser.ParseArgs(std::vector<std::string>{"-bftest", "--baz=7.555e2", "--bim", "c"}); REQUIRE(foo); @@ -112,7 +112,7 @@ TEST_CASE("Unified argument lists for match work", "[args]") TEST_CASE("Get can be assigned to for non-reference types", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::ValueFlag<std::string> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); parser.ParseArgs(std::vector<std::string>{"--foo=test"}); REQUIRE(foo); REQUIRE(args::get(foo) == "test"); @@ -123,7 +123,7 @@ TEST_CASE("Get can be assigned to for non-reference types", "[args]") TEST_CASE("Invalid argument parsing throws parsing exceptions", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<int> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::ValueFlag<int> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); REQUIRE_THROWS_AS(parser.ParseArgs(std::vector<std::string>{"--foo=7.5"}), args::ParseError); REQUIRE_THROWS_AS(parser.ParseArgs(std::vector<std::string>{"--foo", "7a"}), args::ParseError); REQUIRE_THROWS_AS(parser.ParseArgs(std::vector<std::string>{"--foo", "7e4"}), args::ParseError); @@ -132,7 +132,7 @@ TEST_CASE("Invalid argument parsing throws parsing exceptions", "[args]") TEST_CASE("Argument flag lists work as expected", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlagList<int> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); + args::ValueFlagList<int> foo(parser, "FOO", "test flag", args::Matcher{'f', "foo"}); parser.ParseArgs(std::vector<std::string>{"--foo=7", "-f2", "-f", "9", "--foo", "42"}); REQUIRE((args::get(foo) == std::vector<int>{7, 2, 9, 42})); } @@ -140,9 +140,9 @@ TEST_CASE("Argument flag lists work as expected", "[args]") TEST_CASE("Positional arguments and positional argument lists work as expected", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::PosArg<std::string> foo(parser, "FOO", "test flag"); - args::PosArg<bool> bar(parser, "BAR", "test flag"); - args::PosArgList<char> baz(parser, "BAZ", "test flag"); + args::Positional<std::string> foo(parser, "FOO", "test flag"); + args::Positional<bool> bar(parser, "BAR", "test flag"); + args::PositionalList<char> baz(parser, "BAZ", "test flag"); parser.ParseArgs(std::vector<std::string>{"this is a test flag", "0", "a", "b", "c", "x", "y", "z"}); REQUIRE(foo); REQUIRE((args::get(foo) == "this is a test flag")); @@ -155,9 +155,9 @@ TEST_CASE("Positional arguments and positional argument lists work as expected", TEST_CASE("Positionals that are unspecified evaluate false", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::PosArg<std::string> foo(parser, "FOO", "test flag"); - args::PosArg<bool> bar(parser, "BAR", "test flag"); - args::PosArgList<char> baz(parser, "BAZ", "test flag"); + args::Positional<std::string> foo(parser, "FOO", "test flag"); + args::Positional<bool> bar(parser, "BAR", "test flag"); + args::PositionalList<char> baz(parser, "BAZ", "test flag"); parser.ParseArgs(std::vector<std::string>{"this is a test flag again"}); REQUIRE(foo); REQUIRE((args::get(foo) == "this is a test flag again")); @@ -168,8 +168,8 @@ TEST_CASE("Positionals that are unspecified evaluate false", "[args]") TEST_CASE("Additional positionals throw an exception", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::PosArg<std::string> foo(parser, "FOO", "test flag"); - args::PosArg<bool> bar(parser, "BAR", "test flag"); + args::Positional<std::string> foo(parser, "FOO", "test flag"); + args::Positional<bool> bar(parser, "BAR", "test flag"); REQUIRE_THROWS_AS(parser.ParseArgs(std::vector<std::string>{"this is a test flag again", "1", "this has no positional available"}), args::ParseError); } @@ -243,13 +243,13 @@ TEST_CASE("Custom types work", "[args]") { { args::ArgumentParser parser("This is a test program."); - args::PosArg<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); - args::PosArg<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); + args::Positional<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); + args::Positional<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); REQUIRE_THROWS_AS(parser.ParseArgs(std::vector<std::string>{"1.2,2", "3.8,4"}), args::ParseError); } args::ArgumentParser parser("This is a test program."); - args::PosArg<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); - args::PosArg<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); + args::Positional<std::tuple<int, int>> ints(parser, "INTS", "This takes a pair of integers."); + args::Positional<std::tuple<double, double>, DoublesReader> doubles(parser, "DOUBLES", "This takes a pair of doubles."); parser.ParseArgs(std::vector<std::string>{"1,2", "3.8,4"}); REQUIRE(std::get<0>(args::get(ints)) == 1); REQUIRE(std::get<1>(args::get(ints)) == 2); @@ -263,10 +263,10 @@ TEST_CASE("Custom parser prefixes (dd-style)", "[args]") parser.LongPrefix(""); parser.LongSeparator("="); args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher({"help"})); - args::ArgFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); - args::ArgFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); - args::ArgFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); - args::ArgFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); + args::ValueFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); + args::ValueFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); + args::ValueFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); + args::ValueFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); parser.ParseArgs(std::vector<std::string>{"skip=8", "if=/dev/null"}); REQUIRE_FALSE(bs); REQUIRE(args::get(bs) == 512); @@ -283,10 +283,10 @@ TEST_CASE("Custom parser prefixes (Some Windows styles)", "[args]") parser.LongPrefix("/"); parser.LongSeparator(":"); args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher({"help"})); - args::ArgFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); - args::ArgFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); - args::ArgFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); - args::ArgFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); + args::ValueFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); + args::ValueFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); + args::ValueFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); + args::ValueFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); parser.ParseArgs(std::vector<std::string>{"/skip:8", "/if:/dev/null"}); REQUIRE_FALSE(bs); REQUIRE(args::get(bs) == 512); @@ -302,10 +302,10 @@ TEST_CASE("Help menu can be grabbed as a string, passed into a stream, or by usi std::ostream null(nullptr); args::ArgumentParser parser("This command likes to break your disks"); args::HelpFlag help(parser, "HELP", "Show this help menu.", args::Matcher({"help"})); - args::ArgFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); - args::ArgFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); - args::ArgFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); - args::ArgFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); + args::ValueFlag<long> bs(parser, "BYTES", "Block size", args::Matcher({"bs"}), 512); + args::ValueFlag<long> skip(parser, "BYTES", "Bytes to skip", args::Matcher({"skip"}), 0); + args::ValueFlag<std::string> input(parser, "BLOCK SIZE", "Block size", args::Matcher({"if"})); + args::ValueFlag<std::string> output(parser, "BLOCK SIZE", "Block size", args::Matcher({"of"})); parser.ParseArgs(std::vector<std::string>{"--skip=8", "--if=/dev/null"}); null << parser.Help(); parser.Help(null); @@ -315,7 +315,7 @@ TEST_CASE("Help menu can be grabbed as a string, passed into a stream, or by usi TEST_CASE("Required argument separation being violated throws an error", "[args]") { args::ArgumentParser parser("This is a test program.", "This goes after the options."); - args::ArgFlag<std::string> bar(parser, "BAR", "test flag", args::Matcher{'b', "bar"}); + args::ValueFlag<std::string> bar(parser, "BAR", "test flag", args::Matcher{'b', "bar"}); REQUIRE_NOTHROW(parser.ParseArgs(std::vector<std::string>{"-btest"})); REQUIRE_NOTHROW(parser.ParseArgs(std::vector<std::string>{"--bar=test"})); REQUIRE_NOTHROW(parser.ParseArgs(std::vector<std::string>{"-b", "test"})); |