mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-16 18:16:00 +00:00
Castable: Have Switch() support nullptr objects.
Change-Id: I7635b01707e80c2d2e0b79148e07874f2fa2b5ff Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/79764 Auto-Submit: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
6839cba568
commit
88d1a433aa
@ -565,7 +565,6 @@ inline bool NonDefaultCases(T* object,
|
|||||||
/// @see NonDefaultCases
|
/// @see NonDefaultCases
|
||||||
template <typename T, typename RETURN_TYPE, typename... CASES>
|
template <typename T, typename RETURN_TYPE, typename... CASES>
|
||||||
inline void SwitchCases(T* object,
|
inline void SwitchCases(T* object,
|
||||||
const TypeInfo* type,
|
|
||||||
RETURN_TYPE* result,
|
RETURN_TYPE* result,
|
||||||
std::tuple<CASES...>&& cases) {
|
std::tuple<CASES...>&& cases) {
|
||||||
using Cases = std::tuple<CASES...>;
|
using Cases = std::tuple<CASES...>;
|
||||||
@ -575,6 +574,8 @@ inline void SwitchCases(T* object,
|
|||||||
static constexpr bool kHasDefaultCase = kDefaultIndex >= 0;
|
static constexpr bool kHasDefaultCase = kDefaultIndex >= 0;
|
||||||
static constexpr bool kHasReturnType = !std::is_same_v<RETURN_TYPE, void>;
|
static constexpr bool kHasReturnType = !std::is_same_v<RETURN_TYPE, void>;
|
||||||
|
|
||||||
|
if (object) {
|
||||||
|
auto* type = &object->TypeInfo();
|
||||||
if constexpr (kHasDefaultCase) {
|
if constexpr (kHasDefaultCase) {
|
||||||
// Evaluate non-default cases.
|
// Evaluate non-default cases.
|
||||||
if (!detail::NonDefaultCases<T>(object, type, result,
|
if (!detail::NonDefaultCases<T>(object, type, result,
|
||||||
@ -589,6 +590,17 @@ inline void SwitchCases(T* object,
|
|||||||
} else {
|
} else {
|
||||||
detail::NonDefaultCases<T>(object, type, result, std::move(cases));
|
detail::NonDefaultCases<T>(object, type, result, std::move(cases));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Object is nullptr, so no cases can match
|
||||||
|
if constexpr (kHasDefaultCase) {
|
||||||
|
// Evaluate default case.
|
||||||
|
if constexpr (kHasReturnType) {
|
||||||
|
*result = std::get<kDefaultIndex>(cases)({});
|
||||||
|
} else {
|
||||||
|
std::get<kDefaultIndex>(cases)({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -608,6 +620,10 @@ inline void SwitchCases(T* object,
|
|||||||
/// used as the last case. This default case will be called if all previous
|
/// used as the last case. This default case will be called if all previous
|
||||||
/// cases failed to match.
|
/// cases failed to match.
|
||||||
///
|
///
|
||||||
|
/// If `object` is nullptr and a default case is provided, then the default case
|
||||||
|
/// will be called. If `object` is nullptr and no default case is provided, then
|
||||||
|
/// no cases will be called.
|
||||||
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// Switch(object,
|
/// Switch(object,
|
||||||
@ -630,17 +646,14 @@ inline auto Switch(T* object, CASES&&... cases) {
|
|||||||
using ReturnType = traits::ReturnType<std::tuple_element_t<0, Cases>>;
|
using ReturnType = traits::ReturnType<std::tuple_element_t<0, Cases>>;
|
||||||
static constexpr bool kHasReturnType = !std::is_same_v<ReturnType, void>;
|
static constexpr bool kHasReturnType = !std::is_same_v<ReturnType, void>;
|
||||||
|
|
||||||
auto& type = object->TypeInfo();
|
|
||||||
|
|
||||||
if constexpr (kHasReturnType) {
|
if constexpr (kHasReturnType) {
|
||||||
ReturnType res = {};
|
ReturnType res = {};
|
||||||
detail::SwitchCases(object, &type, &res,
|
detail::SwitchCases(object, &res,
|
||||||
std::forward_as_tuple(std::forward<CASES>(cases)...));
|
std::forward_as_tuple(std::forward<CASES>(cases)...));
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
detail::SwitchCases<T, void>(
|
detail::SwitchCases<T, void>(
|
||||||
object, &type, nullptr,
|
object, nullptr, std::forward_as_tuple(std::forward<CASES>(cases)...));
|
||||||
std::forward_as_tuple(std::forward<CASES>(cases)...));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,6 +371,7 @@ TEST(Castable, SwitchDefault) {
|
|||||||
EXPECT_TRUE(gecko_matched_default);
|
EXPECT_TRUE(gecko_matched_default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Castable, SwitchMatchFirst) {
|
TEST(Castable, SwitchMatchFirst) {
|
||||||
std::unique_ptr<Animal> frog = std::make_unique<Frog>();
|
std::unique_ptr<Animal> frog = std::make_unique<Frog>();
|
||||||
{
|
{
|
||||||
@ -397,6 +398,25 @@ TEST(Castable, SwitchMatchFirst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Castable, SwitchNull) {
|
||||||
|
Animal* null = nullptr;
|
||||||
|
Switch(
|
||||||
|
null, //
|
||||||
|
[&](Amphibian*) { FAIL() << "should not be called"; },
|
||||||
|
[&](Animal*) { FAIL() << "should not be called"; });
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Castable, SwitchNullNoDefault) {
|
||||||
|
Animal* null = nullptr;
|
||||||
|
bool default_called = false;
|
||||||
|
Switch(
|
||||||
|
null, //
|
||||||
|
[&](Amphibian*) { FAIL() << "should not be called"; },
|
||||||
|
[&](Animal*) { FAIL() << "should not be called"; },
|
||||||
|
[&](Default) { default_called = true; });
|
||||||
|
EXPECT_TRUE(default_called);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TINT_INSTANTIATE_TYPEINFO(Animal);
|
TINT_INSTANTIATE_TYPEINFO(Animal);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user