Sharg 1.1.2-rc.1
The argument parser for bio-c++ tools.
Loading...
Searching...
No Matches
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:

// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0
#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:40
The Sharg command line parser.
Definition parser.hpp:154
void add_option(option_type &value, config< validator_type > const &config)
Adds an option to the sharg::parser.
Definition parser.hpp:243
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:43
char short_id
The short identifier for the option (e.g. 'a', making the option callable via -a).
Definition config.hpp:53
T what(T... args)

Make an external type compatible

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

// SPDX-FileCopyrightText: 2006-2024 Knut Reinert & Freie Universität Berlin
// SPDX-FileCopyrightText: 2016-2024 Knut Reinert & MPI für molekulare Genetik
// SPDX-License-Identifier: CC0-1.0
#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;
}
T is_same_v
Hide me