6#ifndef commandline_parser_h
7#define commandline_parser_h
17 static std::mutex sync;
25 std::map<std::string, std::pair<bool, std::string>> options;
27 std::map<std::string, std::string> parsed_options;
29 std::map<std::string, std::set<std::string>> option_values;
31 const std::string command;
39 static std::string_view take_end(
const char *
string,
40 const char character) {
41 std::string_view view(
string);
42 return view.substr(view.find_last_of(character) + 1);
50 command(take_end(name,
'/')) {
51 options.try_emplace(
"help",
false,
"Show this help.");
63 const bool takes_value,
64 const std::string &help_text,
65 const std::set<std::string> &values = {}) {
66 options.try_emplace(option, takes_value, help_text);
67 if (!values.empty()) {
68 option_values.try_emplace(option, values);
80 for (
auto &[option, value] : options) {
81 longest = std::max(longest, option.size());
83 std::cout <<
"USAGE: " << command <<
" [--options] [--options=with_value]" << std::endl << std::endl;
84 std::cout <<
"OPTIONS:" << std::endl;
85 for (
auto &[option, value] : options) {
86 std::cout <<
" --" << option
87 << (std::get<bool> (value) ?
"= " :
" ");
88 for (
size_t i = option.size(); i < longest; i++) {
91 std::cout << std::get<std::string> (value) << std::endl;
92 if (option_values.find(option) != option_values.cend()) {
93 for (
auto &option_value : option_values.at(option)) {
95 for (
size_t i = 0; i < longest; i++) {
98 std::cout <<
" * " << option_value << std::endl;
102 std::cout << std::endl;
113 void parse(
const int argc,
const char * argv[]) {
114 for (
int i = 1; i < argc; i++) {
115 std::string_view view(argv[i]);
116 const size_t option_end = view.find_first_of(
'=');
117 std::string option(view.substr(2, option_end - 2));
119 std::cout <<
"Warning --" << option <<
" set more than once." << std::endl;
120 std::cout <<
" Overwriting --" << option << std::endl;
122 if (options.find(option) == options.cend()) {
123 std::cout <<
"UNKNOWN OPTION: " << view << std::endl << std::endl;
126 if (option_end != view.size()) {
127 parsed_options[option] = std::string(view.substr(option_end + 1));
128 if ((option_values.find(option) != option_values.cend()) &&
129 !(option_values.at(option).find(parsed_options[option]) !=
130 option_values.at(option).cend())) {
131 std::cout <<
"UNKNOWN VALUE: " << parsed_options[option]
132 << std::endl << std::endl;
135 parsed_options[option] =
"";
150 return parsed_options.find(option) != parsed_options.cend();
161 std::string value = parsed_options.at(option);
162 if constexpr (std::is_same<T, std::string> ()) {
164 }
else if constexpr (std::is_same<T, float> () ||
165 std::is_same<T, std::complex<float>> ()) {
166 return static_cast<T
> (std::stof(value));
167 }
else if constexpr (std::is_same<T, double> () ||
168 std::is_same<T, std::complex<double>> ()) {
169 return static_cast<T
> (std::stod(value));
170 }
else if constexpr (std::is_same<T, int> ()) {
171 return std::stoi(value);
172 }
else if constexpr (std::is_same<T, long> ()) {
173 return std::stol(value);
174 }
else if constexpr (std::is_same<T, unsigned long> ()) {
175 return std::stoul(value);
178 std::cout <<
"Expected option : --" << option << std::endl << std::endl;
Parser class.
Definition commandline_parser.hpp:22
void add_option(const std::string &option, const bool takes_value, const std::string &help_text, const std::set< std::string > &values={})
Add commandline option.
Definition commandline_parser.hpp:62
parser(const char *name)
Default constructor.
Definition commandline_parser.hpp:49
void show_help(const std::string &command) const
Display help.
Definition commandline_parser.hpp:77
T get_option_value(const std::string &option) const
Get the option value.
Definition commandline_parser.hpp:159
bool is_option_set(const std::string &option) const
Check if option is set.
Definition commandline_parser.hpp:149
void parse(const int argc, const char *argv[])
Parse the command line.
Definition commandline_parser.hpp:113
Name space for the command line parsing.
Definition commandline_parser.hpp:15