Skip to content

Commit 6cc0e16

Browse files
committed
add custom parse example
1 parent e2e3cb2 commit 6cc0e16

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,7 @@ Every `add_` option you have seen so far depends on one method that takes a lamb
800800

801801
Other values can be added as long as they support `operator>>` (and defaults can be printed if they support `operator<<`). To add a new type, for example, provide a custom `operator>>` with an `istream` (inside the CLI namespace is fine if you don't want to interfere with an existing `operator>>`).
802802

803-
If you wanted to extend this to support a completely new type, use a lambda or add a specialization of the `lexical_cast` function template in the namespace `CLI::detail` with the type you need to convert to. Some examples of some new parsers for `complex<double>` that support all of the features of a standard `add_options` call are in [one of the tests](./tests/NewParseTest.cpp). A simpler example is shown below:
803+
If you wanted to extend this to support a completely new type, use a lambda or add a specialization of the `lexical_cast` function template in the namespace of the type you need to convert to. Some examples of some new parsers for `complex<double>` that support all of the features of a standard `add_options` call are in [one of the tests](./tests/NewParseTest.cpp). A simpler example is shown below:
804804

805805
#### Example
806806

@@ -872,6 +872,7 @@ The API is [documented here][api-docs]. Also see the [CLI11 tutorial GitBook][gi
872872
Several short examples of different features are included in the repository. A brief description of each is included here
873873
874874
- [callback_passthrough](https://github.com/CLIUtils/CLI11/blob/master/examples/callback_passthrough.cpp): Example of directly passing remaining arguments through to a callback function which generates a CLI11 application based on existing arguments.
875+
- [custom_parse](https://github.com/CLIUtils/CLI11/blob/master/examples/custom_parse.cpp): Based on [Issue #566](https://github.com/CLIUtils/CLI11/issues/566), example of custom parser
875876
- [digit_args](https://github.com/CLIUtils/CLI11/blob/master/examples/digit_args.cpp): Based on [Issue #123](https://github.com/CLIUtils/CLI11/issues/123), uses digit flags to pass a value
876877
- [enum](https://github.com/CLIUtils/CLI11/blob/master/examples/enum.cpp): Using enumerations in an option, and the use of [CheckedTransformer](#transforming-validators)
877878
- [enum_ostream](https://github.com/CLIUtils/CLI11/blob/master/examples/enum_ostream.cpp): In addition to the contents of example enum.cpp, this example shows how a custom ostream operator overrides CLI11's enum streaming.

examples/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,8 @@ set_property(TEST retired_retired_test2 PROPERTY PASS_REGULAR_EXPRESSION "WARNIN
226226
set_property(TEST retired_retired_test3 PROPERTY PASS_REGULAR_EXPRESSION "WARNING.*retired")
227227

228228
set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION "deprecated.*not_deprecated")
229+
230+
#--------------------------------------------
231+
add_cli_exe(custom_parse custom_parse.cpp)
232+
add_test(NAME cp_test COMMAND custom_parse --dv 1.7)
233+
set_property(TEST cp_test PROPERTY PASS_REGULAR_EXPRESSION "called correct")

examples/custom_parse.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/** from Issue #566 on github https://github.com/CLIUtils/CLI11/issues/566 */
2+
3+
#include <CLI/CLI.hpp>
4+
#include <iostream>
5+
#include <sstream>
6+
/** example file to demonstrate a custom lexical cast function*/
7+
8+
template <class T = int> struct Values {
9+
T a;
10+
T b;
11+
T c;
12+
};
13+
14+
/** in C++20 this is constructible from a double due to the new aggregate initialization in C++20.*/
15+
using DoubleValues = Values<double>;
16+
17+
auto &&operator>>(std::istringstream &in, Values<double> &v) {
18+
std::string input;
19+
in >> input;
20+
std::cout << "called correct function " __FUNCTION__ " ! "
21+
"val: "
22+
<< input << std::endl;
23+
return in;
24+
}
25+
// the lexical cast operator should be in the same namespace as the type for ADL to work properly
26+
bool lexical_cast(const std::string &input, Values<double> &v) {
27+
std::cout << "called correct function " __FUNCTION__ " ! "
28+
"val: "
29+
<< input << std::endl;
30+
return true;
31+
}
32+
33+
DoubleValues doubles;
34+
void argparse(CLI::Option_group *group) { group->add_option("--dv", doubles)->default_str("0"); }
35+
36+
int main(int argc, char **argv) {
37+
CLI::App app;
38+
39+
argparse(app.add_option_group("param"));
40+
CLI11_PARSE(app, argc, argv);
41+
return 0;
42+
}

0 commit comments

Comments
 (0)