Skip to content

Commit

Permalink
Value initialization (#416)
Browse files Browse the repository at this point in the history
* work on the flags book chapter and making sure the values are initialized properly.

* Fix initialization of values used in flags or options

* update some formatting and more brace initialization

* update more formatting and fix a incorrect initializer

* more formatting and some error fixes

* more formatting

* Small formatting fix

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
  • Loading branch information
phlptp and henryiii committed Jan 27, 2020
1 parent 0c3020b commit 6b7f6a7
Show file tree
Hide file tree
Showing 24 changed files with 287 additions and 261 deletions.
32 changes: 29 additions & 3 deletions book/chapters/flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The most basic addition to a command line program is a flag. This is simply some
The simplest way to add a flag is probably a boolean flag:

```cpp
bool my_flag;
bool my_flag{false};
app.add_flag("-f", my_flag, "Optional description");
```
Expand All @@ -19,12 +19,38 @@ This will bind the flag `-f` to the boolean `my_flag`. After the parsing step, `
If you want to allow multiple flags, simply use any integer-like instead of a bool:
```cpp
int my_flag;
int my_flag{0};
app.add_flag("-f", my_flag, "Optional description");
```

After the parsing step, `my_flag` will contain the number of times this flag was found on the command line, including 0 if not found.

## Arbitrary type flags

CLI11 allows the type of the variable to assign to in the `add_flag` function to be any supported type. This is particularly useful in combination with specifying default values for flags. The allowed types include bool, int, float, vector, enum, or string-like.

### Default Flag Values

Flag options specified through the `add_flag*` functions allow a syntax for the option names to default particular options to a false value or any other value if some flags are passed. For example:

```cpp
app.add_flag("--flag,!--no-flag",result,"help for flag");
```

specifies that if `--flag` is passed on the command line result will be true or contain a value of 1. If `--no-flag` is
passed `result` will contain false or -1 if `result` is a signed integer type, or 0 if it is an unsigned type. An
alternative form of the syntax is more explicit: `"--flag,--no-flag{false}"`; this is equivalent to the previous
example. This also works for short form options `"-f,!-n"` or `"-f,-n{false}"`. If `variable_to_bind_to` is anything but an integer value the
default behavior is to take the last value given, while if `variable_to_bind_to` is an integer type the behavior will be to sum
all the given arguments and return the result. This can be modified if needed by changing the `multi_option_policy` on each flag (this is not inherited).
The default value can be any value. For example if you wished to define a numerical flag:

```cpp
app.add_flag("-1{1},-2{2},-3{3}",result,"numerical flag")
```

using any of those flags on the command line will result in the specified number in the output. Similar things can be done for string values, and enumerations, as long as the default value can be converted to the given type.

## Pure flags

Every command that starts with `add_`, such as the flag commands, return a pointer to the internally stored `CLI::Option` that describes your addition. If you prefer, you can capture this pointer and use it, and that allows you to skip adding a variable to bind to entirely:
Expand Down Expand Up @@ -52,7 +78,7 @@ The name string, the first item of every `add_` method, can contain as many shor
If you want to make an option case insensitive, you can use the `->ignore_case()` method on the `CLI::Option` to do that. For example,

```cpp
bool flag;
bool flag{false};
app.add_flag("--flag", flag)
->ignore_case();
```
Expand Down
10 changes: 5 additions & 5 deletions book/chapters/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ The most versatile addition to a command line program is a option. This is like


```cpp
int int_option;
int int_option{0};
app.add_option("-i", int_option, "Optional description");
```
This will bind the option `-i` to the integer `int_option`. On the command line, a single value that can be converted to an integer will be expected. Non-integer results will fail. If that option is not given, CLI11 will not touch the initial value. This allows you to set up defaults by simply setting your value beforehand. If you want CLI11 to display your default value, you can add the optional final argument `true` when you add the option. If you do not add this, you do not even need your option value to be printable[^1].
```cpp
int int_option = 0;
int int_option{0};
app.add_option("-i", int_option, "Optional description", true);
```

Expand Down Expand Up @@ -138,7 +138,7 @@ Besides `add_option` and `add_flag`, there are several special ways to create op
You can add a set with `add_set`, where you give a variable to set and a `std::set` of choices to pick from. There also is a `add_set_ignore_case` version which ignores case when set matching. If you use an existing set instead of an inline one, you can edit the set after adding it and changes will be reflected in the set checking and help message.
```cpp
int val;
int val{0};
app.add_set("--even", val, {0,2,4,6,8});
```

Expand All @@ -147,7 +147,7 @@ app.add_set("--even", val, {0,2,4,6,8});
You can also add a complex number. This type just needs to support a `(T x, T y)` constructor and be printable. You can also pass one extra argument that will set the label of the type; by default it is "COMPLEX".

```cpp
std::complex<float> val;
std::complex<float> val{0.0F,0.0F};
app.add_complex("--cplx", val);
```
Expand Down Expand Up @@ -197,7 +197,7 @@ app.add_option("--opt",val,"description");
gets into the complicated cases where the type size is now 3. and the expected max is set to a large number and `allow_extra_args` is set to true. In this case at least 3 arguments are required to follow the option, and subsequent groups must come in groups of three, otherwise an error will result.

```cpp
bool val;
bool val{false};
app.add_flag("--opt",val,"description");
```
Expand Down
2 changes: 1 addition & 1 deletion examples/digit_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
int main(int argc, char **argv) {
CLI::App app;

int val;
int val{0};
// add a set of flags with default values associate with them
app.add_flag("-1{1},-2{2},-3{3},-4{4},-5{5},-6{6}, -7{7}, -8{8}, -9{9}", val, "compression level");

Expand Down
4 changes: 2 additions & 2 deletions examples/groups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ int main(int argc, char **argv) {
std::string file;
CLI::Option *opt = app.add_option("-f,--file,file", file, "File name")->required()->group("Important");

int count;
int count{0};
CLI::Option *copt = app.add_flag("-c,--count", count, "Counter")->required()->group("Important");

double value; // = 3.14;
double value{0.0}; // = 3.14;
app.add_option("-d,--double", value, "Some Value")->group("Other");

try {
Expand Down
6 changes: 3 additions & 3 deletions examples/option_groups.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ int main(int argc, char **argv) {

auto format = app.add_option_group("output_format", "formatting type for output");
auto target = app.add_option_group("output target", "target location for the output");
bool csv = false;
bool human = false;
bool binary = false;
bool csv{false};
bool human{false};
bool binary{false};
format->add_flag("--csv", csv, "specify the output in csv format");
format->add_flag("--human", human, "specify the output in human readable text format");
format->add_flag("--binary", binary, "specify the output in binary format");
Expand Down
2 changes: 1 addition & 1 deletion examples/positional_arity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main(int argc, char **argv) {

auto numbers = app.add_option_group("numbers", "specify key numbers");
auto files = app.add_option_group("files", "specify files");
int num1 = -1, num2 = -1;
int num1{-1}, num2{-1};
numbers->add_option("num1", num1, "first number");
numbers->add_option("num2", num2, "second number");
std::string file1, file2;
Expand Down
2 changes: 1 addition & 1 deletion examples/positional_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ int main(int argc, char **argv) {

CLI::App app("test for positional validation");

int num1 = -1, num2 = -1;
int num1{-1}, num2{-1};
app.add_option("num1", num1, "first number")->check(CLI::Number);
app.add_option("num2", num2, "second number")->check(CLI::Number);
std::string file1, file2;
Expand Down
2 changes: 1 addition & 1 deletion examples/ranges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ int main(int argc, char **argv) {
app.add_option("--range,-R", range, "A range")->expected(-2);

auto ogroup = app.add_option_group("min_max_step", "set the min max and step");
int min, max, step = 1;
int min{0}, max{0}, step{1};
ogroup->add_option("--min,-m", min, "The minimum")->required();
ogroup->add_option("--max,-M", max, "The maximum")->required();
ogroup->add_option("--step,-s", step, "The step", true);
Expand Down
4 changes: 2 additions & 2 deletions examples/shapes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int main(int argc, char **argv) {
app.set_help_all_flag("--help-all");
auto circle = app.add_subcommand("circle", "draw a circle")->immediate_callback();
double radius{0.0};
int circle_counter = 0;
int circle_counter{0};
circle->callback([&radius, &circle_counter] {
++circle_counter;
std::cout << "circle" << circle_counter << " with radius " << radius << std::endl;
Expand All @@ -20,7 +20,7 @@ int main(int argc, char **argv) {
auto rect = app.add_subcommand("rectangle", "draw a rectangle")->immediate_callback();
double edge1{0.0};
double edge2{0.0};
int rect_counter = 0;
int rect_counter{0};
rect->callback([&edge1, &edge2, &rect_counter] {
++rect_counter;
if(edge2 == 0) {
Expand Down
6 changes: 3 additions & 3 deletions examples/simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ int main(int argc, char **argv) {
std::string file;
CLI::Option *opt = app.add_option("-f,--file,file", file, "File name");

int count;
int count{0};
CLI::Option *copt = app.add_option("-c,--count", count, "Counter");

int v;
int v{0};
CLI::Option *flag = app.add_flag("--flag", v, "Some flag that can be passed multiple times");

double value; // = 3.14;
double value{0.0}; // = 3.14;
app.add_option("-d,--double", value, "Some Value");

CLI11_PARSE(app, argc, argv);
Expand Down
4 changes: 2 additions & 2 deletions examples/subcom_partitioned.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ int main(int argc, char **argv) {
std::string file;
CLI::Option *opt = impOpt->add_option("-f,--file,file", file, "File name")->required();

int count;
int count{0};
CLI::Option *copt = impOpt->add_flag("-c,--count", count, "Counter")->required();

CLI::App_p otherOpt = std::make_shared<CLI::App>("Other");
double value; // = 3.14;
double value{0.0}; // = 3.14;
otherOpt->add_option("-d,--double", value, "Some Value");

// add the subapps to the main one
Expand Down
2 changes: 1 addition & 1 deletion examples/validators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ int main(int argc, char **argv) {
std::string file;
app.add_option("-f,--file,file", file, "File name")->check(CLI::ExistingFile);

int count;
int count{0};
app.add_option("-v,--value", count, "Value in range")->check(CLI::Range(3, 6));
CLI11_PARSE(app, argc, argv);

Expand Down
Loading

0 comments on commit 6b7f6a7

Please sign in to comment.