15 #ifndef LLVM_SUPPORT_ERROROR_H
16 #define LLVM_SUPPORT_ERROROR_H
20 #include <system_error>
21 #include <type_traits>
57 template <
class OtherT>
friend class ErrorOr;
59 static constexpr
bool isRef = std::is_reference<T>::value;
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<OtherT, T>::value> * =
nullptr)
90 new (getStorage())
storage_type(std::forward<OtherT>(Val));
97 template <
class OtherT>
99 std::enable_if_t<std::is_convertible<OtherT, T>::value> * =
nullptr) {
100 copyConstruct(
Other);
103 template <
class OtherT>
106 std::enable_if_t<!std::is_convertible<OtherT, const T &>::value> * =
108 copyConstruct(
Other);
115 template <
class OtherT>
117 std::enable_if_t<std::is_convertible<OtherT, T>::value> * =
nullptr) {
123 template <
class OtherT>
126 std::enable_if_t<!std::is_convertible<OtherT, T>::value> * =
nullptr) {
142 getStorage()->~storage_type();
146 explicit operator bool()
const {
150 reference
get() {
return *getStorage(); }
154 return HasError ? *getErrorStorage() : std::error_code();
158 return toPointer(getStorage());
161 const_pointer
operator->()
const {
return toPointer(getStorage()); }
164 return *getStorage();
167 const_reference
operator*()
const {
return *getStorage(); }
170 template <
class OtherT>
172 if (!
Other.HasError) {
179 new (getErrorStorage()) std::error_code(
Other.getError());
184 static bool compareThisIfSameType(
const T1 &
a,
const T1 &
b) {
188 template <
class T1,
class T2>
189 static bool compareThisIfSameType(
const T1 &
a,
const T2 &
b) {
193 template <
class OtherT>
194 void copyAssign(
const ErrorOr<OtherT> &
Other) {
195 if (compareThisIfSameType(*
this,
Other))
202 template <
class OtherT>
203 void moveConstruct(ErrorOr<OtherT> &&
Other) {
204 if (!
Other.HasError) {
211 new (getErrorStorage()) std::error_code(
Other.getError());
215 template <
class OtherT>
216 void moveAssign(ErrorOr<OtherT> &&
Other) {
217 if (compareThisIfSameType(*
this,
Other))
228 const_pointer toPointer(const_pointer Val)
const {
return Val; }
234 const_pointer toPointer(
const wrap *Val)
const {
return &Val->get(); }
237 assert(!HasError &&
"Cannot get value when an error exists!");
242 assert(!HasError &&
"Cannot get value when an error exists!");
246 std::error_code *getErrorStorage() {
247 assert(HasError &&
"Cannot get error when a value exists!");
248 return reinterpret_cast<std::error_code *
>(&
ErrorStorage);
251 const std::error_code *getErrorStorage()
const {
252 return const_cast<ErrorOr<T> *
>(
this)->getErrorStorage();
262 template <
class T,
class E>
263 std::enable_if_t<std::is_error_code_enum<E>::value ||
264 std::is_error_condition_enum<E>::value,
267 return Err.getError() == Code;
272 #endif // LLVM_SUPPORT_ERROROR_H