]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Support/MSVCErrorWorkarounds.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Support / MSVCErrorWorkarounds.h
1 //===--- MSVCErrorWorkarounds.h - Enable future<Error> in MSVC --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // MSVC's promise/future implementation requires types to be default
11 // constructible, so this header provides analogues of Error an Expected
12 // that are default constructed in a safely destructible state.
13 //
14 // FIXME: Kill off this header and migrate all users to Error/Expected once we
15 //        move to MSVC versions that support non-default-constructible types.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
20 #define LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
21
22 #include "llvm/Support/Error.h"
23
24 namespace llvm {
25
26 // A default-constructible llvm::Error that is suitable for use with MSVC's
27 // std::future implementation which requires default constructible types.
28 class MSVCPError : public Error {
29 public:
30   MSVCPError() { (void)!!*this; }
31
32   MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
33
34   MSVCPError &operator=(MSVCPError Other) {
35     Error::operator=(std::move(Other));
36     return *this;
37   }
38
39   MSVCPError(Error Err) : Error(std::move(Err)) {}
40 };
41
42 // A default-constructible llvm::Expected that is suitable for use with MSVC's
43 // std::future implementation, which requires default constructible types.
44 template <typename T> class MSVCPExpected : public Expected<T> {
45 public:
46   MSVCPExpected()
47       : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
48     consumeError(this->takeError());
49   }
50
51   MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
52
53   MSVCPExpected &operator=(MSVCPExpected &&Other) {
54     Expected<T>::operator=(std::move(Other));
55     return *this;
56   }
57
58   MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
59
60   template <typename OtherT>
61   MSVCPExpected(
62       OtherT &&Val,
63       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
64           nullptr)
65       : Expected<T>(std::move(Val)) {}
66
67   template <class OtherT>
68   MSVCPExpected(
69       Expected<OtherT> &&Other,
70       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
71           nullptr)
72       : Expected<T>(std::move(Other)) {}
73
74   template <class OtherT>
75   explicit MSVCPExpected(
76       Expected<OtherT> &&Other,
77       typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
78           nullptr)
79       : Expected<T>(std::move(Other)) {}
80 };
81
82 } // end namespace llvm
83
84 #endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H