Skip to content

Commit cc6f8cc

Browse files
committed
[ADT] Allow std::nullopt Default in TypeSwitch
1 parent 9d5c354 commit cc6f8cc

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

llvm/include/llvm/ADT/TypeSwitch.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,22 @@ class TypeSwitch : public detail::TypeSwitchBase<TypeSwitch<T, ResultT>, T> {
111111
return std::move(*result);
112112
return defaultFn(this->value);
113113
}
114+
114115
/// As a default, return the given value.
115116
[[nodiscard]] ResultT Default(ResultT defaultResult) {
116117
if (result)
117118
return std::move(*result);
118119
return defaultResult;
119120
}
120121

122+
/// Default for optional results types that accept `std::nullopt`.
123+
template <typename ArgT = ResultT,
124+
typename =
125+
std::enable_if_t<std::is_constructible_v<ArgT, std::nullopt_t>>>
126+
[[nodiscard]] ResultT Default(std::nullopt_t) {
127+
return Default(ResultT(std::nullopt));
128+
}
129+
121130
/// Declare default as unreachable, making sure that all cases were handled.
122131
[[nodiscard]] ResultT DefaultUnreachable(
123132
const char *message = "Fell off the end of a type-switch") {

llvm/unittests/ADT/TypeSwitchTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,13 @@ TEST(TypeSwitchTest, DefaultUnreachableWithVoid) {
142142
EXPECT_DEATH((void)translate(DerivedD()), "Unhandled type");
143143
#endif
144144
}
145+
146+
TEST(TypeSwitchTest, DefaultNullopt) {
147+
auto translate = [](auto value) {
148+
return TypeSwitch<Base *, std::optional<int>>(&value)
149+
.Case([](DerivedA *) { return 0; })
150+
.Default(std::nullopt);
151+
};
152+
EXPECT_EQ(0, translate(DerivedA()));
153+
EXPECT_EQ(std::nullopt, translate(DerivedD()));
154+
}

0 commit comments

Comments
 (0)