Skip to content

Commit

Permalink
Add ParmParse::query_enum_sloppy that can ignore characters
Browse files Browse the repository at this point in the history
The characters in the `ignores` argument will be ignored as if they don't
exist in the value part of `name = value`.
  • Loading branch information
WeiqunZhang committed Sep 11, 2024
1 parent 484345c commit 6b9dfe9
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 2 deletions.
63 changes: 63 additions & 0 deletions Src/Base/AMReX_ParmParse.H
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,69 @@ public:
}
}

/**
* \brief. Query enum value using given name.
*
* Here T is an enum class defined by AMREX_ENUM. The return value
* indicates if `name` is found. An exception is thrown, if the found
* string associated with the name cannot be case-insensitively
* converted to an enumerator (i.e., the found string, not `name`, does
* not case-insensitively match any names in the definition of T). If
* there are multiple matches, the first one is used. Characters in
* `ignores` will be ignored as if they don't exist in the value part of
* ParamParse entries (e.g., `name = value`).
*/
template <typename T, typename ET = amrex_enum_traits<T>,
std::enable_if_t<ET::value,int> = 0>
int query_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
int ival = FIRST) const
{
std::string s;
int exist = this->query(name, s, ival);
if (exist) {
try {
s.erase(std::remove_if(s.begin(), s.end(),
[&] (auto const& c) {
return ignores.find(c) != ignores.npos; }),
s.end());
ref = amrex::getEnumCaseInsensitive<T>(s);
} catch (...) {
if (amrex::Verbose() > 0) {
amrex::Print() << "amrex::ParmParse::query_enum_sloppy (input name: "
<< this->prefixedName(name) << "):\n";
}
throw;
}
}
return exist;
}

/**
* \brief. Get enum value using given name.
*
* Here T is an enum class defined by AMREX_ENUM. It's a runtime error,
* if `name` is not found. An exception is thrown, if the found string
* associated with the name cannot be case-insensitively converted to an
* enumerator (i.e., the found string, not `name`, does not
* case-insensitively match any names in the definition of T). If there
* are multiple matches, the first one is used. Characters in `ignores`
* will be ignored as if they don't exist in the value part of
* ParamParse entries (e.g., `name = value`).
*/
template <typename T, typename ET = amrex_enum_traits<T>,
std::enable_if_t<ET::value,int> = 0>
void get_enum_sloppy (const char* name, T& ref, std::string_view const& ignores,
int ival = FIRST) const
{
int exist = this->query_enum_sloppy(name, ref, ignores, ival);
if (!exist) {
std::string msg("get_enum_sloppy(\"");
msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
.append("&) failed.");
amrex::Abort(msg);
}
}

//! Remove given name from the table.
int remove (const char* name);

Expand Down
3 changes: 1 addition & 2 deletions Tests/Enum/inputs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ color2 = green
color3 = blue
color4 = greenxxx
color5 = Blue
color6 = G-r-e-e.n

colors = cyan yellow orange


4 changes: 4 additions & 0 deletions Tests/Enum/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ int main (int argc, char* argv[])
ParmParse pp;
pp.query_enum_case_insensitive("color5", my_blue);
AMREX_ALWAYS_ASSERT(my_blue == MyColor2::blue);

auto my_green = MyColor2::red;
pp.query_enum_sloppy("color6", my_green, "-.");
AMREX_ALWAYS_ASSERT(my_green == MyColor2::green);
}

amrex::Finalize();
Expand Down

0 comments on commit 6b9dfe9

Please sign in to comment.