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.
This class represents an efficient way to signal success or failure.
This class provides various trait information about a callable object.