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).then([](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).then([](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).then([](T2&& v) { return T(std::move(v)); }));
+}
+
template <class T>
template <class T2, typename>
Future<T>::Future(T2&& val)
Future(Future&&) noexcept;
Future& operator=(Future&&) noexcept;
+ // converting move
+ 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 = 0>
+ /* implicit */ Future(Future<T2>&&);
+ 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 = 0>
+ explicit Future(Future<T2>&&);
+ 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 = 0>
+ Future& operator=(Future<T2>&&);
+
/// Construct a Future from a value (perfect forwarding)
template <class T2 = T, typename =
typename std::enable_if<
--- /dev/null
+/*
+ * Copyright 2017 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <folly/futures/Future.h>
+#include <folly/portability/GTest.h>
+
+#include <thread>
+
+using namespace folly;
+
+namespace {
+struct Widget {
+ int v_;
+ /* implicit */ Widget(int v) : v_(v) {}
+ Widget(const Widget& other) = default;
+ Widget(Widget&& other) noexcept = default;
+ Widget& operator=(const Widget& /* other */) {
+ throw std::logic_error("unexpected copy assignment");
+ }
+ Widget& operator=(Widget&& /* other */) {
+ throw std::logic_error("unexpected move assignment");
+ }
+ explicit operator int() && {
+ return v_;
+ }
+};
+}
+
+TEST(ConverstionOperator, DirectInitialization) {
+ auto future = makeFuture<Widget>(23);
+ EXPECT_EQ(future.value().v_, 23);
+ Future<int> secondFuture{std::move(future)};
+ EXPECT_EQ(secondFuture.value(), 23);
+}
+
+TEST(ConverstionOperator, StaticCast) {
+ auto future = makeFuture<Widget>(23);
+ EXPECT_EQ(future.value().v_, 23);
+ EXPECT_EQ(static_cast<Future<int>>(std::move(future)).value(), 23);
+}
using namespace folly;
+namespace {
struct Widget {
int v_, copied_, moved_;
/* implicit */ Widget(int v) : v_(v), copied_(0), moved_(0) {}
throw std::logic_error("unexpected move assignment");
}
};
+}
TEST(Then, tryConstructor) {
auto t = Try<Widget>(23);
../futures/test/CallbackLifetimeTest.cpp \
../futures/test/CollectTest.cpp \
../futures/test/ContextTest.cpp \
+ ../futures/test/ConversionOperatorTest.cpp \
../futures/test/CoreTest.cpp \
../futures/test/EnsureTest.cpp \
../futures/test/ExecutorTest.cpp \