Modern C++ arguments parsing library with beautiful API. Single header. Inspired by commander.js.
Supports all fundamental types and most of the standart containers. Could be used with custom value types and containers.
Short API Example:
auto b = false;
auto i = 0;
auto d = 0.0;
std::string str = ""s;
auto v = std::vector<int>{};
auto m = std::map<std::string, std::string>{};
args::options options = {
{"-b", &b},
{"-i", &i},
{"-d", &d},
{args::required, "-s", "--str", &str},
{"-v", &v},
{"-m", &m}
};
args::parse(argc, argv, options);
See short-syntax.cpp for the full example.
Chain API Example:
auto b = false;
auto i = 0;
auto d = 0.0;
auto str = ""s;
auto v = std::vector<int>{};
auto m = std::map<std::string, std::string>{};
auto p = args::parser{}
.option("-b", &b)
.option(args::required, "-i", &i)
.option("-d", &d)
.option("-s", "--str", &str)
.option(args::required, "-v", "--vector", &v)
.option("-m", "--map", &m);
auto cmd_called = false;
auto cmd_b = false;
auto e = ""s;
p.command("cmd", "c")
.option("-b", &cmd_b)
.option("-e", &e)
.action([&]() {
cmd_called = true;
});
p.parse(argc, argv);
See chain-syntax.cpp for the full example.
With autogenerated help:
auto a = ""s;
auto b = ""s;
auto c = ""s;
auto d = ""s;
auto carg1 = ""s;
auto crest = std::vector<std::string>{};
args::parser p = args::parser{}
.name("cli-cmd")
.description("Some text")
.command_required()
.option("-a", "Global option A", &a)
.option("-b", "--bb", "Global option B", &b);
p.command("list", "l", "List command")
.arg(args::required, "carg1", "List command arg1", &carg1)
.rest("crest", "List command rest args", &crest)
.option("-c", "Option C", &c)
.option(args::required, "-d", "--dd", "Option D", &d);
p.command("get", "g", "Get command")
.arg(args::required, "smt", "What to get", &carg1)
.option("-h", "How to get", &c);
p.parse(argc, argv);
See help.cpp for the full example.
Short API:
- args::parse(argv, argc, options) - Parse all options
- args::option - Used for literal options creation in short syntax
- args::options - Used for short syntax
Chain API:
- args::parser{}
- parser.name(name) - Set program name for generated help
- parser.description(description) - Set program description for generated help
- parser.command_required() - Make commands required
- parser.option(...) - Define global option
- parser.arg(...) - Define global positional argument
- parser.rest(...) - Capture rest global positional arguments into the container
- parser.command(...) - Define command
- command.option(...) - Define command option
- command.arg(...) - Define command positional argument
- command.rest(...) - Capture rest command positional arguments into the container
- command.action(lambda) - Set action for command
- parser.parse(argv, argc) - Parse all options, arguments and commands
- Exception: args::invalid_option
- Exception: args::invalid_option_value
- Exception: args::invalid_command_option_value
- Exception: args::invalid_arg_value
- Exception: args::invalid_command_arg_value
- Exception: args::unexpected_arg
- Exception: args::missing_command
- Exception: args::missing_option
- Exception: args::missing_command_option
- Exception: args::missing_arg
- Exception: args::missing_command_arg
Custom help generation:
- parser.help(lambda) - Set custom
--helphandler - parser.format_help([indent]) -> str - Generate help
- parser.format_command_help(command_name, [indent]) -> str - Generate help for the command
- parser.format_usage([indent]) -> str - Usage section of help
- parser.format_args([indent]) -> str - Arguments section of help
- parser.format_options([indent]) -> str - Options section of help
- parser.format_commands([indent]) -> str - Commands section of help
- parser.format_command_usage(command_name, [indent]) -> str - Usage section of the command help
- parser.format_command_args(command_name, [indent]) -> str - Arguments section of the command help
- parser.format_command_options(command_name, [indent]) -> str - Options section of the command help
- Commands
- Multi-word commands
- Global/command options
- Repeated options
- Global/command positional args
- Capture global/command rest positional args in container
- Required options, args, rest args
- Require command to be called
- Autogenerates
--helpdocumentation + for commands - Build-in error messages for invalid/required options, arguments, commands
- Supports non conventional options:
-frtti, -fno-rtti, +fb - Supports pairs
key=valueas option value - Supports any type that could be parsed with
std::stringstream -
1, 0, true, false, on, off, yes, novalues forboolflags - Implicitly add
--no-flagforboolflags - Supports
-- - Supports
std::vector-like containers for repeated options - Supports
std::pairforkey=valueoption value - Supports
std::map-like containers for repeatedkey=valueoption value - Any value could be passed to lambda
To output default error messages wrap parse(...) in:
try {
p.parse(argc, argv);
} catch (const std::runtime_error& err) {
std::cout << err.what() << std::endl;
std::exit(1);
}
To handle all errors separately wrap `parse(...)` in:
try {
p.parse(argc, argv);
} catch (const args::invalid_option& err) {
// when unregistered option is passed
// use err.option
} catch (const args::invalid_command_option_value& err) {
// when failed to parse command option value
// use err.command, err.option and err.value
} catch (const args::invalid_option_value& err) {
// when failed to parse option value
// use err.option and err.value
} catch (const args::invalid_command_arg_value& err) {
// when failed to parse command argument value
// use err.command, err.arg and err.value
} catch (const args::invalid_arg_value& err) {
// when failed to parse argument value
// use err.arg and err.value
} catch (const args::unexpected_arg& err) {
// when non captured arguments is passed
// use err.value
} catch (const args::missing_command_option& err) {
// only when there are required command options
// use err.command and err.option
} catch (const args::missing_option& err) {
// only when there are required options
// use err.option
} catch (const args::missing_command_arg& err) {
// only when there are required command arguments
// use err.command and err.arg
} catch (const args::missing_arg& err) {
// only when there are required arguments
// use err.arg
} catch (const args::missing_command& err) {
// only when parser.command_required() is called
}
See errors.cpp, required-errors.cpp and command-required-error.cpp for the full error handling examples.
See make examples output for all errors messages.
See help.cpp, required-command-help.cpp examples.
For using parts of the generated help for the custom help output see custom-help.cpp example.
args::parse(argv, argc, options) #
Used for short syntax.
void parse(int argc, const char** argv, const args::options& ptions);
args::option{...} #
Used for short syntax.
args::option{[args::required], name, destination_ptr);
args::option{[args::required], short_name, long_name, destination_ptr);
[args::required]args::required_tSet optional marker to make option requirednamestd::stringShort-s, long--longor non conventional+fb, -fno-rttishort_namestd::stringShort-slong_namestd::stringLong--longdestination_ptrT*Set option value by pointer
All overloads example:
auto b = false;
args::options options = {
{"-b", &b},
{"-b", "Description", &b},
{args::required, "-b", &b}
{args::required, "-b", "Description", &b}
{"-b", "--long", &b},
{"-b", "--long", "Description", &b},
{args::required, "-b", "--long", &b}
{args::required, "-b", "--long", "Description", &b}
};
All overloads:
template<typename T>
args::option(const std::string& name, T* destination);
template<typename T>
args::option(args::required_t, const std::string& name, T* destination);
template<typename T>
args::option(const std::string& short_name, const std::string& long_name, T* destination);
template<typename T>
args::option(args::required_t, const std::string& short_name, const std::string& long_name,
T* destination);
args::options #
Used for short syntax.
using args::options = std::vector<option>;
args::parser{} #
parser.name(name) #
Set program name for documentation.
parser& name(const std::string& name);
parser.description(description) #
Set program description for documentation.
parser& description(const std::string& description);
parser.command_required() #
If called will throw when no command is called.
parser& command_required();
parser.option(...) #
parser.option([args::required], name, [description], destination_ptr);
parser.option<Value_Type>([args::required], name, [description], lambda);
parser.option([args::required], short_name, long_name, [description], destination_ptr);
parser.option<Value_Type>([args::required], short_name, long_name, [description], lambda);
Specify global options.
[args::required]args::required_tSet optional marker to make option requirednamestd::stringShort-s, long--longor non conventional+fb, -fno-rttishort_namestd::stringShort-slong_namestd::stringLong--longdescriptionstd::stringDescription used in help generationdestination_ptrT*Set option value by pointerlambdavoid (T)Get option value with lambda
Note! When using lambda first template parameter Value_Type is required.
All overloads example:
auto b = false;
auto p = parser{}
// using destination_ptr
.option("-s", &b)
.option("-s", "Description", &b)
.option(args::required, "-s" &b)
.option(args::required, "-s", "Description", &b)
.option("-s", "--long", &b)
.option("-s", "--long", "Description", &b)
.option(args::required, "-s", "--long", &b)
.option(args::required, "-s", "--long", "Description", &b)
// non conventional options with destination_ptr
.option("+fw-tf", &b)
.option("+fw-tf", "Description", &b)
.option(args::required, "+fw-tf" &b)
.option(args::required, "+fw-tf", "Description", &b)
// using lambda
.option<bool>("-s", [&](auto v) { b = v; })
.option<bool>("-s", "Description", [&](auto v) { b = v; })
.option<bool>(args::required, "-s" [&](auto v) { b = v; })
.option<bool>(args::required, "-s", "Description", [&](auto v) { b = v; })
.option<bool>("-s", "--long", [&](auto v) { b = v; })
.option<bool>("-s", "--long", "Description", [&](auto v) { b = v; })
.option<bool>(args::required, "-s", "--long", [&](auto v) { b = v; })
.option<bool>(args::required, "-s", "--long", "Description", [&](auto v) { b = v; })
// non conventional options with lambda
.option("+fw-tf", [&](auto v) { b = v; })
.option("+fw-tf", "Description", [&](auto v) { b = v; })
.option(args::required, "+fw-tf" [&](auto v) { b = v; })
.option(args::required, "+fw-tf", "Description", [&](auto v) { b = v; });
All overloads
template<typename T>
args::parser& option(const std::string& name, T* destination);
template<typename T>
args::parser& option(args::required_t, const std::string& name, T* destination);
template<typename T, typename F>
args::parser& option(const std::string& name, F handler);
template<typename T, typename F>
args::parser& option(args::required_t, const std::string& name, F handler);
template<typename T>
args::parser& option(const std::string& short_name, const std::string& long_name_or_desc,
T* destination);
template<typename T>
args::parser& option(const std::string& short_name, const std::string& long_name,
const std::string& description, T* destination);
template<typename T>
args::parser& option(args::required_t, const std::string& short_name,
const std::string& long_name_or_desc, T* destination);
template<typename T>
args::parser& option(args::required_t, const std::string& short_name, const std::string& long_name,
const std::string& description, T* destination);
template<typename T, typename F>
args::parser& option(const std::string& short_name, const std::string& long_name_or_desc,
F handler);
template<typename T, typename F>
args::parser& option(const std::string& short_name, const std::string& long_name,
const std::string& description, F handler);
template<typename T, typename F>
args::parser& option(args::required_t, const std::string& short_name,
const std::string& long_name_or_desc, F handler);
template<typename T, typename F>
args::parser& option(args::required_t, const std::string& short_name,
const std::string& long_name, const std::string& description, F handler);
parser.arg(...) #
parser.arg(destination_ptr);
parser.arg<Value_Type>(lambda);
parser.arg([args::required], name, [description], destination_ptr);
parser.arg<Value_Type>([args::required], name, [description], lambda);
Specify global positional arguments.
When arguments are passed before command name they are treated as global. If command arguments are already captured or command has no arguments all subsequent arguments will be treated as global.
[args::required]args::required_tSet optional marker to make option requirednamestd::stringName used in required errors and help generationdescriptionstd::stringDescription used in help generationdestination_ptrT*Set option value by pointerlambdavoid (T)Get option value with lambda
Note! When using lambda first template parameter Value_Type is required.
All overloads example:
auto arg = ""s;
auto p = parser{}
// using destination_ptr
.arg(&arg)
.arg("file", &arg)
.arg("file", "Description", &arg)
.arg(args::required, "file", &arg)
.arg(args::required, "file", "Description", &arg)
// using lambda
.arg([&](auto v) { arg = v; })
.arg("file", [&](auto v) { arg = v; })
.arg("file", "Description", [&](auto v) { arg = v; })
.arg(args::required, "file", [&](auto v) { arg = v; })
.arg(args::required, "file", "Description", [&](auto v) { arg = v; })
All overloads
template<typename T>
parser& arg(T* destination);
template<typename T>
parser& arg(const std::string& name, T* destination);
template<typename T>
parser& arg(const std::string& name, const std::string& description, T* destination);
template<typename T>
parser& arg(args::required_t, const std::string& name, T* destination);
template<typename T>
parser& arg(args::required_t, const std::string& name, const std::string& description,
T* destination);
template<typename T, typename F>
parser& arg(F handler);
template<typename T, typename F>
parser& arg(const std::string& name, F handler);
template<typename T, typename F>
parser& arg(const std::string& name, const std::string& description, F handler);
template<typename T, typename F>
parser& arg(args::required_t, const std::string& name, F handler);
template<typename T, typename F>
parser& arg(args::required_t, const std::string& name, const std::string& description,
F handler);
parser.rest(...) #
parser.rest(destination_ptr);
parser.rest<Value_Type>(lambda);
parser.rest([args::required], name, [description], destination_ptr);
parser.rest<Value_Type>([args::required], name, [description], lambda);
Capture all the rest positional arguments in the container.
[args::required]args::required_tSet optional marker to make option requirednamestd::stringName used in required errors and help generationdescriptionstd::stringDescription used in help generationdestination_ptrT*Set option value by pointerlambdavoid (T)Get option value with lambda
Note! When using lambda first template parameter Value_Type is required.
All overloads example:
auto rest = std::vector<std::string>{};
auto p = parser{}
// using destination_ptr
.rest(&rest)
.rest("cmd", &rest)
.rest("cmd", "Description", &rest)
.rest(args::required, "cmd", &rest)
.rest(args::required, "cmd", "Description", &rest)
// using lambda
.rest([&](auto v) { rest = v; })
.rest("cmd", [&](auto v) { rest = v; })
.rest("cmd", "Description", [&](auto v) { rest = v; })
.rest(args::required, "cmd", [&](auto v) { rest = v; })
.rest(args::required, "cmd", "Description", [&](auto v) { rest = v; })
All overloads
template<typename T>
parser& rest(T* destination);
template<typename T>
parser& rest(const std::string& name, T* destination);
template<typename T>
parser& rest(const std::string& name, const std::string& description, T* destination);
template<typename T>
parser& rest(args::required_t, const std::string& name, T* destination);
template<typename T>
parser& rest(args::required_t, const std::string& name, const std::string& description,
T* destination);
template<typename T, typename F>
parser& rest(F handler);
template<typename T, typename F>
parser& rest(const std::string& name, F handler);
template<typename T, typename F>
parser& rest(const std::string& name, const std::string& description, F handler);
template<typename T, typename F>
parser& rest(args::required_t, const std::string& name, F handler);
template<typename T, typename F>
parser& rest(args::required_t, const std::string& name
parser.command(...) #
parser.command(name, [alias], [description], [destination_ptr]);
Declare command. Returns command instance that could be used to set commands options, arguments and action.
namestd::stringCommand namealiasstd::stringCommand aliasdescriptionstd::stringDescription used in help generationdestination_ptrbool*Set totrueif command is called
Note! When called with only 2 string arguments alias must be single word and description must be multiple words.
All overloads example:
auto command_called = false;
auto p = parser{};
// with destination_ptr
p.command("list", &command_called);
p.command("list", "Description must be multi word", &command_called);
p.command("list all", "la", &command_called);
p.command("list", "l", "Description", &command_called);
// with action
p.command("list")
.action([]() { /* do smt */ });
p.command("list", "Description must be multi word")
.action([]() { /* do smt */ });
p.command("list all", "la")
.action([]() { /* do smt */ });
p.command("list", "l", "Description")
.action([]() { /* do smt */ });
All overloads
command_internal& command(const std::string& name);
command_internal& command(const std::string& name, const std::string& alias_or_desc);
command_internal& command(const std::string& name, const std::string& alias,
const std::string& description);
command_internal& command(const std::string& name, bool* destination);
command_internal& command(const std::string& name, const std::string& alias_or_desc,
bool* destination);
command_internal& command(const std::string& name, const std::string& alias,
const std::string& description, bool* destination);
command.option(...) #
Same as parser.option(...) except it returns command instance.
All overloads
template<typename T>
command_internal& option(const std::string& name, T* destination);
template<typename T>
command_internal& option(args::required_t, const std::string& name, T* destination);
template<typename T, typename F>
command_internal& option(const std::string& name, F handler);
template<typename T, typename F>
command_internal& option(args::required_t, const std::string& name, F handler);
template<typename T>
command_internal& option(const std::string& short_name, const std::string& long_name_or_desc,
T* destination);
template<typename T>
command_internal& option(const std::string& short_name, const std::string& long_name,
const std::string& description, T* destination);
template<typename T>
command_internal& option(args::required_t, const std::string& short_name,
const std::string& long_name_or_desc, T* destination);
template<typename T>
command_internal& option(args::required_t, const std::string& short_name,
const std::string& long_name, const std::string& description, T* destination);
template<typename T, typename F>
command_internal& option(const std::string& short_name,
const std::string& long_name_or_desc, F handler);
template<typename T, typename F>
command_internal& option(const std::string& short_name, const std::string& long_name,
const std::string& description, F handler);
template<typename T, typename F>
command_internal& option(args::required_t, const std::string& short_name,
const std::string& long_name_or_desc, F handler);
template<typename T, typename F>
command_internal& option(args::required_t, const std::string& short_name,
const std::string& long_name, const std::string& description, F handler);
command.arg(...) #
Same as parser.arg(...) except it returns command instance.
All overloads
template<typename T>
command_internal& arg(T* destination);
template<typename T>
command_internal& arg(const std::string& name, T* destination);
template<typename T>
command_internal& arg(const std::string& name, const std::string& description, T* destination);
template<typename T>
command_internal& arg(args::required_t, const std::string& name, T* destination);
template<typename T>
command_internal& arg(args::required_t, const std::string& name, const std::string& description,
T* destination);
template<typename T, typename F>
command_internal& arg(F handler);
template<typename T, typename F>
command_internal& arg(const std::string& name, F handler);
template<typename T, typename F>
command_internal& arg(const std::string& name, const std::string& description, F handler);
template<typename T, typename F>
command_internal& arg(args::required_t, const std::string& name, F handler);
template<typename T, typename F>
command_internal& arg(args::required_t, const std::string& name, const std::string& description,
F handler);
command.rest(...) #
Same as parser.rest(...) except it returns command instance.
All overloads
template<typename T>
command_internal& rest(T* destination);
template<typename T>
command_internal& rest(const std::string& name, T* destination);
template<typename T>
command_internal& rest(const std::string& name, const std::string& description, T* destination);
template<typename T>
command_internal& rest(args::required_t, const std::string& name, T* destination);
template<typename T>
command_internal& rest(args::required_t, const std::string& name, const std::string& description,
T* destination);
template<typename T, typename F>
command_internal& rest(F handler);
template<typename T, typename F>
command_internal& rest(const std::string& name, F handler);
template<typename T, typename F>
command_internal& rest(const std::string& name, const std::string& description, F handler);
template<typename T, typename F>
command_internal& rest(args::required_t, const std::string& name, F handler);
template<typename T, typename F>
command_internal& rest(args::required_t, const std::string& name, const std::string& description,
F handler);
command.action(lambda) #
Call lambda if command is called. Is called after all options and arguments are parsed.
lambdavoid ()Call if command is called
command_internal& action(std::function<void (void)> action);
Example:
auto p = parser{};
p.command("list")
.action([]() { /* do smt */ });
parser.parse(argv, argc) #
Parse options and arguments.
Throws exceptions for invalid options and arguments, unexpected arguments, missing required options, arguments and commands.
argv, argcFrommain()arguments
void parse(int argc, const char** argv);
Exception: args::invalid_option #
When unregistered option is passed.
Subclass std::runtime_error
Properties:
optionstd::string
Exception: args::invalid_option_value #
When failed to parse option value.
Subclass std::runtime_error
Properties:
optionstd::stringvaluestd::string
Exception: args::invalid_command_option_value #
When failed to parse command option value.
Subclass args::invalid_option_value
Properties:
commandstd::stringoptionstd::stringvaluestd::string
Exception: args::invalid_arg_value #
When failed to parse argument value.
Subclass std::runtime_error
Properties:
argstd::stringvaluestd::string
Exception: args::invalid_command_arg_value #
When failed to parse command argument value.
Subclass args::invalid_arg_value
Properties:
commandstd::stringargstd::stringvaluestd::string
Exception: args::unexpected_arg #
When non captured arguments is passed.
Subclass std::runtime_error
Properties:
valuestd::string
Exception: args::missing_command #
When command is required but not passed.
Subclass std::runtime_error
Properties:
commandstd::string
Exception: args::missing_option #
When option is required but not passed.
Subclass std::runtime_error
Properties:
optionstd::string
Exception: args::missing_command_option #
When command option is required but not passed.
Subclass args::missing_option
Properties:
commandstd::stringoptionstd::string
Exception: args::missing_arg #
When positional argument is required but not passed.
Subclass std::runtime_error
Properties:
argstd::string
Exception: args::missing_command_arg #
When command positional argument is required but not passed.
Subclass args::missing_arg
Properties:
commandstd::stringargstd::string
parser.help(lambda) #
Custom --help handler.
If not present will output generated documentation.
See custom-help.cpp example.
lambdavoid ()Call if--helppresent
template<typename F>
parser& help(F help_fun);
parser.format_help([indent]) -> str #
Return generated documentation.
indentstd::stringUse as indentation for help
std::string format_help(const std::string& indentation = default_indentation);
parser.format_command_help(command_name, [indent]) -> str #
Return generated documentation for command.
command_namestd::stringName of alias of the commandindentstd::stringUse as indentation for help
std::string format_command_help(const std::string& command_name,
const std::string& indentation = default_indentation);
parser.format_usage([indent]) -> str #
Return generated usage section.
indentstd::stringUse as indentation for help
std::string format_usage(const std::string& indentation = default_indentation);
parser.format_args([indent]) -> str #
Return generated arguments section.
indentstd::stringUse as indentation for help
std::string format_args(const std::string& indentation = default_indentation);
parser.format_options([indent]) -> str #
Return generated options section.
indentstd::stringUse as indentation for help
std::string format_options(const std::string& indentation = default_indentation);
parser.format_commands([indent]) -> str #
Return generated commands section.
indentstd::stringUse as indentation for help
std::string format_commands(const std::string& indentation = default_indentation);
parser.format_command_usage(command_name, [indent]) -> str #
Return generated command usage section.
command_namestd::stringName of alias of the commandindentstd::stringUse as indentation for help
std::string format_command_usage(const std::string& command_name,
const std::string& indentation = default_indentation);
parser.format_command_args(command_name, [indent]) -> str #
Return generated command args section.
command_namestd::stringName of alias of the commandindentstd::stringUse as indentation for help
std::string format_command_args(const std::string& command_name,
const std::string& indentation = default_indentation);
parser.format_command_options(command_name, [indent]) -> str #
Return generated command options section.
command_namestd::stringName of alias of the commandindentstd::stringUse as indentation for help
std::string format_command_options(const std::string& command_name,
const std::string& indentation = default_indentation);