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
--help
handler - 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
--help
documentation + for commands - Build-in error messages for invalid/required options, arguments, commands
- Supports non conventional options:
-frtti, -fno-rtti, +fb
- Supports pairs
key=value
as option value - Supports any type that could be parsed with
std::stringstream
-
1, 0, true, false, on, off, yes, no
values forbool
flags - Implicitly add
--no-flag
forbool
flags - Supports
--
- Supports
std::vector
-like containers for repeated options - Supports
std::pair
forkey=value
option value - Supports
std::map
-like containers for repeatedkey=value
option 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_t
Set optional marker to make option requiredname
std::string
Short-s
, long--long
or non conventional+fb, -fno-rtti
short_name
std::string
Short-s
long_name
std::string
Long--long
destination_ptr
T*
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_t
Set optional marker to make option requiredname
std::string
Short-s
, long--long
or non conventional+fb, -fno-rtti
short_name
std::string
Short-s
long_name
std::string
Long--long
description
std::string
Description used in help generationdestination_ptr
T*
Set option value by pointerlambda
void (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_t
Set optional marker to make option requiredname
std::string
Name used in required errors and help generationdescription
std::string
Description used in help generationdestination_ptr
T*
Set option value by pointerlambda
void (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_t
Set optional marker to make option requiredname
std::string
Name used in required errors and help generationdescription
std::string
Description used in help generationdestination_ptr
T*
Set option value by pointerlambda
void (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.
name
std::string
Command namealias
std::string
Command aliasdescription
std::string
Description used in help generationdestination_ptr
bool*
Set totrue
if 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.
lambda
void ()
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, argc
Frommain()
arguments
void parse(int argc, const char** argv);
Exception: args::invalid_option #
When unregistered option is passed.
Subclass std::runtime_error
Properties:
option
std::string
Exception: args::invalid_option_value #
When failed to parse option value.
Subclass std::runtime_error
Properties:
option
std::string
value
std::string
Exception: args::invalid_command_option_value #
When failed to parse command option value.
Subclass args::invalid_option_value
Properties:
command
std::string
option
std::string
value
std::string
Exception: args::invalid_arg_value #
When failed to parse argument value.
Subclass std::runtime_error
Properties:
arg
std::string
value
std::string
Exception: args::invalid_command_arg_value #
When failed to parse command argument value.
Subclass args::invalid_arg_value
Properties:
command
std::string
arg
std::string
value
std::string
Exception: args::unexpected_arg #
When non captured arguments is passed.
Subclass std::runtime_error
Properties:
value
std::string
Exception: args::missing_command #
When command is required but not passed.
Subclass std::runtime_error
Properties:
command
std::string
Exception: args::missing_option #
When option is required but not passed.
Subclass std::runtime_error
Properties:
option
std::string
Exception: args::missing_command_option #
When command option is required but not passed.
Subclass args::missing_option
Properties:
command
std::string
option
std::string
Exception: args::missing_arg #
When positional argument is required but not passed.
Subclass std::runtime_error
Properties:
arg
std::string
Exception: args::missing_command_arg #
When command positional argument is required but not passed.
Subclass args::missing_arg
Properties:
command
std::string
arg
std::string
parser.help(lambda) #
Custom --help
handler.
If not present will output generated documentation.
See custom-help.cpp example.
lambda
void ()
Call if--help
present
template<typename F>
parser& help(F help_fun);
parser.format_help([indent]) -> str #
Return generated documentation.
indent
std::string
Use 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_name
std::string
Name of alias of the commandindent
std::string
Use 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.
indent
std::string
Use as indentation for help
std::string format_usage(const std::string& indentation = default_indentation);
parser.format_args([indent]) -> str #
Return generated arguments section.
indent
std::string
Use as indentation for help
std::string format_args(const std::string& indentation = default_indentation);
parser.format_options([indent]) -> str #
Return generated options section.
indent
std::string
Use as indentation for help
std::string format_options(const std::string& indentation = default_indentation);
parser.format_commands([indent]) -> str #
Return generated commands section.
indent
std::string
Use 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_name
std::string
Name of alias of the commandindent
std::string
Use 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_name
std::string
Name of alias of the commandindent
std::string
Use 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_name
std::string
Name of alias of the commandindent
std::string
Use as indentation for help
std::string format_command_options(const std::string& command_name,
const std::string& indentation = default_indentation);