14 #ifndef MLIR_SUPPORT_TYPESWITCH_H 15 #define MLIR_SUPPORT_TYPESWITCH_H 19 #include "llvm/ADT/Optional.h" 36 template <
typename CaseT,
typename CaseT2,
typename... CaseTs,
38 DerivedT &
Case(CallableT &&caseFn) {
39 DerivedT &derived =
static_cast<DerivedT &
>(*this);
40 return derived.template Case<CaseT>(caseFn)
41 .
template Case<CaseT2, CaseTs...>(caseFn);
48 template <
typename CallableT> DerivedT &
Case(CallableT &&caseFn) {
50 using CaseT = std::remove_cv_t<std::remove_pointer_t<
51 std::remove_reference_t<typename Traits::template arg_t<0>>>>;
53 DerivedT &derived =
static_cast<DerivedT &
>(*this);
54 return derived.template Case<CaseT>(std::forward<CallableT>(caseFn));
60 template <
typename ValueT,
typename CastT>
62 decltype(std::declval<ValueT &>().
template dyn_cast<CastT>());
66 template <
typename CastT,
typename ValueT>
69 typename std::enable_if_t<
71 return value.template dyn_cast<CastT>();
76 template <
typename CastT,
typename ValueT>
79 typename std::enable_if_t<
81 return dyn_cast<CastT>(
value);
100 template <
typename T,
typename ResultT =
void>
109 template <
typename CaseT,
typename CallableT>
115 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value))
116 result = caseFn(caseValue);
121 template <
typename CallableT>
122 LLVM_NODISCARD ResultT
Default(CallableT &&defaultFn) {
124 return std::move(*result);
125 return defaultFn(this->
value);
130 assert(result &&
"Fell off the end of a type-switch");
131 return std::move(*result);
141 template <
typename T>
151 template <
typename CaseT,
typename CallableT>
157 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value)) {
165 template <
typename CallableT>
void Default(CallableT &&defaultFn) {
167 defaultFn(this->
value);
172 bool foundMatch =
false;
176 #endif // MLIR_SUPPORT_TYPESWITCH_H Definition: InferTypeOpInterface.cpp:20
Definition: TypeSwitch.h:24
TypeSwitchBase(const T &value)
Definition: TypeSwitch.h:26
static auto castValue(ValueT value, typename std::enable_if_t< !is_detected< has_dyn_cast_t, ValueT, CastT >::value > *=nullptr)
Definition: TypeSwitch.h:77
LLVM_NODISCARD ResultT Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
Definition: TypeSwitch.h:122
Definition: STLExtras.h:350
TypeSwitchBase(TypeSwitchBase &&other)
Definition: TypeSwitch.h:27
decltype(std::declval< ValueT &>().template dyn_cast< CastT >()) has_dyn_cast_t
Definition: TypeSwitch.h:62
static auto castValue(ValueT value, typename std::enable_if_t< is_detected< has_dyn_cast_t, ValueT, CastT >::value > *=nullptr)
Definition: TypeSwitch.h:67
TypeSwitch< T, void > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition: TypeSwitch.h:152
const T value
The root value we are switching on.
Definition: TypeSwitch.h:85
typename detail::detector< void, Op, Args... >::value_t is_detected
Definition: STLExtras.h:125
~TypeSwitchBase()=default
void operator=(const TypeSwitchBase &)=delete
Definition: TypeSwitch.h:101
DerivedT & Case(CallableT &&caseFn)
Invoke a case on the derived class with multiple case types.
Definition: TypeSwitch.h:38
void Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
Definition: TypeSwitch.h:165
Specialization of TypeSwitch for void returning callables.
Definition: TypeSwitch.h:142
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition: TypeSwitch.h:110
DerivedT & Case(CallableT &&caseFn)
Definition: TypeSwitch.h:48