Skip to content

Commit

Permalink
[MISC] Defer everything to parse()
Browse files Browse the repository at this point in the history
  • Loading branch information
eseiler committed Feb 12, 2024
1 parent 9c33c36 commit 022ed36
Showing 1 changed file with 81 additions and 45 deletions.
126 changes: 81 additions & 45 deletions include/sharg/parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,7 @@ class parser
subcommands{std::move(subcommands)},
original_arguments{arguments}
{
for (auto & sub : this->subcommands)
{
if (!std::regex_match(sub, app_name_regex))
{
throw design_error{"The subcommand name must only contain alpha-numeric characters or '_' and '-' "
"(regex: \"^[a-zA-Z0-9_-]+$\")."};
}
}

info.app_name = app_name;

init();
}

//!\overload
Expand Down Expand Up @@ -252,14 +241,17 @@ class parser
{
verify_option_config(config);

// copy variables into the lambda because the calls are pushed to a stack
// and the references would go out of scope.
std::visit(
[&value, &config](auto & f)
auto operation = [this, &value, config]()
{
auto visit_fn = [&value, &config](auto & f)
{
f.add_option(value, config);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}

/*!\brief Adds a flag to the sharg::parser.
Expand All @@ -281,14 +273,17 @@ class parser
if (value)
throw design_error("A flag's default value must be false.");

// copy variables into the lambda because the calls are pushed to a stack
// and the references would go out of scope.
std::visit(
[&value, &config](auto & f)
auto operation = [this, &value, config]()
{
auto visit_fn = [&value, &config](auto & f)
{
f.add_flag(value, config);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}

/*!\brief Adds a positional option to the sharg::parser.
Expand Down Expand Up @@ -323,14 +318,17 @@ class parser
if constexpr (detail::is_container_option<option_type>)
has_positional_list_option = true; // keep track of a list option because there must be only one!

// copy variables into the lambda because the calls are pushed to a stack
// and the references would go out of scope.
std::visit(
[&value, &config](auto & f)
auto operation = [this, &value, config]()
{
auto visit_fn = [&value, &config](auto & f)
{
f.add_positional_option(value, config);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}
//!\}

Expand Down Expand Up @@ -414,8 +412,19 @@ class parser
"(regex: \"^[a-zA-Z0-9_-]+$\").")};
}

for (auto & sub : this->subcommands)
{
if (!std::regex_match(sub, app_name_regex))
{
throw design_error{"The subcommand name must only contain alpha-numeric characters or '_' and '-' "
"(regex: \"^[a-zA-Z0-9_-]+$\")."};
}
}

detail::version_checker app_version{info.app_name, info.version, info.url};

init();

if (std::holds_alternative<detail::format_parse>(format) && !subcommands.empty() && sub_parser == nullptr)
{
assert(!subcommands.empty());
Expand All @@ -438,6 +447,10 @@ class parser
version_check_future = app_version_prom.get_future();
app_version(std::move(app_version_prom));
}

for (auto & operation : operations)
operation();

std::visit(
[this]<typename T>(T & f)
{
Expand Down Expand Up @@ -545,12 +558,17 @@ class parser
*/
void add_section(std::string const & title, bool const advanced_only = false)
{
std::visit(
[&title, advanced_only](auto & f)
auto operation = [this, title, advanced_only]()
{
auto visit_fn = [&title, advanced_only](auto & f)
{
f.add_section(title, advanced_only);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}

/*!\brief Adds an help page subsection to the sharg::parser.
Expand All @@ -564,12 +582,17 @@ class parser
*/
void add_subsection(std::string const & title, bool const advanced_only = false)
{
std::visit(
[&title, advanced_only](auto & f)
auto operation = [this, title, advanced_only]()
{
auto visit_fn = [&title, advanced_only](auto & f)
{
f.add_subsection(title, advanced_only);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}

/*!\brief Adds an help page text line to the sharg::parser.
Expand All @@ -584,12 +607,17 @@ class parser
*/
void add_line(std::string const & text, bool is_paragraph = false, bool const advanced_only = false)
{
std::visit(
[&text, is_paragraph, advanced_only](auto & f)
auto operation = [this, text, is_paragraph, advanced_only]()
{
auto visit_fn = [&text, is_paragraph, advanced_only](auto & f)
{
f.add_line(text, is_paragraph, advanced_only);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}

/*!\brief Adds an help page list item (key-value) to the sharg::parser.
Expand All @@ -613,12 +641,17 @@ class parser
*/
void add_list_item(std::string const & key, std::string const & desc, bool const advanced_only = false)
{
std::visit(
[&key, &desc, advanced_only](auto & f)
auto operation = [this, key, desc, advanced_only]()
{
auto visit_fn = [&key, &desc, advanced_only](auto & f)
{
f.add_list_item(key, desc, advanced_only);
},
format);
};

std::visit(std::move(visit_fn), format);
};

operations.push_back(std::move(operation));
}
//!\}

Expand Down Expand Up @@ -734,6 +767,9 @@ class parser
//!\brief The command that lead to calling this parser, e.g. [./build/bin/raptor, build]
std::vector<std::string> executable_name{};

//!\brief Vector of functions that stores all calls.
std::vector<std::function<void()>> operations;

/*!\brief Initializes the sharg::parser class on construction.
* \throws sharg::too_few_arguments if option --export-help was specified without a value
* \throws sharg::too_few_arguments if option --version-check was specified without a value
Expand Down

0 comments on commit 022ed36

Please sign in to comment.