Skip to content

Commit d0caa4e

Browse files
authored
[ADT] Backport std::to_underlying from C++23 (llvm#70681)
This patch backports a one-liner `std::to_underlying` that came with C++23. This is useful for refactoring unscoped enums into scoped enums, because the latter are not implicitly convertible to integer types. I followed libc++ implementation, but I consider their testing too heavy for us, so I wrote a simpler set of tests.
1 parent 134c915 commit d0caa4e

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

llvm/include/llvm/ADT/STLForwardCompat.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ auto transformOptional(std::optional<T> &&O, const Function &F)
6060
return std::nullopt;
6161
}
6262

63+
/// Returns underlying integer value of an enum. Backport of C++23
64+
/// std::to_underlying.
65+
template <typename Enum>
66+
[[nodiscard]] constexpr std::underlying_type_t<Enum> to_underlying(Enum E) {
67+
return static_cast<std::underlying_type_t<Enum>>(E);
68+
}
69+
6370
} // namespace llvm
6471

6572
#endif // LLVM_ADT_STLFORWARDCOMPAT_H

llvm/unittests/ADT/STLForwardCompatTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,21 @@ TEST(TransformTest, MoveTransformLlvm) {
119119
EXPECT_EQ(0u, MoveOnly::Destructions);
120120
}
121121

122+
TEST(TransformTest, ToUnderlying) {
123+
enum E { A1 = 0, B1 = -1 };
124+
static_assert(llvm::to_underlying(A1) == 0);
125+
static_assert(llvm::to_underlying(B1) == -1);
126+
127+
enum E2 : unsigned char { A2 = 0, B2 };
128+
static_assert(
129+
std::is_same_v<unsigned char, decltype(llvm::to_underlying(A2))>);
130+
static_assert(llvm::to_underlying(A2) == 0);
131+
static_assert(llvm::to_underlying(B2) == 1);
132+
133+
enum class E3 { A3 = -1, B3 };
134+
static_assert(std::is_same_v<int, decltype(llvm::to_underlying(E3::A3))>);
135+
static_assert(llvm::to_underlying(E3::A3) == -1);
136+
static_assert(llvm::to_underlying(E3::B3) == 0);
137+
}
138+
122139
} // namespace

0 commit comments

Comments
 (0)