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 23namespace 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. 27class MSVCPError : public Error { 28public: 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. 43template <typename T> class MSVCPExpected : public Expected<T> { 44public: 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 84