15#ifndef LLVM_ADT_TYPESWITCH_H
16#define LLVM_ADT_TYPESWITCH_H
39 template <
typename CaseT,
typename CaseT2,
typename... CaseTs,
47 DerivedT &derived =
static_cast<DerivedT &
>(*this);
49 .template
Case<CaseT2, CaseTs...>(caseFn);
56 template <
typename CallableT> DerivedT &
Case(CallableT &&caseFn) {
58 using CaseT = std::remove_cv_t<std::remove_pointer_t<
59 std::remove_reference_t<typename Traits::template arg_t<0>>>>;
61 DerivedT &derived =
static_cast<DerivedT &
>(*this);
62 return derived.template
Case<CaseT>(std::forward<CallableT>(caseFn));
67 template <
typename CastT,
typename ValueT>
88template <
typename T,
typename ResultT =
void>
97 template <
typename CaseT,
typename CallableT>
104 result.emplace(caseFn(caseValue));
109 template <
typename CallableT>
110 [[nodiscard]] ResultT
Default(CallableT &&defaultFn) {
112 return std::move(*result);
113 return defaultFn(this->
value);
117 [[nodiscard]] ResultT
Default(ResultT defaultResult) {
119 return std::move(*result);
120 return defaultResult;
124 template <
typename ArgT = ResultT,
126 std::enable_if_t<std::is_constructible_v<ArgT, std::nullptr_t>>>
127 [[nodiscard]] ResultT
Default(std::nullptr_t) {
128 return Default(ResultT(
nullptr));
132 template <
typename ArgT = ResultT,
134 std::enable_if_t<std::is_constructible_v<ArgT, std::nullopt_t>>>
135 [[nodiscard]] ResultT
Default(std::nullopt_t) {
136 return Default(ResultT(std::nullopt));
141 template <
typename ArgT = ResultT,
143 std::enable_if_t<std::is_constructible_v<ArgT, LogicalResult> &&
144 !std::is_same_v<ArgT, LogicalResult>>>
146 return Default(ResultT(result));
151 const char *message =
"Fell off the end of a type-switch") {
153 return std::move(*result);
162 std::optional<ResultT> result;
176 template <
typename CaseT,
typename CallableT>
190 template <
typename CallableT>
void Default(CallableT &&defaultFn) {
192 defaultFn(this->
value);
197 const char *message =
"Fell off the end of a type-switch") {
204 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...
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.
detail::TypeSwitchBase< TypeSwitch< T, void >, T > BaseT
void DefaultUnreachable(const char *message="Fell off the end of a type-switch")
Declare default as unreachable, making sure that all cases were handled.
detail::TypeSwitchBase< TypeSwitch< T, ResultT >, T > BaseT
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.
ResultT Default(std::nullptr_t)
Default for pointer-like results types that accept nullptr.
ResultT DefaultUnreachable(const char *message="Fell off the end of a type-switch")
Declare default as unreachable, making sure that all cases were handled.
ResultT Default(LogicalResult result)
Default for result types constructible from LogicalResult (e.g., FailureOr<T>).
ResultT Default(std::nullopt_t)
Default for optional results types that accept std::nullopt.
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)
LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG DerivedT & Case(CallableT &&caseFn)
Invoke a case on the derived class with multiple case types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Default
The result values are uniform if and only if all operands are uniform.
This class represents an efficient way to signal success or failure.
This class provides various trait information about a callable object.