16 #ifndef LLVM_SUPPORT_ERROROR_H
17 #define LLVM_SUPPORT_ERROROR_H
22 #include <system_error>
23 #include <type_traits>
26 template<
class T,
class V>
27 typename std::enable_if< std::is_constructible<T, V>::value
28 ,
typename std::remove_reference<V>::type>::type &&
30 return std::move(Val);
33 template<
class T,
class V>
34 typename std::enable_if< !std::is_constructible<T, V>::value
35 ,
typename std::remove_reference<V>::type>::type &
48 operator T &()
const {
return *Storage; }
49 T &
get()
const {
return *Storage; }
83 template <
class OtherT>
friend class ErrorOr;
84 static const bool isRef = std::is_reference<T>::value;
88 typedef typename std::conditional<isRef, wrap, T>::type
storage_type;
91 typedef typename std::remove_reference<T>::type &reference;
92 typedef const typename std::remove_reference<T>::type &const_reference;
93 typedef typename std::remove_reference<T>::type *pointer;
98 typename std::enable_if<std::is_error_code_enum<E>::value ||
99 std::is_error_condition_enum<E>::value,
106 new (getErrorStorage()) std::error_code(EC);
110 new (getStorage())
storage_type(moveIfMoveConstructible<storage_type>(Val));
114 copyConstruct(Other);
117 template <
class OtherT>
120 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
122 copyConstruct(Other);
125 template <
class OtherT>
128 typename std::enable_if<
129 !std::is_convertible<OtherT, const T &>::value>::type * =
nullptr) {
130 copyConstruct(Other);
134 moveConstruct(std::move(
Other));
137 template <
class OtherT>
140 typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
142 moveConstruct(std::move(
Other));
147 template <
class OtherT>
150 typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
152 moveConstruct(std::move(
Other));
161 moveAssign(std::move(
Other));
167 getStorage()->~storage_type();
171 explicit operator bool()
const {
175 reference
get() {
return *getStorage(); }
176 const_reference
get()
const {
return const_cast<ErrorOr<T> *
>(
this)->
get(); }
179 return HasError ? *getErrorStorage() : std::error_code();
183 return toPointer(getStorage());
187 return *getStorage();
191 template <
class OtherT>
193 if (!Other.HasError) {
200 new (getErrorStorage()) std::error_code(Other.
getError());
205 static bool compareThisIfSameType(
const T1 &a,
const T1 &b) {
209 template <
class T1,
class T2>
210 static bool compareThisIfSameType(
const T1 &a,
const T2 &b) {
214 template <
class OtherT>
215 void copyAssign(
const ErrorOr<OtherT> &Other) {
216 if (compareThisIfSameType(*
this, Other))
223 template <
class OtherT>
224 void moveConstruct(ErrorOr<OtherT> &&Other) {
225 if (!Other.HasError) {
228 new (getStorage())
storage_type(std::move(*Other.getStorage()));
232 new (getErrorStorage()) std::error_code(Other.getError());
236 template <
class OtherT>
237 void moveAssign(ErrorOr<OtherT> &&Other) {
238 if (compareThisIfSameType(*
this, Other))
242 new (
this)
ErrorOr(std::move(Other));
245 pointer toPointer(pointer Val) {
249 pointer toPointer(
wrap *Val) {
254 assert(!HasError &&
"Cannot get value when an error exists!");
259 assert(!HasError &&
"Cannot get value when an error exists!");
263 std::error_code *getErrorStorage() {
264 assert(HasError &&
"Cannot get error when a value exists!");
265 return reinterpret_cast<std::error_code *
>(
ErrorStorage.buffer);
268 const std::error_code *getErrorStorage()
const {
269 return const_cast<ErrorOr<T> *
>(
this)->getErrorStorage();
280 template <
class T,
class E>
281 typename std::enable_if<std::is_error_code_enum<E>::value ||
282 std::is_error_condition_enum<E>::value,
285 return Err.getError() == Code;
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(E ErrorCode, typename std::enable_if< std::is_error_code_enum< E >::value||std::is_error_condition_enum< E >::value, void * >::type=0)
ErrorOr & operator=(const ErrorOr &Other)
std::error_code make_error_code(BitcodeError E)
LLVMTargetDataRef wrap(const DataLayout *P)
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)
std::enable_if< std::is_constructible< T, V >::value, typename std::remove_reference< V >::type >::type && moveIfMoveConstructible(V &Val)
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
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.
ErrorOr & operator=(ErrorOr &&Other)
bool operator==(uint64_t V1, const APInt &V2)