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 std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) 63 : Expected<T>(std::move(Val)) {} 64 65 template <class OtherT> 66 MSVCPExpected( 67 Expected<OtherT> &&Other, 68 std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) 69 : Expected<T>(std::move(Other)) {} 70 71 template <class OtherT> 72 explicit MSVCPExpected( 73 Expected<OtherT> &&Other, 74 std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) 75 : Expected<T>(std::move(Other)) {} 76 }; 77 78 } // end namespace llvm 79 80 #endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H 81