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));
66 template <
typename ValueT,
typename CastT>
68 decltype(std::declval<ValueT &>().template dyn_cast<CastT>());
72 template <
typename CastT,
typename ValueT>
77 return value.template dyn_cast<CastT>();
82 template <
typename CastT,
typename ValueT>
87 return dyn_cast<CastT>(
value);
106template <
typename T,
typename ResultT =
void>
115 template <
typename CaseT,
typename CallableT>
121 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value))
122 result.emplace(caseFn(caseValue));
127 template <
typename CallableT>
128 [[nodiscard]] ResultT
Default(CallableT &&defaultFn) {
130 return std::move(*result);
131 return defaultFn(this->
value);
134 [[nodiscard]] ResultT
Default(ResultT defaultResult) {
136 return std::move(*result);
137 return defaultResult;
140 [[nodiscard]]
operator ResultT() {
141 assert(result &&
"Fell off the end of a type-switch");
142 return std::move(*result);
148 std::optional<ResultT> result;
162 template <
typename CaseT,
typename CallableT>
168 if (
auto caseValue = BaseT::template castValue<CaseT>(this->
value)) {
176 template <
typename CallableT>
void Default(CallableT &&defaultFn) {
178 defaultFn(this->
value);
183 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, std::enable_if_t< is_detected< has_dyn_cast_t, ValueT, CastT >::value > *=nullptr)
Attempt to dyn_cast the given value to CastT.
TypeSwitchBase(const TypeSwitchBase &)=delete
TypeSwitchBase is not copyable.
TypeSwitchBase(const T &value)
decltype(std::declval< ValueT & >().template dyn_cast< CastT >()) has_dyn_cast_t
Trait to check whether ValueT provides a 'dyn_cast' method with type CastT.
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.
static decltype(auto) castValue(ValueT &&value, std::enable_if_t<!is_detected< has_dyn_cast_t, ValueT, CastT >::value > *=nullptr)
Attempt to dyn_cast the given value to CastT.
This is an optimization pass for GlobalISel generic memory operations.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
This class provides various trait information about a callable object.