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: MSVCPError()29 MSVCPError() { (void)!!*this; } 30 MSVCPError(MSVCPError && Other)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 MSVCPError(Error Err)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: MSVCPExpected()45 MSVCPExpected() 46 : Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) { 47 consumeError(this->takeError()); 48 } 49 MSVCPExpected(MSVCPExpected && Other)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 MSVCPExpected(Error Err)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 84