15#ifndef LLVM_ADT_TYPESWITCH_H
16#define LLVM_ADT_TYPESWITCH_H
37 template <
typename CaseT,
typename CaseT2,
typename... CaseTs,
45 DerivedT &derived =
static_cast<DerivedT &
>(*this);
46 return derived.template Case<CaseT>(caseFn)
47 .template
Case<CaseT2, CaseTs...>(caseFn);
54 template <
typename CallableT> DerivedT &
Case(CallableT &&caseFn) {
56 using CaseT = std::remove_cv_t<std::remove_pointer_t<
57 std::remove_reference_t<typename Traits::template arg_t<0>>>>;
59 DerivedT &derived =
static_cast<DerivedT &
>(*this);
60 return derived.template Case<CaseT>(std::forward<CallableT>(caseFn));
65 template <
typename CastT,
typename ValueT>
67 return dyn_cast<CastT>(
value);
86template <
typename T,
typename ResultT =
void>
95 template <
typename CaseT,
typename CallableT>
101 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value))
102 result.emplace(caseFn(caseValue));
107 template <
typename CallableT>
108 [[nodiscard]] ResultT
Default(CallableT &&defaultFn) {
110 return std::move(*result);
111 return defaultFn(this->
value);
114 [[nodiscard]] ResultT
Default(ResultT defaultResult) {
116 return std::move(*result);
117 return defaultResult;
120 [[nodiscard]]
operator ResultT() {
121 assert(result &&
"Fell off the end of a type-switch");
122 return std::move(*result);
128 std::optional<ResultT> result;
142 template <
typename CaseT,
typename CallableT>
148 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value)) {
156 template <
typename CallableT>
void Default(CallableT &&defaultFn) {
158 defaultFn(this->
value);
163 bool foundMatch =
false;
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
#define LLVM_ATTRIBUTE_NODEBUG
LLVM_ATTRIBUTE_NO_DEBUG - On compilers where we have a directive to do so, mark a method "no debug" b...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
TypeSwitch(TypeSwitch &&other)=default
TypeSwitch< T, void > & Case(CallableT &&caseFn)
Add a case on the given type.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
ResultT Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
ResultT Default(ResultT defaultResult)
As a default, return the given value.
TypeSwitch(TypeSwitch &&other)=default
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
DerivedT & Case(CallableT &&caseFn)
Invoke a case on the derived class, inferring the type of the Case from the first input of the given ...
void operator=(TypeSwitchBase &&other)=delete
void operator=(const TypeSwitchBase &)=delete
~TypeSwitchBase()=default
TypeSwitchBase(TypeSwitchBase &&other)
static decltype(auto) castValue(ValueT &&value)
Attempt to dyn_cast the given value to CastT.
TypeSwitchBase(const TypeSwitchBase &)=delete
TypeSwitchBase is not copyable.
TypeSwitchBase(const T &value)
const T value
The root value we are switching on.
LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG DerivedT & Case(CallableT &&caseFn)
Invoke a case on the derived class with multiple case types.
This is an optimization pass for GlobalISel generic memory operations.
This class provides various trait information about a callable object.