]> 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 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // MSVC's promise/future implementation requires types to be default
10 // constructible, so this header provides analogues of Error an Expected
11 // that are default constructed in a safely destructible state.
12 //
13 // FIXME: Kill off this header and migrate all users to Error/Expected once we
14 //        move to MSVC versions that support non-default-constructible types.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
19 #define LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
20
21 #include "llvm/Support/Error.h"
22
23 namespace llvm {
24
25 // A default-constructible llvm::Error that is suitable for use with MSVC's
26 // std::future implementation which requires default constructible types.
27 class MSVCPError : public Error {
28 public:
29   MSVCPError() { (void)!!*this; }
30
31   MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {}
32
33   MSVCPError &operator=(MSVCPError Other) {
34     Error::operator=(std::move(Other));
35     return *this;
36   }
37
38   MSVCPError(Error Err) : Error(std::move(Err)) {}
39 };
40
41 // A default-constructible llvm::Expected that is suitable for use with MSVC's
42 // std::future implementation, which requires default constructible types.
43 template <typename T> class MSVCPExpected : public Expected<T> {
44 public:
45   MSVCPExpected()
46       : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) {
47     consumeError(this->takeError());
48   }
49
50   MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {}
51
52   MSVCPExpected &operator=(MSVCPExpected &&Other) {
53     Expected<T>::operator=(std::move(Other));
54     return *this;
55   }
56
57   MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {}
58
59   template <typename OtherT>
60   MSVCPExpected(
61       OtherT &&Val,
62       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
63           nullptr)
64       : Expected<T>(std::move(Val)) {}
65
66   template <class OtherT>
67   MSVCPExpected(
68       Expected<OtherT> &&Other,
69       typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
70           nullptr)
71       : Expected<T>(std::move(Other)) {}
72
73   template <class OtherT>
74   explicit MSVCPExpected(
75       Expected<OtherT> &&Other,
76       typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
77           nullptr)
78       : Expected<T>(std::move(Other)) {}
79 };
80
81 } // end namespace llvm
82
83 #endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H