Skip to content

Commit

Permalink
Fix ParmParse::query_enum_case_insensitive (#4144)
Browse files Browse the repository at this point in the history
Since #4143, we can no longer cast the position of the found string in
the vector of all names to obtain its enum value, because the enum
values can now have duplicates.
  • Loading branch information
WeiqunZhang authored Sep 11, 2024
1 parent d572928 commit 484345c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 13 deletions.
20 changes: 20 additions & 0 deletions Src/Base/AMReX_Enum.H
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ namespace amrex
}
}

template <typename T, typename ET = amrex_enum_traits<T>,
std::enable_if_t<ET::value,int> = 0>
T getEnumCaseInsensitive (std::string_view const& s)
{
auto const& kv = getEnumNameValuePairs<T>();
std::string ls = amrex::toLower(std::string(s));
auto it = std::find_if(kv.begin(), kv.end(),
[&] (auto const& x) -> bool
{ return amrex::toLower(x.first) == ls; });
if (it != kv.end()) {
return it->second;
} else {
std::string error_msg("amrex::getEnumCaseInsensitive: Unknown enum: ");
error_msg.append(s).append(" in AMREX_ENUM(").append(ET::class_name)
.append(", ").append(ET::enum_names).append(").");
throw std::runtime_error(error_msg);
return T();
}
}

template <typename T, typename ET = amrex_enum_traits<T>,
std::enable_if_t<ET::value,int> = 0>
std::string getEnumNameString (T const& v)
Expand Down
21 changes: 8 additions & 13 deletions Src/Base/AMReX_ParmParse.H
Original file line number Diff line number Diff line change
Expand Up @@ -1329,19 +1329,14 @@ public:
std::string s;
int exist = this->query(name, s, ival);
if (exist) {
s = amrex::toLower(s);
auto const& enum_names = amrex::getEnumNameStrings<T>();
auto found = std::find_if(enum_names.begin(), enum_names.end(),
[&] (std::string const& ename) {
return amrex::toLower(ename) == s;
});
if (found != enum_names.end()) {
ref = static_cast<T>(std::distance(enum_names.begin(), found));
} else {
std::string msg("query_enum_case_insensitive(\"");
msg.append(name).append("\",").append(amrex::getEnumClassName<T>())
.append("&) failed.");
throw std::runtime_error(msg);
try {
ref = amrex::getEnumCaseInsensitive<T>(s);
} catch (...) {
if (amrex::Verbose() > 0) {
amrex::Print() << "amrex::ParmParse::query_enum_case_insensitive (input name: "
<< this->prefixedName(name) << "):\n";
}
throw;
}
}
return exist;
Expand Down
5 changes: 5 additions & 0 deletions Tests/Enum/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ int main (int argc, char* argv[])
AMREX_ALWAYS_ASSERT(amrex::getEnum<MyColor2>("green") == MyColor2::green);
AMREX_ALWAYS_ASSERT(amrex::getEnum<MyColor2>("blue") == MyColor2::blue);
AMREX_ALWAYS_ASSERT(amrex::getEnum<MyColor2>("Default") == MyColor2::Default);

auto my_blue = MyColor2::Default;
ParmParse pp;
pp.query_enum_case_insensitive("color5", my_blue);
AMREX_ALWAYS_ASSERT(my_blue == MyColor2::blue);
}

amrex::Finalize();
Expand Down

0 comments on commit 484345c

Please sign in to comment.