15#ifndef LLVM_SUPPORT_ERROROR_H
16#define LLVM_SUPPORT_ERROROR_H
20#include <system_error>
57 template <
class OtherT>
friend class ErrorOr;
59 static constexpr bool isRef = std::is_reference_v<T>;
61 using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
67 using reference = std::remove_reference_t<T> &;
68 using const_reference =
const std::remove_reference_t<T> &;
69 using pointer = std::remove_reference_t<T> *;
70 using const_pointer =
const std::remove_reference_t<T> *;
75 std::enable_if_t<std::is_error_code_enum<E>::value ||
76 std::is_error_condition_enum<E>::value,
83 new (getErrorStorage()) std::error_code(EC);
86 template <
class OtherT>
88 std::enable_if_t<std::is_convertible_v<OtherT, T>> * =
nullptr)
90 new (getStorage())
storage_type(std::forward<OtherT>(Val));
97 template <
class OtherT>
99 std::enable_if_t<std::is_convertible_v<OtherT, T>> * =
nullptr) {
100 copyConstruct(
Other);
103 template <
class OtherT>
106 std::enable_if_t<!std::is_convertible_v<OtherT, const T &>> * =
nullptr) {
107 copyConstruct(
Other);
111 moveConstruct(std::move(
Other));
114 template <
class OtherT>
116 std::enable_if_t<std::is_convertible_v<OtherT, T>> * =
nullptr) {
117 moveConstruct(std::move(
Other));
122 template <
class OtherT>
125 std::enable_if_t<!std::is_convertible_v<OtherT, T>> * =
nullptr) {
126 moveConstruct(std::move(
Other));
135 moveAssign(std::move(
Other));
141 getStorage()->~storage_type();
145 explicit operator bool()
const {
149 reference
get() {
return *getStorage(); }
153 return HasError ? *getErrorStorage() : std::error_code();
157 return toPointer(getStorage());
160 const_pointer
operator->()
const {
return toPointer(getStorage()); }
163 return *getStorage();
166 const_reference
operator*()
const {
return *getStorage(); }
169 template <
class OtherT>
171 if (!
Other.HasError) {
178 new (getErrorStorage()) std::error_code(
Other.getError());
183 static bool compareThisIfSameType(
const T1 &a,
const T1 &b) {
187 template <
class T1,
class T2>
188 static bool compareThisIfSameType(
const T1 &a,
const T2 &b) {
192 template <
class OtherT>
193 void copyAssign(
const ErrorOr<OtherT> &
Other) {
194 if (compareThisIfSameType(*
this,
Other))
201 template <
class OtherT>
202 void moveConstruct(ErrorOr<OtherT> &&
Other) {
203 if (!
Other.HasError) {
210 new (getErrorStorage()) std::error_code(
Other.getError());
214 template <
class OtherT>
215 void moveAssign(ErrorOr<OtherT> &&
Other) {
216 if (compareThisIfSameType(*
this,
Other))
223 pointer toPointer(pointer Val) {
227 const_pointer toPointer(const_pointer Val)
const {
return Val; }
229 pointer toPointer(
wrap *Val) {
233 const_pointer toPointer(
const wrap *Val)
const {
return &Val->get(); }
236 assert(!HasError &&
"Cannot get value when an error exists!");
241 assert(!HasError &&
"Cannot get value when an error exists!");
245 std::error_code *getErrorStorage() {
246 assert(HasError &&
"Cannot get error when a value exists!");
247 return reinterpret_cast<std::error_code *
>(&
ErrorStorage);
250 const std::error_code *getErrorStorage()
const {
251 return const_cast<ErrorOr<T> *
>(
this)->getErrorStorage();
261template <
class T,
class E>
262std::enable_if_t<std::is_error_code_enum<E>::value ||
263 std::is_error_condition_enum<E>::value,
266 return Err.getError() == Code;
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static LLVMTargetMachineRef wrap(const TargetMachine *P)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represents either an error or a value T.
std::conditional_t< isRef, wrap, T > storage_type
const_reference get() const
ErrorOr(std::error_code EC)
ErrorOr(OtherT &&Val, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)
AlignedCharArrayUnion< std::error_code > ErrorStorage
ErrorOr(const ErrorOr &Other)
ErrorOr(E ErrorCode, std::enable_if_t< std::is_error_code_enum< E >::value||std::is_error_condition_enum< E >::value, void * >=nullptr)
const_reference operator*() const
ErrorOr(ErrorOr< OtherT > &&Other, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)
ErrorOr & operator=(const ErrorOr &Other)
std::error_code getError() const
ErrorOr(const ErrorOr< OtherT > &Other, std::enable_if_t< std::is_convertible_v< OtherT, T > > *=nullptr)
ErrorOr(const ErrorOr< OtherT > &Other, std::enable_if_t<!std::is_convertible_v< OtherT, const T & > > *=nullptr)
ErrorOr(ErrorOr< OtherT > &&Other, std::enable_if_t<!std::is_convertible_v< OtherT, T > > *=nullptr)
const_pointer operator->() const
ErrorOr & operator=(ErrorOr &&Other)
AlignedCharArrayUnion< storage_type > TStorage
This is an optimization pass for GlobalISel generic memory operations.
std::error_code make_error_code(BitcodeError E)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
A suitably aligned and sized character array member which can hold elements of any type.