Commit 178fe966 authored by Uladzislau Paulovich's avatar Uladzislau Paulovich Committed by Facebook Github Bot

folly | Inline Future constructors to workaround MSVC bug (#1212)

Summary:
Pull Request resolved: https://github.com/facebook/folly/pull/1212

MSVC has a bug and can't match definitions of some of the constructors to the corresponding declarations in a class body. This diff workarounds the bug by inlining constructors.

Reviewed By: LeeHowes

Differential Revision: D17119718

fbshipit-source-id: eb7a9d4916b962c718d047eb0ee7fa4a9761776e
parent b1ac6a22
...@@ -206,14 +206,6 @@ FutureBase<T>::FutureBase( ...@@ -206,14 +206,6 @@ FutureBase<T>::FutureBase(
typename std::enable_if<std::is_same<Unit, T2>::value>::type*) typename std::enable_if<std::is_same<Unit, T2>::value>::type*)
: core_(Core::make(Try<T>(T()))) {} : core_(Core::make(Try<T>(T()))) {}
template <class T>
template <
class... Args,
typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
type>
FutureBase<T>::FutureBase(in_place_t, Args&&... args)
: core_(Core::make(in_place, std::forward<Args>(args)...)) {}
template <class T> template <class T>
void FutureBase<T>::assign(FutureBase<T>&& other) noexcept { void FutureBase<T>::assign(FutureBase<T>&& other) noexcept {
detach(); detach();
...@@ -898,42 +890,6 @@ Future<T>& Future<T>::operator=(Future<T>&& other) noexcept { ...@@ -898,42 +890,6 @@ Future<T>& Future<T>::operator=(Future<T>&& other) noexcept {
return *this; return *this;
} }
template <class T>
template <
class T2,
typename std::enable_if<
!std::is_same<T, typename std::decay<T2>::type>::value &&
std::is_constructible<T, T2&&>::value &&
std::is_convertible<T2&&, T>::value,
int>::type>
Future<T>::Future(Future<T2>&& other)
: Future(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
template <class T>
template <
class T2,
typename std::enable_if<
!std::is_same<T, typename std::decay<T2>::type>::value &&
std::is_constructible<T, T2&&>::value &&
!std::is_convertible<T2&&, T>::value,
int>::type>
Future<T>::Future(Future<T2>&& other)
: Future(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
template <class T>
template <
class T2,
typename std::enable_if<
!std::is_same<T, typename std::decay<T2>::type>::value &&
std::is_constructible<T, T2&&>::value,
int>::type>
Future<T>& Future<T>::operator=(Future<T2>&& other) {
return operator=(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); }));
}
// unwrap // unwrap
template <class T> template <class T>
......
...@@ -147,7 +147,8 @@ class FutureBase { ...@@ -147,7 +147,8 @@ class FutureBase {
class... Args, class... Args,
typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>:: typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
type = 0> type = 0>
explicit FutureBase(in_place_t, Args&&... args); explicit FutureBase(in_place_t, Args&&... args)
: core_(Core::make(in_place, std::forward<Args>(args)...)) {}
FutureBase(FutureBase<T> const&) = delete; FutureBase(FutureBase<T> const&) = delete;
FutureBase(SemiFuture<T>&&) noexcept; FutureBase(SemiFuture<T>&&) noexcept;
...@@ -998,7 +999,10 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -998,7 +999,10 @@ class Future : private futures::detail::FutureBase<T> {
std::is_constructible<T, T2&&>::value && std::is_constructible<T, T2&&>::value &&
std::is_convertible<T2&&, T>::value, std::is_convertible<T2&&, T>::value,
int>::type = 0> int>::type = 0>
/* implicit */ Future(Future<T2>&&); /* implicit */ Future(Future<T2>&& other)
: Future(std::move(other).thenValue(
[](T2&& v) { return T(std::move(v)); })) {}
template < template <
class T2, class T2,
typename std::enable_if< typename std::enable_if<
...@@ -1006,14 +1010,20 @@ class Future : private futures::detail::FutureBase<T> { ...@@ -1006,14 +1010,20 @@ class Future : private futures::detail::FutureBase<T> {
std::is_constructible<T, T2&&>::value && std::is_constructible<T, T2&&>::value &&
!std::is_convertible<T2&&, T>::value, !std::is_convertible<T2&&, T>::value,
int>::type = 0> int>::type = 0>
explicit Future(Future<T2>&&); explicit Future(Future<T2>&& other)
: Future(std::move(other).thenValue(
[](T2&& v) { return T(std::move(v)); })) {}
template < template <
class T2, class T2,
typename std::enable_if< typename std::enable_if<
!std::is_same<T, typename std::decay<T2>::type>::value && !std::is_same<T, typename std::decay<T2>::type>::value &&
std::is_constructible<T, T2&&>::value, std::is_constructible<T, T2&&>::value,
int>::type = 0> int>::type = 0>
Future& operator=(Future<T2>&&); Future& operator=(Future<T2>&& other) {
return operator=(
std::move(other).thenValue([](T2&& v) { return T(std::move(v)); }));
}
using Base::cancel; using Base::cancel;
using Base::hasException; using Base::hasException;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment