forked from llvm-mirror/llvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move MSVC workarounds for future<Error>/future<Expected<T>> out of OR…
…C and into a header in support. MSVC's std::future implementation requires types to be default constructible, but Error and Expected are not. This issue came up once before in ORC's RPCUtils.h header and was worked around there but came up again in r342939, so I am moving the workaround to Support to make it available to other clients. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343011 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
2 changed files
with
90 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
//===--- MSVCErrorWorkarounds.h - Enable future<Error> in MSVC --*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// MSVC's promise/future implementation requires types to be default | ||
// constructible, so this header provides analogues of Error an Expected | ||
// that are default constructed in a safely destructible state. | ||
// | ||
// FIXME: Kill off this header and migrate all users to Error/Expected once we | ||
// move to MSVC versions that support non-default-constructible types. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H | ||
#define LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H | ||
|
||
#include "llvm/Support/Error.h" | ||
|
||
namespace llvm { | ||
namespace orc { | ||
|
||
// A default-constructible llvm::Error that is suitable for use with MSVC's | ||
// std::future implementation which requires default constructible types. | ||
class MSVCPError : public Error { | ||
public: | ||
MSVCPError() { (void)!!*this; } | ||
|
||
MSVCPError(MSVCPError &&Other) : Error(std::move(Other)) {} | ||
|
||
MSVCPError &operator=(MSVCPError Other) { | ||
Error::operator=(std::move(Other)); | ||
return *this; | ||
} | ||
|
||
MSVCPError(Error Err) : Error(std::move(Err)) {} | ||
}; | ||
|
||
// A default-constructible llvm::Expected that is suitable for use with MSVC's | ||
// std::future implementation, which requires default constructible types. | ||
template <typename T> class MSVCPExpected : public Expected<T> { | ||
public: | ||
MSVCPExpected() | ||
: Expected<T>(make_error<StringError>("", inconvertibleErrorCode())) { | ||
consumeError(this->takeError()); | ||
} | ||
|
||
MSVCPExpected(MSVCPExpected &&Other) : Expected<T>(std::move(Other)) {} | ||
|
||
MSVCPExpected &operator=(MSVCPExpected &&Other) { | ||
Expected<T>::operator=(std::move(Other)); | ||
return *this; | ||
} | ||
|
||
MSVCPExpected(Error Err) : Expected<T>(std::move(Err)) {} | ||
|
||
template <typename OtherT> | ||
MSVCPExpected( | ||
OtherT &&Val, | ||
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = | ||
nullptr) | ||
: Expected<T>(std::move(Val)) {} | ||
|
||
template <class OtherT> | ||
MSVCPExpected( | ||
Expected<OtherT> &&Other, | ||
typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = | ||
nullptr) | ||
: Expected<T>(std::move(Other)) {} | ||
|
||
template <class OtherT> | ||
explicit MSVCPExpected( | ||
Expected<OtherT> &&Other, | ||
typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = | ||
nullptr) | ||
: Expected<T>(std::move(Other)) {} | ||
}; | ||
|
||
} // end namespace orc | ||
} // end namespace llvm | ||
|
||
#endif // LLVM_SUPPORT_MSVCERRORWORKAROUNDS_H |