Skip to content

Commit 80fcecb

Browse files
authored
AMREX_ENUM: Fix enumerator = int (#4766)
Previously, we only considered enumerator = constant-expression, where constant-expression is an enumerator, but not an int.
1 parent aa6df80 commit 80fcecb

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

Src/Base/AMReX_Enum.H

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,19 @@ namespace detail
3434
++next_value;
3535
} else if (kv.size() == 2) {
3636
auto const& value_string = amrex::trim(kv[1]);
37+
// For k = v, find if v exists as a key. If not, v must be an int.
3738
auto it = std::find_if(r.begin(), r.end(),
3839
[&] (auto const& x) -> bool
3940
{ return x.first == value_string; });
40-
auto this_value = it->second;
41+
T this_value;
42+
if (it != r.end()) {
43+
this_value = it->second;
44+
} else { // v is an int
45+
// Note that if value_string is not a valid string for int,
46+
// it will fail at compile time, because the compiler
47+
// will not allow something like `enum FOO : int { x = 3% }`.
48+
this_value = static_cast<T>(std::stoi(value_string));
49+
}
4150
r.emplace_back(amrex::trim(kv[0]), this_value);
4251
next_value = static_cast<int>(this_value) + 1;
4352
} else {

Tests/Enum/main.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ AMREX_ENUM(MyColor2,
1717
blue, // 2
1818
Default = green); // 1
1919

20+
AMREX_ENUM(Location, entry = 1, exit = -1, after_exit);
21+
2022
int main (int argc, char* argv[])
2123
{
2224
amrex::Initialize(argc, argv);
@@ -140,5 +142,27 @@ int main (int argc, char* argv[])
140142
AMREX_ALWAYS_ASSERT(my_green == MyColor2::green);
141143
}
142144

145+
146+
{
147+
auto const& kv = amrex::getEnumNameValuePairs<Location>();
148+
amrex::Print() << "Name : Value\n";
149+
for (auto const& item : kv) {
150+
amrex::Print() << " " << item.first << ": "
151+
<< static_cast<int>(item.second) << "\n";
152+
}
153+
AMREX_ALWAYS_ASSERT(static_cast<int>(Location::entry) == 1);
154+
AMREX_ALWAYS_ASSERT(static_cast<int>(Location::exit) == -1);
155+
AMREX_ALWAYS_ASSERT(static_cast<int>(Location::after_exit) == 0);
156+
AMREX_ALWAYS_ASSERT(amrex::toUnderlying(Location::entry) == 1);
157+
AMREX_ALWAYS_ASSERT(amrex::toUnderlying(Location::exit) == -1);
158+
AMREX_ALWAYS_ASSERT(amrex::toUnderlying(Location::after_exit) == 0);
159+
AMREX_ALWAYS_ASSERT(amrex::getEnum<Location>("entry") == Location::entry);
160+
AMREX_ALWAYS_ASSERT(amrex::getEnum<Location>("exit") == Location::exit);
161+
AMREX_ALWAYS_ASSERT(amrex::getEnum<Location>("after_exit") == Location::after_exit);
162+
AMREX_ALWAYS_ASSERT(amrex::getEnumNameString(Location::entry) == "entry");
163+
AMREX_ALWAYS_ASSERT(amrex::getEnumNameString(Location::exit) == "exit");
164+
AMREX_ALWAYS_ASSERT(amrex::getEnumNameString(Location::after_exit) == "after_exit");
165+
}
166+
143167
amrex::Finalize();
144168
}

0 commit comments

Comments
 (0)