clipp
clipp copied to clipboard
(feature request) Automatically print default values for options
From docs it looks like the task of displaying a default value for an option is fully on the shoulders of the deveolper. i.e. one should manually write option("-s") & integer("filesize", size).doc("max size of the file (default: " + to_string(size) + ")")
.
It would be nice if the library would provide method to easily display defaults in some sort of "standard way" if it's needed, maybe something like option() & integer.doc().print_default()
I have though about this, too. It is however not as straightforward as it might seem. The interface looks like you could "bind" variables to value parameters. That is however not what happens under the hood. All that ever happens, is that function calls are bound to parameters. Take this example:
int n = 5;
auto v = value("count", n);
or equivalently:
int n = 5;
auto v = value("count").set(n);
Both of the above will actually do this:
int n = 5;
auto v = value("count").call( detail::set(n) );
where detail::set
generates a function object that references n
:
int n = 5;
auto v = value("count").call( detail::map_arg_to<int>{n} );
So all parameters can do is call handler functions (or function objects). And the number of handler functions is potentially unlimited. So you can bind several variables, lambdas, function pointers, etc. to your parameter:
bool customCount = false;
int n = 5;
int m = 3;
double x = 2.0;
auto v1 = value("count", n, m, x, customCount, []{ cout << "count was set"; } );
//which is equivalent to:
auto v2 = value("count")
.set(n)
.set(m)
.set(x)
.set(customCount)
.call([]{ cout << "count was set"; } );
This approach has several advantages but it also means that a parameter has no idea what the default value of an associated variable might be nor would it be unambiguous.
So the problem boils down to this: Which value should be used for the default (n's, m's, ...) and how should it be accessed?
There might be a solution along these lines:
Handler function objects like map_arg_to
could provide a doc generation facility that the user could invoke to print the current value of the object it references. Then I would to make sure, that it did not compile if one tries to call this doc generation in combination with other custom functions or if there was more than one handler function.
So: I have to think about how to do this without breaking interfaces and how to make it easily accessible and unambiguous.
BTW, you could always implement your own factory function:
template<class Target>
clipp::parameter
documented_value(const std::string& name, Target& tgt, const std::string& docstr) {
using std::to_string;
return clipp::value(name,tgt).doc(docstr + "(default: " + to_string(tgt) + ")");
}
OR:
template<class Target>
clipp::parameter
documented_value(const std::string& name, Target& tgt, const std::string& docstr) {
using std::to_string;
return clipp::parameter{}
.label(name).target(tgt)
.required(true).blocking(true).repeatable(false).greedy(false)
.doc(docstr + "(default: " + to_string(tgt) + ")");
}