This HowTo guides you through implementing your own sharg::validator
.
Difficulty | Easy |
Duration | 10 min |
Prerequisite tutorials | |
Recommended reading | |
Motivation
To use a custom validator sharg::validator
, the type must satisfy certain requirements (listed below). This tutorial shows you what requirements must be met and supplies you with a copy and paste source for your code.
sharg::validator
Remember the tutorial on Parsing command line arguments with Sharg ? Let's implement our own validator that checks if a numeric argument is an integral square (i.e. the user shall only be allowed to enter 0, 1, 4, 9...).
Understanding the requirements
In order to model the sharg::validator, your custom validator must provide the following:
- It needs to expose a
value_type
type member which identifies the type of variable the validator works on. Currently, the Sharg validators either have value_type double
or std::string
. Since the validator works on every type that has a common reference type to value_type
, it enables a validator with value_type = double
to work on all arithmetic values. - Attention
- In order to be chainable, the validators need to share the same value_type!
- It has to be a functor, which basically means it must provide
operator()
.
- It has to have a member function
std::string get_help_page_message() const
that returns a string that can be displayed on the help page.
Formally satisfying the requirements
You can check if your type models sharg::validator in the following way:
struct custom_validator
{
};
The concept for option validators passed to add_option/positional_option.
Definition validators.hpp:49
To formally satisfy the requirements, your functions do not need the correct behaviour, yet. Only the signatures need to be fully specified.
Assignment 3: Custom validator I
Implement enough of the above-mentioned struct custom_validator
for it to model sharg::validator and pass the check. You can use an empty main()
-function for now.
Solution
struct custom_validator
{
using option_value_type = double;
void operator()(option_value_type const &) const
{
}
{
return "";
}
};
int main()
{}
Provides sharg::parser class.
Implementing the functionality
The above implementation is of course not yet useful. It should be usable with this main function:
int main(int argc, char ** argv)
{
int32_t variable{};
int16_t variable2{};
myparser.add_option(variable,
.description = "An int that is a square",
.validator = custom_validator{}});
myparser.add_option(variable2,
.description = "An int that is a square and within [0,20].",
.validator = custom_validator{}
try
{
myparser.parse();
}
{
return -1;
}
return 0;
}
A validator that checks whether a number is inside a given range.
Definition validators.hpp:79
Parser exception that is thrown whenever there is an error while parsing the command line arguments.
Definition exceptions.hpp:40
The Sharg command line parser.
Definition parser.hpp:154
Parser exception thrown when an argument could not be casted to the according type.
Definition exceptions.hpp:180
The concept for option validators passed to add_option/positional_option.
Definition validators.hpp:49
Provides sharg::parser class.
Option struct that is passed to the sharg::parser::add_option() function.
Definition config.hpp:43
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition config.hpp:53
Try to think of the correct behaviour of this program.
It should print "Yeah!" for the arguments -i 0
, -i 4
, or -i 144
with -j 0
or -j 4
.
It should fail for the arguments -i 3
with -j 144
or -j 3
.
Assignment 4: Custom validator II
Implement your validator fully, i.e. make it throw
sharg::validation_error if the number provided is not a square. Additionally, give a nice description for the help page.
Solution
struct custom_validator
{
using option_value_type = double;
void operator()(option_value_type const & val) const
{
{
}
}
{
return "Value must be the square of an integral number.";
}
};
You have now written your own type that is compatible with our constrained interfaces!