sharg 1.0.0
THE argument parser for bio-c++ tools.
How to make your custom type model sharg::parsable

This HowTo guides you through satisfying the requirements of sharg::parsable.

DifficultyEasy
Duration10 min
Prerequisite tutorials
Recommended reading

Motivation

To use a custom type with sharg::parser::add_option or sharg::parser::add_positional_option, the type must satisfy sharg::parsable. This tutorial shows you what requirements must be met and supplies you with a copy and paste source for your code.

Concept sharg::parsable

As you can see in the API documentation of sharg::parsable, the type must model either both sharg::istreamable and sharg::ostreamable or sharg::named_enumeration.

If your type is an enum, refer to sharg::enumeration_names on how to make it compatible with the sharg::parser.

In all other cases, your type needs to model sharg::istreamable and sharg::ostreamable. As you can see in the respective documentation, the concept is simple. You merely need to supply the stream operators operator>>() and operator<<() for your type.

Make your own type compatible

Note
You must be able to modify the class itself for this solution to work.

The following example makes the class bar in namespace foo compatible with the sharg::parser:

#include <sharg/all.hpp>
// my custom type
namespace foo
{
class bar
{
public:
int a;
// Make foo::bar satisfy sharg::ostreamable
friend std::ostream & operator<<(std::ostream & output, bar const & my_bar)
{
output << my_bar.a; // Adapt this for your type
return output;
}
// Make foo::bar satisfy sharg::istreamable
friend std::istream & operator>>(std::istream & input, bar & my_bar)
{
input >> my_bar.a; // Adapt this for your type
return input;
}
};
} // namespace foo
int main(int argc, char const ** argv)
{
sharg::parser parser{"my_foobar_parser", argc, argv, sharg::update_notifications::off};
foo::bar my_bar{};
parser.add_option(my_bar,
sharg::config{.short_id = 'f', .long_id = "foo-bar", .description = "Supply an integer."});
try
{
parser.parse(); // trigger command line parsing
}
catch (sharg::parser_error const & ext) // catch user errors
{
std::cerr << "[Error] " << ext.what() << "\n"; // customise your error message
return -1;
}
std::cout << "my_bar was initialised with a = " << my_bar.a << std::endl;
return 0;
}
Meta-header for the Parser module .
Parser exception that is thrown whenever there is an error while parsing the command line arguments.
Definition: exceptions.hpp:43
The Sharg command line parser.
Definition: parser.hpp:156
T endl(T... args)
@ off
Automatic update notifications should be disabled.
Option struct that is passed to the sharg::parser::add_option() function.
Definition: config.hpp:46
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition: config.hpp:56
T what(T... args)

Make an external type compatible

If you cannot modify the class, you can do the following:

#include <sharg/all.hpp>
// external type, i.e., you cannot change the implementation
namespace external
{
class bar
{
public:
int a;
};
} // namespace external
namespace std
{
// Make external::bar satisfy sharg::ostreamable
ostream & operator<<(ostream & output, external::bar const & ext_bar)
{
output << ext_bar.a; // Adapt this for your type
return output;
}
// Make external::bar satisfy sharg::istreamable
istream & operator>>(istream & input, external::bar & ext_bar)
{
input >> ext_bar.a; // Adapt this for your type
return input;
}
} // namespace std
int main(int argc, char const ** argv)
{
sharg::parser parser{"my_ext_bar_parser", argc, argv, sharg::update_notifications::off};
external::bar ext_bar{};
parser.add_option(ext_bar, sharg::config{.short_id = 'f', .long_id = "ext-bar", .description = "Supply an int."});
try
{
parser.parse(); // trigger command line parsing
}
catch (sharg::parser_error const & ext) // catch user errors
{
std::cerr << "[Error] " << ext.what() << "\n"; // customise your error message
return -1;
}
std::cout << "ext_bar was initialised with a = " << ext_bar.a << std::endl;
return 0;
}