16 #ifndef LLVM_SUPPORT_ERROROR_H
17 #define LLVM_SUPPORT_ERROROR_H
22 #include <system_error>
23 #include <type_traits>
34 operator T &()
const {
return *Storage; }
35 T &
get()
const {
return *Storage; }
69 template <
class OtherT>
friend class ErrorOr;
70 static const bool isRef = std::is_reference<T>::value;
74 typedef typename std::conditional<isRef, wrap, T>::type
storage_type;
77 typedef typename std::remove_reference<T>::type &reference;
78 typedef const typename std::remove_reference<T>::type &const_reference;
79 typedef typename std::remove_reference<T>::type *pointer;
80 typedef const typename std::remove_reference<T>::type *const_pointer;
85 typename std::enable_if<std::is_error_code_enum<E>::value ||
86 std::is_error_condition_enum<E>::value,
87 void *>::type =
nullptr)
93 new (getErrorStorage()) std::error_code(EC);
96 template <
class OtherT>
98 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
101 new (getStorage())
storage_type(std::forward<OtherT>(Val));
105 copyConstruct(Other);
108 template <
class OtherT>
111 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
113 copyConstruct(Other);
116 template <
class OtherT>
119 typename std::enable_if<
120 !std::is_convertible<OtherT, const T &>::value>::type * =
nullptr) {
121 copyConstruct(Other);
125 moveConstruct(std::move(
Other));
128 template <
class OtherT>
131 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
133 moveConstruct(std::move(
Other));
138 template <
class OtherT>
141 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
143 moveConstruct(std::move(
Other));
152 moveAssign(std::move(
Other));
158 getStorage()->~storage_type();
162 explicit operator bool()
const {
166 reference
get() {
return *getStorage(); }
167 const_reference
get()
const {
return const_cast<ErrorOr<T> *
>(
this)->
get(); }
170 return HasError ? *getErrorStorage() : std::error_code();
174 return toPointer(getStorage());
177 const_pointer
operator->()
const {
return toPointer(getStorage()); }
180 return *getStorage();
183 const_reference
operator*()
const {
return *getStorage(); }
186 template <
class OtherT>
188 if (!Other.HasError) {
195 new (getErrorStorage()) std::error_code(Other.
getError());
200 static bool compareThisIfSameType(
const T1 &a,
const T1 &b) {
204 template <
class T1,
class T2>
205 static bool compareThisIfSameType(
const T1 &a,
const T2 &b) {
209 template <
class OtherT>
210 void copyAssign(
const ErrorOr<OtherT> &Other) {
211 if (compareThisIfSameType(*
this, Other))
218 template <
class OtherT>
219 void moveConstruct(ErrorOr<OtherT> &&Other) {
220 if (!Other.HasError) {
223 new (getStorage())
storage_type(std::move(*Other.getStorage()));
227 new (getErrorStorage()) std::error_code(Other.getError());
231 template <
class OtherT>
232 void moveAssign(ErrorOr<OtherT> &&Other) {
233 if (compareThisIfSameType(*
this, Other))
237 new (
this)
ErrorOr(std::move(Other));
240 pointer toPointer(pointer Val) {
244 const_pointer toPointer(const_pointer Val)
const {
return Val; }
246 pointer toPointer(
wrap *Val) {
250 const_pointer toPointer(
const wrap *Val)
const {
return &Val->get(); }
253 assert(!HasError &&
"Cannot get value when an error exists!");
258 assert(!HasError &&
"Cannot get value when an error exists!");
262 std::error_code *getErrorStorage() {
263 assert(HasError &&
"Cannot get error when a value exists!");
264 return reinterpret_cast<std::error_code *
>(
ErrorStorage.buffer);
267 const std::error_code *getErrorStorage()
const {
268 return const_cast<ErrorOr<T> *
>(
this)->getErrorStorage();
278 template <
class T,
class E>
279 typename std::enable_if<std::is_error_code_enum<E>::value ||
280 std::is_error_condition_enum<E>::value,
283 return Err.getError() == Code;
287 #endif // LLVM_SUPPORT_ERROROR_H
ErrorOr(const ErrorOr< OtherT > &Other, typename std::enable_if< std::is_convertible< OtherT, T >::value >::type *=nullptr)
std::error_code getError() const
Represents either an error or a value T.
ErrorOr & operator=(const ErrorOr &Other)
ErrorOr(OtherT &&Val, typename std::enable_if< std::is_convertible< OtherT, T >::value >::type *=nullptr)
const_pointer operator->() const
std::error_code make_error_code(BitcodeError E)
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
ErrorOr(E ErrorCode, typename std::enable_if< std::is_error_code_enum< E >::value||std::is_error_condition_enum< E >::value, void * >::type=nullptr)
AlignedCharArrayUnion< std::error_code > ErrorStorage
ErrorOr(const ErrorOr &Other)
AlignedCharArrayUnion< storage_type > TStorage
ErrorOr(ErrorOr< OtherT > &&Other, typename std::enable_if<!std::is_convertible< OtherT, T >::value >::type *=nullptr)
ErrorOr(std::error_code EC)
ErrorOr(ErrorOr< OtherT > &&Other, typename std::enable_if< std::is_convertible< OtherT, T >::value >::type *=nullptr)
std::conditional< isRef, wrap, T >::type storage_type
LLVMAttributeRef wrap(Attribute Attr)
ErrorOr(const ErrorOr< OtherT > &Other, typename std::enable_if< !std::is_convertible< OtherT, const T & >::value >::type *=nullptr)
Stores a reference that can be changed.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ErrorOr & operator=(ErrorOr &&Other)
const_reference operator*() const
bool operator==(uint64_t V1, const APInt &V2)