1 //===--- MSVCErrorWorkarounds.h - Enable future<Error> in MSVC --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
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.
16 //===----------------------------------------------------------------------===//
18 #ifndef LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
19 #define LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H
21 #include "llvm/Support/Error.h"
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
{
29 MSVCPError() { (void)!!*this; }
31 MSVCPError(MSVCPError
&&Other
) : Error(std::move(Other
)) {}
33 MSVCPError
&operator=(MSVCPError Other
) {
34 Error::operator=(std::move(Other
));
38 MSVCPError(Error Err
) : Error(std::move(Err
)) {}
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
> {
46 : Expected
<T
>(make_error
<StringError
>("", inconvertibleErrorCode())) {
47 consumeError(this->takeError());
50 MSVCPExpected(MSVCPExpected
&&Other
) : Expected
<T
>(std::move(Other
)) {}
52 MSVCPExpected
&operator=(MSVCPExpected
&&Other
) {
53 Expected
<T
>::operator=(std::move(Other
));
57 MSVCPExpected(Error Err
) : Expected
<T
>(std::move(Err
)) {}
59 template <typename OtherT
>
62 typename
std::enable_if
<std::is_convertible
<OtherT
, T
>::value
>::type
* =
64 : Expected
<T
>(std::move(Val
)) {}
66 template <class OtherT
>
68 Expected
<OtherT
> &&Other
,
69 typename
std::enable_if
<std::is_convertible
<OtherT
, T
>::value
>::type
* =
71 : Expected
<T
>(std::move(Other
)) {}
73 template <class OtherT
>
74 explicit MSVCPExpected(
75 Expected
<OtherT
> &&Other
,
76 typename
std::enable_if
<!std::is_convertible
<OtherT
, T
>::value
>::type
* =
78 : Expected
<T
>(std::move(Other
)) {}
81 } // end namespace llvm
83 #endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H