summaryrefslogtreecommitdiff
path: root/test/std/thread/futures
diff options
context:
space:
mode:
Diffstat (limited to 'test/std/thread/futures')
-rw-r--r--test/std/thread/futures/futures.async/async.pass.cpp198
-rw-r--r--test/std/thread/futures/futures.async/async_race.pass.cpp67
-rw-r--r--test/std/thread/futures/futures.errors/default_error_condition.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp26
-rw-r--r--test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.errors/future_category.pass.cpp24
-rw-r--r--test/std/thread/futures/futures.errors/make_error_code.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.errors/make_error_condition.pass.cpp30
-rw-r--r--test/std/thread/futures/futures.future_error/code.pass.cpp43
-rw-r--r--test/std/thread/futures/futures.future_error/types.pass.cpp23
-rw-r--r--test/std/thread/futures/futures.future_error/what.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.overview/future_errc.pass.cpp30
-rw-r--r--test/std/thread/futures/futures.overview/future_status.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp21
-rw-r--r--test/std/thread/futures/futures.overview/launch.pass.cpp45
-rw-r--r--test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp84
-rw-r--r--test/std/thread/futures/futures.promise/copy_assign.fail.cpp87
-rw-r--r--test/std/thread/futures/futures.promise/copy_ctor.fail.cpp81
-rw-r--r--test/std/thread/futures/futures.promise/default.pass.cpp38
-rw-r--r--test/std/thread/futures/futures.promise/dtor.pass.cpp116
-rw-r--r--test/std/thread/futures/futures.promise/get_future.pass.cpp55
-rw-r--r--test/std/thread/futures/futures.promise/move_assign.pass.cpp91
-rw-r--r--test/std/thread/futures/futures.promise/move_ctor.pass.cpp85
-rw-r--r--test/std/thread/futures/futures.promise/set_exception.pass.cpp47
-rw-r--r--test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp44
-rw-r--r--test/std/thread/futures/futures.promise/set_lvalue.pass.cpp43
-rw-r--r--test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp38
-rw-r--r--test/std/thread/futures/futures.promise/set_rvalue.pass.cpp69
-rw-r--r--test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp41
-rw-r--r--test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp39
-rw-r--r--test/std/thread/futures/futures.promise/set_value_const.pass.cpp63
-rw-r--r--test/std/thread/futures/futures.promise/set_value_void.pass.cpp39
-rw-r--r--test/std/thread/futures/futures.promise/swap.pass.cpp84
-rw-r--r--test/std/thread/futures/futures.promise/uses_allocator.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/default.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.shared_future/dtor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/get.pass.cpp145
-rw-r--r--test/std/thread/futures/futures.shared_future/move_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.shared_future/wait.pass.cpp88
-rw-r--r--test/std/thread/futures/futures.shared_future/wait_for.pass.cpp97
-rw-r--r--test/std/thread/futures/futures.shared_future/wait_until.pass.cpp129
-rw-r--r--test/std/thread/futures/futures.state/nothing_to_do.pass.cpp13
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp48
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp29
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp30
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp46
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp27
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp79
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp124
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp48
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp62
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp64
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp106
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp107
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp60
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp50
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp52
-rw-r--r--test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp26
-rw-r--r--test/std/thread/futures/futures.tas/types.pass.cpp28
-rw-r--r--test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp74
-rw-r--r--test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp66
-rw-r--r--test/std/thread/futures/futures.unique_future/default.pass.cpp35
-rw-r--r--test/std/thread/futures/futures.unique_future/dtor.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.unique_future/get.pass.cpp145
-rw-r--r--test/std/thread/futures/futures.unique_future/move_assign.pass.cpp76
-rw-r--r--test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp70
-rw-r--r--test/std/thread/futures/futures.unique_future/share.pass.cpp68
-rw-r--r--test/std/thread/futures/futures.unique_future/wait.pass.cpp88
-rw-r--r--test/std/thread/futures/futures.unique_future/wait_for.pass.cpp97
-rw-r--r--test/std/thread/futures/futures.unique_future/wait_until.pass.cpp129
-rw-r--r--test/std/thread/futures/test_allocator.h158
-rw-r--r--test/std/thread/futures/version.pass.cpp22
78 files changed, 4937 insertions, 0 deletions
diff --git a/test/std/thread/futures/futures.async/async.pass.cpp b/test/std/thread/futures/futures.async/async.pass.cpp
new file mode 100644
index 0000000000000..c8a742566d8f2
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async.pass.cpp
@@ -0,0 +1,198 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+typedef std::chrono::high_resolution_clock Clock;
+typedef std::chrono::milliseconds ms;
+
+int f0()
+{
+ std::this_thread::sleep_for(ms(200));
+ return 3;
+}
+
+int i = 0;
+
+int& f1()
+{
+ std::this_thread::sleep_for(ms(200));
+ return i;
+}
+
+void f2()
+{
+ std::this_thread::sleep_for(ms(200));
+}
+
+std::unique_ptr<int> f3(int i)
+{
+ std::this_thread::sleep_for(ms(200));
+ return std::unique_ptr<int>(new int(i));
+}
+
+std::unique_ptr<int> f4(std::unique_ptr<int>&& p)
+{
+ std::this_thread::sleep_for(ms(200));
+ return std::move(p);
+}
+
+void f5(int i)
+{
+ std::this_thread::sleep_for(ms(200));
+ throw i;
+}
+
+int main()
+{
+ {
+ std::future<int> f = std::async(f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::async, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::any, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int> f = std::async(std::launch::deferred, f0);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<int&> f = std::async(f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::async, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::any, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<int&> f = std::async(std::launch::deferred, f1);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(&f.get() == &i);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<void> f = std::async(f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::async, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::any, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+ {
+ std::future<void> f = std::async(std::launch::deferred, f2);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ f.get();
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 > ms(100));
+ }
+
+ {
+ std::future<std::unique_ptr<int>> f = std::async(f3, 3);
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+
+ {
+ std::future<std::unique_ptr<int>> f =
+ std::async(f4, std::unique_ptr<int>(new int(3)));
+ std::this_thread::sleep_for(ms(300));
+ Clock::time_point t0 = Clock::now();
+ assert(*f.get() == 3);
+ Clock::time_point t1 = Clock::now();
+ assert(t1-t0 < ms(100));
+ }
+
+ {
+ std::future<void> f = std::async(f5, 3);
+ std::this_thread::sleep_for(ms(300));
+ try { f.get(); assert (false); } catch ( int ex ) {}
+ }
+
+ {
+ std::future<void> f = std::async(std::launch::deferred, f5, 3);
+ std::this_thread::sleep_for(ms(300));
+ try { f.get(); assert (false); } catch ( int ex ) {}
+ }
+
+}
diff --git a/test/std/thread/futures/futures.async/async_race.pass.cpp b/test/std/thread/futures/futures.async/async_race.pass.cpp
new file mode 100644
index 0000000000000..325a027132de9
--- /dev/null
+++ b/test/std/thread/futures/futures.async/async_race.pass.cpp
@@ -0,0 +1,67 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(F&& f, Args&&... args);
+
+// template <class F, class... Args>
+// future<typename result_of<F(Args...)>::type>
+// async(launch policy, F&& f, Args&&... args);
+
+// This test is designed to cause and allow TSAN to detect the race condition
+// reported in PR23293. (http://llvm.org/PR23293).
+
+#include <future>
+#include <chrono>
+#include <thread>
+#include <memory>
+#include <cassert>
+
+int f_async() {
+ typedef std::chrono::milliseconds ms;
+ std::this_thread::sleep_for(ms(200));
+ return 42;
+}
+
+bool ran = false;
+
+int f_deferred() {
+ ran = true;
+ return 42;
+}
+
+void test_each() {
+ {
+ std::future<int> f = std::async(f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ std::future<int> f = std::async(std::launch::async, f_async);
+ int const result = f.get();
+ assert(result == 42);
+ }
+ {
+ ran = false;
+ std::future<int> f = std::async(std::launch::deferred, f_deferred);
+ assert(ran == false);
+ int const result = f.get();
+ assert(ran == true);
+ assert(result == 42);
+ }
+}
+
+int main() {
+ for (int i=0; i < 25; ++i) test_each();
+}
diff --git a/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp
new file mode 100644
index 0000000000000..7f28b8a23b810
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/default_error_condition.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual error_condition default_error_condition(int ev) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ std::error_condition e_cond = e_cat.default_error_condition(static_cast<int>(std::errc::not_a_directory));
+ assert(e_cond.category() == e_cat);
+ assert(e_cond.value() == static_cast<int>(std::errc::not_a_directory));
+}
diff --git a/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
new file mode 100644
index 0000000000000..cd0017657740f
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/equivalent_error_code_int.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual bool equivalent(const error_code& code, int condition) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ assert(e_cat.equivalent(std::error_code(5, e_cat), 5));
+ assert(!e_cat.equivalent(std::error_code(5, e_cat), 6));
+}
diff --git a/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
new file mode 100644
index 0000000000000..05ad1ec9c6f55
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/equivalent_int_error_condition.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+// virtual bool equivalent(int code, const error_condition& condition) const;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& e_cat = std::future_category();
+ std::error_condition e_cond = e_cat.default_error_condition(5);
+ assert(e_cat.equivalent(5, e_cond));
+ assert(!e_cat.equivalent(6, e_cond));
+}
diff --git a/test/std/thread/futures/futures.errors/future_category.pass.cpp b/test/std/thread/futures/futures.errors/future_category.pass.cpp
new file mode 100644
index 0000000000000..7f407a061d954
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/future_category.pass.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// const error_category& future_category();
+
+#include <future>
+#include <cstring>
+#include <cassert>
+
+int main()
+{
+ const std::error_category& ec = std::future_category();
+ assert(std::strcmp(ec.name(), "future") == 0);
+}
diff --git a/test/std/thread/futures/futures.errors/make_error_code.pass.cpp b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp
new file mode 100644
index 0000000000000..3c14addf309fb
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/make_error_code.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class error_code
+
+// error_code make_error_code(future_errc e);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::error_code ec = make_error_code(std::future_errc::broken_promise);
+ assert(ec.value() == static_cast<int>(std::future_errc::broken_promise));
+ assert(ec.category() == std::future_category());
+ }
+}
diff --git a/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp
new file mode 100644
index 0000000000000..52972aa373f58
--- /dev/null
+++ b/test/std/thread/futures/futures.errors/make_error_condition.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class error_condition
+
+// error_condition make_error_condition(future_errc e);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ const std::error_condition ec1 =
+ std::make_error_condition(std::future_errc::future_already_retrieved);
+ assert(ec1.value() ==
+ static_cast<int>(std::future_errc::future_already_retrieved));
+ assert(ec1.category() == std::future_category());
+ }
+}
diff --git a/test/std/thread/futures/futures.future_error/code.pass.cpp b/test/std/thread/futures/futures.future_error/code.pass.cpp
new file mode 100644
index 0000000000000..e02af486fc39c
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/code.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future_error
+
+// const error_code& code() const throw();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::broken_promise);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::future_already_retrieved);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::promise_already_satisfied);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+ {
+ std::error_code ec = std::make_error_code(std::future_errc::no_state);
+ std::future_error f(ec);
+ assert(f.code() == ec);
+ }
+}
diff --git a/test/std/thread/futures/futures.future_error/types.pass.cpp b/test/std/thread/futures/futures.future_error/types.pass.cpp
new file mode 100644
index 0000000000000..e741dd06e4b97
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/types.pass.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future_error : public logic_error {...};
+
+#include <future>
+#include <type_traits>
+
+int main()
+{
+ static_assert((std::is_convertible<std::future_error*,
+ std::logic_error*>::value), "");
+}
diff --git a/test/std/thread/futures/futures.future_error/what.pass.cpp b/test/std/thread/futures/futures.future_error/what.pass.cpp
new file mode 100644
index 0000000000000..52d2e944a684e
--- /dev/null
+++ b/test/std/thread/futures/futures.future_error/what.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// LWG 2056 changed the values of future_errc, so if we're using new headers
+// with an old library we'll get incorrect messages.
+//
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin11
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin12
+// XFAIL: with_system_cxx_lib=x86_64-apple-darwin13
+
+// <future>
+
+// class future_error
+
+// const char* what() const throw();
+
+#include <future>
+#include <cstring>
+#include <cassert>
+
+int main()
+{
+ {
+ std::future_error f(std::make_error_code(std::future_errc::broken_promise));
+ assert(std::strcmp(f.what(), "The associated promise has been destructed prior "
+ "to the associated state becoming ready.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::future_already_retrieved));
+ assert(std::strcmp(f.what(), "The future has already been retrieved from "
+ "the promise or packaged_task.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::promise_already_satisfied));
+ assert(std::strcmp(f.what(), "The state of the promise has already been set.") == 0);
+ }
+ {
+ std::future_error f(std::make_error_code(std::future_errc::no_state));
+ assert(std::strcmp(f.what(), "Operation not permitted on an object without "
+ "an associated state.") == 0);
+ }
+}
diff --git a/test/std/thread/futures/futures.overview/future_errc.pass.cpp b/test/std/thread/futures/futures.overview/future_errc.pass.cpp
new file mode 100644
index 0000000000000..1e6fcb76a0e73
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/future_errc.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// enum class future_errc
+// {
+// future_already_retrieved = 1,
+// promise_already_satisfied,
+// no_state
+// broken_promise,
+// };
+
+#include <future>
+
+int main()
+{
+ static_assert(static_cast<int>(std::future_errc::future_already_retrieved) == 1, "");
+ static_assert(static_cast<int>(std::future_errc::promise_already_satisfied) == 2, "");
+ static_assert(static_cast<int>(std::future_errc::no_state) == 3, "");
+ static_assert(static_cast<int>(std::future_errc::broken_promise) == 4, "");
+}
diff --git a/test/std/thread/futures/futures.overview/future_status.pass.cpp b/test/std/thread/futures/futures.overview/future_status.pass.cpp
new file mode 100644
index 0000000000000..2c196aaac56d1
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/future_status.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// enum class future_status
+// {
+// ready,
+// timeout,
+// deferred
+// };
+
+#include <future>
+
+int main()
+{
+ static_assert(static_cast<int>(std::future_status::ready) == 0, "");
+ static_assert(static_cast<int>(std::future_status::timeout) == 1, "");
+ static_assert(static_cast<int>(std::future_status::deferred) == 2, "");
+}
diff --git a/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
new file mode 100644
index 0000000000000..499de52598b65
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/is_error_code_enum_future_errc.pass.cpp
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// template <> struct is_error_code_enum<future_errc> : public true_type {};
+
+#include <future>
+
+int main()
+{
+ static_assert(std::is_error_code_enum<std::future_errc>::value, "");
+}
diff --git a/test/std/thread/futures/futures.overview/launch.pass.cpp b/test/std/thread/futures/futures.overview/launch.pass.cpp
new file mode 100644
index 0000000000000..da54f7ee67329
--- /dev/null
+++ b/test/std/thread/futures/futures.overview/launch.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// enum class launch
+// {
+// async = 1,
+// deferred = 2,
+// any = async | deferred
+// };
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifdef _LIBCPP_HAS_NO_STRONG_ENUMS
+ static_assert(static_cast<int>(std::launch::any) ==
+ (static_cast<int>(std::launch::async) | static_cast<int>(std::launch::deferred)), "");
+#else
+ static_assert(std::launch::any == (std::launch::async | std::launch::deferred), "");
+ static_assert(std::launch(0) == (std::launch::async & std::launch::deferred), "");
+ static_assert(std::launch::any == (std::launch::async ^ std::launch::deferred), "");
+ static_assert(std::launch::deferred == ~std::launch::async, "");
+ std::launch x = std::launch::async;
+ x &= std::launch::deferred;
+ assert(x == std::launch(0));
+ x = std::launch::async;
+ x |= std::launch::deferred;
+ assert(x == std::launch::any);
+ x ^= std::launch::deferred;
+ assert(x == std::launch::async);
+#endif
+ static_assert(static_cast<int>(std::launch::async) == 1, "");
+ static_assert(static_cast<int>(std::launch::deferred) == 2, "");
+}
diff --git a/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
new file mode 100644
index 0000000000000..70a4e00b0d6af
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/alloc_ctor.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// template <class Allocator>
+// promise(allocator_arg_t, const Allocator& a);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+#include "min_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ // Test with a minimal allocator
+ {
+ std::promise<int> p(std::allocator_arg, bare_allocator<void>());
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p(std::allocator_arg, bare_allocator<void>());
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p(std::allocator_arg, bare_allocator<void>());
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+ // Test with a minimal allocator that returns class-type pointers
+ {
+ std::promise<int> p(std::allocator_arg, min_allocator<void>());
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p(std::allocator_arg, min_allocator<void>());
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p(std::allocator_arg, min_allocator<void>());
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/copy_assign.fail.cpp b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp
new file mode 100644
index 0000000000000..c08278122225c
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/copy_assign.fail.cpp
@@ -0,0 +1,87 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(const promise& rhs) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 2);
+ p = p0;
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp
new file mode 100644
index 0000000000000..36a3555aed468
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/copy_ctor.fail.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class promise<R>
+
+// promise(const promise&) = delete;
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/default.pass.cpp b/test/std/thread/futures/futures.promise/default.pass.cpp
new file mode 100644
index 0000000000000..95c9657c633e5
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/default.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<int&> p;
+ std::future<int&> f = p.get_future();
+ assert(f.valid());
+ }
+ {
+ std::promise<void> p;
+ std::future<void> f = p.get_future();
+ assert(f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/dtor.pass.cpp b/test/std/thread/futures/futures.promise/dtor.pass.cpp
new file mode 100644
index 0000000000000..78912f12adb98
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/dtor.pass.cpp
@@ -0,0 +1,116 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// ~promise();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value(3);
+ }
+ assert(f.get() == 3);
+ }
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ T i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+
+ {
+ typedef int& T;
+ int i = 4;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value(i);
+ }
+ assert(&f.get() == &i);
+ }
+ {
+ typedef int& T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ T i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ p.set_value();
+ }
+ f.get();
+ assert(true);
+ }
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p;
+ f = p.get_future();
+ }
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ // LWG 2056 changed the values of future_errc, so if we're using new
+ // headers with an old library the error codes won't line up.
+ //
+ // Note that this particular check only applies to promise<void>
+ // since the other specializations happen to be implemented in the
+ // header rather than the library.
+ assert(
+ e.code() == make_error_code(std::future_errc::broken_promise) ||
+ e.code() == std::error_code(0, std::future_category()));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/get_future.pass.cpp b/test/std/thread/futures/futures.promise/get_future.pass.cpp
new file mode 100644
index 0000000000000..a7d084ee78730
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/get_future.pass.cpp
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// future<R> get_future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::promise<double> p;
+ std::future<double> f = p.get_future();
+ p.set_value(105.5);
+ assert(f.get() == 105.5);
+ }
+ {
+ std::promise<double> p;
+ std::future<double> f = p.get_future();
+ try
+ {
+ f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ std::promise<double> p;
+ std::promise<double> p0 = std::move(p);
+ try
+ {
+ std::future<double> f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/move_assign.pass.cpp b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
new file mode 100644
index 0000000000000..c3097df74990a
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/move_assign.pass.cpp
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise& operator=(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::allocator_arg, test_allocator<void>());
+ assert(test_alloc_base::count == 2);
+ p = std::move(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/move_ctor.pass.cpp b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
new file mode 100644
index 0000000000000..eeec4fb15b956
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/move_ctor.pass.cpp
@@ -0,0 +1,85 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// promise(promise&& rhs);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int&> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int&> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<int&> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<void> p0(std::allocator_arg, test_allocator<void>());
+ std::promise<void> p(std::move(p0));
+ assert(test_alloc_base::count == 1);
+ std::future<void> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ try
+ {
+ f = p0.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_exception.pass.cpp b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
new file mode 100644
index 0000000000000..51c05eb803cb7
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_exception.pass.cpp
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void set_exception(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_exception(std::make_exception_ptr(3));
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ try
+ {
+ p.set_exception(std::make_exception_ptr(3));
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
new file mode 100644
index 0000000000000..5e57692563d88
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_exception_at_thread_exit.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_exception_at_thread_exit(exception_ptr p);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int> p)
+{
+ const int i = 5;
+ p.set_exception_at_thread_exit(std::make_exception_ptr(3));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
new file mode 100644
index 0000000000000..cdc37775012ce
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_lvalue.pass.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value(R& r);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int& T;
+ int i = 3;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(i);
+ int& j = f.get();
+ assert(j == 3);
+ ++i;
+ assert(j == 4);
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
new file mode 100644
index 0000000000000..18f87c596a005
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_lvalue_at_thread_exit.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<R&>::set_value_at_thread_exit(R& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<int&> p)
+{
+ p.set_value_at_thread_exit(i);
+ i = 4;
+}
+
+int main()
+{
+ {
+ std::promise<int&> p;
+ std::future<int&> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(f.get() == 4);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
new file mode 100644
index 0000000000000..dab4bf7e9c832
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_rvalue.pass.cpp
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+struct A
+{
+ A() {}
+ A(const A&) = delete;
+ A(A&&) {throw 9;}
+};
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef std::unique_ptr<int> T;
+ T i(new int(3));
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(std::move(i));
+ assert(*f.get() == 3);
+ try
+ {
+ p.set_value(std::move(i));
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(std::move(i));
+ assert(false);
+ }
+ catch (int j)
+ {
+ assert(j == 9);
+ }
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
new file mode 100644
index 0000000000000..8f3b76865e2a8
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_rvalue_at_thread_exit.pass.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(R&& r);
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+void func(std::promise<std::unique_ptr<int>> p)
+{
+ p.set_value_at_thread_exit(std::unique_ptr<int>(new int(5)));
+}
+
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ std::promise<std::unique_ptr<int>> p;
+ std::future<std::unique_ptr<int>> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(*f.get() == 5);
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
new file mode 100644
index 0000000000000..ec50cc3102983
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_const.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value_at_thread_exit(const R& r);
+
+#include <future>
+#include <cassert>
+
+void func(std::promise<int> p)
+{
+ const int i = 5;
+ p.set_value_at_thread_exit(i);
+}
+
+int main()
+{
+ {
+ std::promise<int> p;
+ std::future<int> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ assert(f.get() == 5);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
new file mode 100644
index 0000000000000..8c092084668dd
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_at_thread_exit_void.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value_at_thread_exit();
+
+#include <future>
+#include <memory>
+#include <cassert>
+
+int i = 0;
+
+void func(std::promise<void> p)
+{
+ p.set_value_at_thread_exit();
+ i = 1;
+}
+
+int main()
+{
+ {
+ std::promise<void> p;
+ std::future<void> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ f.get();
+ assert(i == 1);
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_const.pass.cpp b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
new file mode 100644
index 0000000000000..6673f63075791
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_const.pass.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise::set_value(const R& r);
+
+#include <future>
+#include <cassert>
+
+struct A
+{
+ A() {}
+ A(const A&) {throw 10;}
+};
+
+int main()
+{
+ {
+ typedef int T;
+ T i = 3;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value(i);
+ ++i;
+ assert(f.get() == 3);
+ --i;
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+ {
+ typedef A T;
+ T i;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ try
+ {
+ p.set_value(i);
+ assert(false);
+ }
+ catch (int j)
+ {
+ assert(j == 10);
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/set_value_void.pass.cpp b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
new file mode 100644
index 0000000000000..5012e0bfe5fd7
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/set_value_void.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void promise<void>::set_value();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ p.set_value();
+ f.get();
+ try
+ {
+ p.set_value();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.promise/swap.pass.cpp b/test/std/thread/futures/futures.promise/swap.pass.cpp
new file mode 100644
index 0000000000000..1ed3e646813c3
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/swap.pass.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// void swap(promise& other);
+
+// template <class R> void swap(promise<R>& x, promise<R>& y);
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ p.swap(p0);
+ assert(test_alloc_base::count == 2);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 2);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 2);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 2);
+ swap(p, p0);
+ assert(test_alloc_base::count == 2);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 2);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 2);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p;
+ assert(test_alloc_base::count == 1);
+ p.swap(p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ std::promise<int> p0(std::allocator_arg, test_allocator<int>());
+ std::promise<int> p;
+ assert(test_alloc_base::count == 1);
+ swap(p, p0);
+ assert(test_alloc_base::count == 1);
+ std::future<int> f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ f = p0.get_future();
+ assert(f.valid());
+ assert(test_alloc_base::count == 1);
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
new file mode 100644
index 0000000000000..458826e956e12
--- /dev/null
+++ b/test/std/thread/futures/futures.promise/uses_allocator.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class promise<R>
+
+// template <class R, class Alloc>
+// struct uses_allocator<promise<R>, Alloc>
+// : true_type { };
+
+#include <future>
+#include "../test_allocator.h"
+
+int main()
+{
+ static_assert((std::uses_allocator<std::promise<int>, test_allocator<int> >::value), "");
+ static_assert((std::uses_allocator<std::promise<int&>, test_allocator<int> >::value), "");
+ static_assert((std::uses_allocator<std::promise<void>, test_allocator<void> >::value), "");
+}
diff --git a/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
new file mode 100644
index 0000000000000..b23ba196ec30e
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/copy_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& operator=(const shared_future& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
new file mode 100644
index 0000000000000..425d1f9be96ff
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/copy_ctor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(const shared_future& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = f0;
+ assert(f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
new file mode 100644
index 0000000000000..3a78b80f0634a
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/ctor_future.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(future<R>&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/default.pass.cpp b/test/std/thread/futures/futures.shared_future/default.pass.cpp
new file mode 100644
index 0000000000000..92927f5f69330
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/default.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::shared_future<int> f;
+ assert(!f.valid());
+ }
+ {
+ std::shared_future<int&> f;
+ assert(!f.valid());
+ }
+ {
+ std::shared_future<void> f;
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/dtor.pass.cpp b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
new file mode 100644
index 0000000000000..baa89cb12b1c4
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// ~shared_future();
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ std::shared_future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.shared_future/get.pass.cpp b/test/std/thread/futures/futures.shared_future/get.pass.cpp
new file mode 100644
index 0000000000000..c5ee234b127f8
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/get.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// const R& shared_future::get();
+// R& shared_future<R&>::get();
+// void shared_future<void>::get();
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3.5));
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr('c'));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ assert(f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 5);
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func4, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (double i)
+ {
+ assert(i == 3.5);
+ }
+ assert(f.valid());
+ }
+ }
+ {
+ typedef void T;
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.get();
+ assert(f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func6, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ f.get();
+ assert(false);
+ }
+ catch (char i)
+ {
+ assert(i == 'c');
+ }
+ assert(f.valid());
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
new file mode 100644
index 0000000000000..6b58f41c90855
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/move_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future& operator=(shared_future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
new file mode 100644
index 0000000000000..32b8fd77c672b
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/move_ctor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// shared_future(shared_future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::shared_future<T> f0;
+ std::shared_future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait.pass.cpp b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
new file mode 100644
index 0000000000000..4293fcab35643
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// void wait() const;
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef std::chrono::duration<double, std::milli> ms;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
new file mode 100644
index 0000000000000..e5a4754e38ad5
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait_for.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class shared_future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#include <future>
+#include <cassert>
+
+typedef std::chrono::milliseconds ms;
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
new file mode 100644
index 0000000000000..6a6aeba7759e3
--- /dev/null
+++ b/test/std/thread/futures/futures.shared_future/wait_until.pass.cpp
@@ -0,0 +1,129 @@
+ //===----------------------------------------------------------------------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file is dual licensed under the MIT and the University of Illinois Open
+ // Source Licenses. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // UNSUPPORTED: libcpp-has-no-threads
+
+ // <future>
+
+ // class shared_future<R>
+
+ // template <class Clock, class Duration>
+ // future_status
+ // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #include <future>
+ #include <atomic>
+ #include <cassert>
+
+ enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
+ typedef std::chrono::milliseconds ms;
+
+ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
+
+ void set_worker_thread_state(WorkerThreadState state)
+ {
+ thread_state.store(state, std::memory_order_relaxed);
+ }
+
+ void wait_for_worker_thread_state(WorkerThreadState state)
+ {
+ while (thread_state.load(std::memory_order_relaxed) != state);
+ }
+
+ void func1(std::promise<int> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value(3);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int j = 0;
+
+ void func3(std::promise<int&> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ j = 5;
+ p.set_value(j);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ void func5(std::promise<void> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value();
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int main()
+ {
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::shared_future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ }
diff --git a/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp
new file mode 100644
index 0000000000000..9a59227abdd98
--- /dev/null
+++ b/test/std/thread/futures/futures.state/nothing_to_do.pass.cpp
@@ -0,0 +1,13 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main()
+{
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
new file mode 100644
index 0000000000000..70ea0ad31feda
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_copy.fail.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task& operator=(packaged_task&) = delete;
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p = p0;
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p = p0;
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
new file mode 100644
index 0000000000000..18786f4eb7a26
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/assign_move.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task& operator=(packaged_task&& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p = std::move(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p = std::move(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
new file mode 100644
index 0000000000000..45048b747f7a4
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor1.fail.cpp
@@ -0,0 +1,29 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+// template <class F>
+// packaged_task(F&& f);
+// These constructors shall not participate in overload resolution if
+// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>.
+
+#include <future>
+#include <cassert>
+
+struct A {};
+typedef std::packaged_task<A(int, char)> PT;
+typedef volatile std::packaged_task<A(int, char)> VPT;
+
+
+int main()
+{
+ PT p { VPT{} };
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
new file mode 100644
index 0000000000000..e4df4ec225e70
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor2.fail.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+// template <class F, class Allocator>
+// packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+// These constructors shall not participate in overload resolution if
+// decay<F>::type is the same type as std::packaged_task<R(ArgTypes...)>.
+
+#include <future>
+#include <cassert>
+
+#include "../../test_allocator.h"
+
+struct A {};
+typedef std::packaged_task<A(int, char)> PT;
+typedef volatile std::packaged_task<A(int, char)> VPT;
+
+int main()
+{
+ PT p { std::allocator_arg_t{}, test_allocator<A>{}, VPT {}};
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
new file mode 100644
index 0000000000000..9884c49a6dc7e
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_copy.fail.cpp
@@ -0,0 +1,46 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task(packaged_task&) = delete;
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
new file mode 100644
index 0000000000000..76904962a778d
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_default.pass.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task();
+
+#include <future>
+#include <cassert>
+
+struct A {};
+
+int main()
+{
+ std::packaged_task<A(int, char)> p;
+ assert(!p.valid());
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
new file mode 100644
index 0000000000000..2eee2cbc2d509
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class F>
+// explicit packaged_task(F&& f);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i) {}
+ A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
+ A(const A& a) : data_(a.data_) {++n_copies;}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+int func(int i) { return i; }
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_copies = 0;
+ {
+ A a(5);
+ std::packaged_task<double(int, char)> p(a);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies > 0);
+ assert(A::n_moves > 0);
+ }
+ {
+ std::packaged_task<int(int)> p(&func);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ {
+ std::packaged_task<int(int)> p(func);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
new file mode 100644
index 0000000000000..3aac2b26bfc1d
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_func_alloc.pass.cpp
@@ -0,0 +1,124 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class F, class Allocator>
+// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+
+#include <future>
+#include <cassert>
+
+#include "../../test_allocator.h"
+#include "min_allocator.h"
+
+class A
+{
+ long data_;
+
+public:
+ static int n_moves;
+ static int n_copies;
+
+ explicit A(long i) : data_(i) {}
+ A(A&& a) : data_(a.data_) {++n_moves; a.data_ = -1;}
+ A(const A& a) : data_(a.data_) {++n_copies;}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int A::n_moves = 0;
+int A::n_copies = 0;
+
+int func(int i) { return i; }
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ test_allocator<A>(), A(5));
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ test_allocator<A>(), a);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies > 0);
+ assert(A::n_moves > 0);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), &func);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ A a(5);
+ std::packaged_task<int(int)> p(std::allocator_arg, test_allocator<A>(), func);
+ assert(test_alloc_base::count > 0);
+ assert(p.valid());
+ std::future<int> f = p.get_future();
+ p(4);
+ assert(f.get() == 4);
+ }
+ assert(test_alloc_base::count == 0);
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ bare_allocator<void>(), A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_moves = 0;
+ {
+ std::packaged_task<double(int, char)> p(std::allocator_arg,
+ min_allocator<void>(), A(5));
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ assert(A::n_copies == 0);
+ assert(A::n_moves > 0);
+ }
+ A::n_copies = 0;
+ A::n_moves = 0;
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
new file mode 100644
index 0000000000000..88f0722817502
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/ctor_move.pass.cpp
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// packaged_task(packaged_task&& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p = std::move(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p = std::move(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
new file mode 100644
index 0000000000000..e24232d1b2276
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/dtor.pass.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// ~packaged_task();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+void func(std::packaged_task<double(int, char)> p)
+{
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p(3, 'a');
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func, std::move(p)).detach();
+ try
+ {
+ double i = f.get();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::broken_promise));
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
new file mode 100644
index 0000000000000..13b5db110668e
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/get_future.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// future<R> get_future();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ try
+ {
+ f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::future_already_retrieved));
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ try
+ {
+ std::future<double> f = p.get_future();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
new file mode 100644
index 0000000000000..61a6a4f87965c
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/make_ready_at_thread_exit.pass.cpp
@@ -0,0 +1,106 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void make_ready_at_thread_exit(ArgTypes... args);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+void func0(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'a');
+}
+
+void func1(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'z');
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p.make_ready_at_thread_exit(3, 'a');
+ try
+ {
+ p.make_ready_at_thread_exit(3, 'c');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(std::packaged_task<double(int, char)> p)
+{
+ try
+ {
+ p.make_ready_at_thread_exit(3, 'a');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func0, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const A& e)
+ {
+ assert(e(3, 'a') == 106);
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ std::thread t(func3, std::move(p));
+ t.join();
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
new file mode 100644
index 0000000000000..2a09353b1e63b
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/operator.pass.cpp
@@ -0,0 +1,107 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void operator()(ArgTypes... args);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+void func0(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p(3, 'a');
+}
+
+void func1(std::packaged_task<double(int, char)> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p(3, 'z');
+}
+
+void func2(std::packaged_task<double(int, char)> p)
+{
+ p(3, 'a');
+ try
+ {
+ p(3, 'c');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
+ }
+}
+
+void func3(std::packaged_task<double(int, char)> p)
+{
+ try
+ {
+ p(3, 'a');
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+}
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func0, std::move(p)).detach();
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ try
+ {
+ f.get();
+ assert(false);
+ }
+ catch (const A& e)
+ {
+ assert(e(3, 'a') == 106);
+ }
+ }
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ std::thread t(func2, std::move(p));
+ assert(f.get() == 105.0);
+ t.join();
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ std::thread t(func3, std::move(p));
+ t.join();
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
new file mode 100644
index 0000000000000..9d38d9b409c09
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/reset.pass.cpp
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void reset();
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const
+ {
+ if (j == 'z')
+ throw A(6);
+ return data_ + i + j;
+ }
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p(A(5));
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ p.reset();
+ p(4, 'a');
+ f = p.get_future();
+ assert(f.get() == 106.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p;
+ try
+ {
+ p.reset();
+ assert(false);
+ }
+ catch (const std::future_error& e)
+ {
+ assert(e.code() == make_error_code(std::future_errc::no_state));
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
new file mode 100644
index 0000000000000..33763bef0d0f8
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.members/swap.pass.cpp
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// void swap(packaged_task& other);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ p.swap(p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ p.swap(p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
new file mode 100644
index 0000000000000..668732b9b24a1
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/swap.pass.cpp
@@ -0,0 +1,52 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class R, class... ArgTypes>
+// void
+// swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y);
+
+#include <future>
+#include <cassert>
+
+class A
+{
+ long data_;
+
+public:
+ explicit A(long i) : data_(i) {}
+
+ long operator()(long i, long j) const {return data_ + i + j;}
+};
+
+int main()
+{
+ {
+ std::packaged_task<double(int, char)> p0(A(5));
+ std::packaged_task<double(int, char)> p;
+ swap(p, p0);
+ assert(!p0.valid());
+ assert(p.valid());
+ std::future<double> f = p.get_future();
+ p(3, 'a');
+ assert(f.get() == 105.0);
+ }
+ {
+ std::packaged_task<double(int, char)> p0;
+ std::packaged_task<double(int, char)> p;
+ swap(p, p0);
+ assert(!p0.valid());
+ assert(!p.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
new file mode 100644
index 0000000000000..986f71e29a46d
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/futures.task.nonmembers/uses_allocator.pass.cpp
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class packaged_task<R(ArgTypes...)>
+
+// template <class Callable, class Alloc>
+// struct uses_allocator<packaged_task<Callable>, Alloc>
+// : true_type { };
+
+#include <future>
+#include "../../test_allocator.h"
+
+int main()
+{
+ static_assert((std::uses_allocator<std::packaged_task<double(int, char)>, test_allocator<int> >::value), "");
+}
diff --git a/test/std/thread/futures/futures.tas/types.pass.cpp b/test/std/thread/futures/futures.tas/types.pass.cpp
new file mode 100644
index 0000000000000..dd1724ddbda5c
--- /dev/null
+++ b/test/std/thread/futures/futures.tas/types.pass.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// template<class R, class... ArgTypes>
+// class packaged_task<R(ArgTypes...)>
+// {
+// public:
+// typedef R result_type;
+
+#include <future>
+#include <type_traits>
+
+struct A {};
+
+int main()
+{
+ static_assert((std::is_same<std::packaged_task<A(int, char)>::result_type, A>::value), "");
+}
diff --git a/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp
new file mode 100644
index 0000000000000..ebdcbf98d996d
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/copy_assign.fail.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class future<R>
+
+// future& operator=(const future&) = delete;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp
new file mode 100644
index 0000000000000..8d43294edc263
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/copy_ctor.fail.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <future>
+
+// class future<R>
+
+// future(const future&) = delete;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f = f0;
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/default.pass.cpp b/test/std/thread/futures/futures.unique_future/default.pass.cpp
new file mode 100644
index 0000000000000..84cb84650dcdb
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/default.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future();
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ std::future<int> f;
+ assert(!f.valid());
+ }
+ {
+ std::future<int&> f;
+ assert(!f.valid());
+ }
+ {
+ std::future<void> f;
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/dtor.pass.cpp b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
new file mode 100644
index 0000000000000..5e9697bb939b9
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/dtor.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// ~future();
+
+#include <future>
+#include <cassert>
+
+#include "../test_allocator.h"
+
+int main()
+{
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef int& T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<int>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+ {
+ typedef void T;
+ std::future<T> f;
+ {
+ std::promise<T> p(std::allocator_arg, test_allocator<T>());
+ assert(test_alloc_base::count == 1);
+ f = p.get_future();
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 1);
+ assert(f.valid());
+ }
+ assert(test_alloc_base::count == 0);
+}
diff --git a/test/std/thread/futures/futures.unique_future/get.pass.cpp b/test/std/thread/futures/futures.unique_future/get.pass.cpp
new file mode 100644
index 0000000000000..758e38a7dae97
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/get.pass.cpp
@@ -0,0 +1,145 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// R future::get();
+// R& future<R&>::get();
+// void future<void>::get();
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+void func2(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3));
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func4(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr(3.5));
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+void func6(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_exception(std::make_exception_ptr('c'));
+}
+
+int main()
+{
+ {
+ typedef int T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func2, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (int i)
+ {
+ assert(i == 3);
+ }
+ assert(!f.valid());
+ }
+ }
+ {
+ typedef int& T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.get() == 5);
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func4, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ assert(f.get() == 3);
+ assert(false);
+ }
+ catch (double i)
+ {
+ assert(i == 3.5);
+ }
+ assert(!f.valid());
+ }
+ }
+ {
+ typedef void T;
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.get();
+ assert(!f.valid());
+ }
+ {
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func6, std::move(p)).detach();
+ try
+ {
+ assert(f.valid());
+ f.get();
+ assert(false);
+ }
+ catch (char i)
+ {
+ assert(i == 'c');
+ }
+ assert(!f.valid());
+ }
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp
new file mode 100644
index 0000000000000..8d38b81f0cdad
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/move_assign.pass.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future& operator=(future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f;
+ f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp
new file mode 100644
index 0000000000000..e12c920886fac
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/move_ctor.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// future(future&& rhs);
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::future<T> f = std::move(f0);
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+}
diff --git a/test/std/thread/futures/futures.unique_future/share.pass.cpp b/test/std/thread/futures/futures.unique_future/share.pass.cpp
new file mode 100644
index 0000000000000..794b5ce38feba
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/share.pass.cpp
@@ -0,0 +1,68 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// shared_future<R> share() &&;
+
+#include <future>
+#include <cassert>
+
+int main()
+{
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef int& T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f0 = p.get_future();
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(f.valid());
+ }
+ {
+ typedef void T;
+ std::future<T> f0;
+ std::shared_future<T> f = std::move(f0.share());
+ assert(!f0.valid());
+ assert(!f.valid());
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait.pass.cpp b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
new file mode 100644
index 0000000000000..e10d37cf80646
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait.pass.cpp
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// void wait() const;
+
+#include <future>
+#include <cassert>
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef std::chrono::duration<double, std::milli> ms;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ f.wait();
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
new file mode 100644
index 0000000000000..0a381d9ca2f0d
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait_for.pass.cpp
@@ -0,0 +1,97 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+// class future<R>
+
+// template <class Rep, class Period>
+// future_status
+// wait_for(const chrono::duration<Rep, Period>& rel_time) const;
+
+#include <future>
+#include <cassert>
+
+typedef std::chrono::milliseconds ms;
+
+void func1(std::promise<int> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value(3);
+}
+
+int j = 0;
+
+void func3(std::promise<int&> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ j = 5;
+ p.set_value(j);
+}
+
+void func5(std::promise<void> p)
+{
+ std::this_thread::sleep_for(ms(500));
+ p.set_value();
+}
+
+int main()
+{
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::timeout);
+ assert(f.valid());
+ assert(f.wait_for(ms(300)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(50));
+ }
+}
diff --git a/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
new file mode 100644
index 0000000000000..d5865b9b9dcf3
--- /dev/null
+++ b/test/std/thread/futures/futures.unique_future/wait_until.pass.cpp
@@ -0,0 +1,129 @@
+ //===----------------------------------------------------------------------===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file is dual licensed under the MIT and the University of Illinois Open
+ // Source Licenses. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // UNSUPPORTED: libcpp-has-no-threads
+
+ // <future>
+
+ // class future<R>
+
+ // template <class Clock, class Duration>
+ // future_status
+ // wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
+
+ #include <future>
+ #include <atomic>
+ #include <cassert>
+
+ enum class WorkerThreadState { Uninitialized, AllowedToRun, Exiting };
+ typedef std::chrono::milliseconds ms;
+
+ std::atomic<WorkerThreadState> thread_state(WorkerThreadState::Uninitialized);
+
+ void set_worker_thread_state(WorkerThreadState state)
+ {
+ thread_state.store(state, std::memory_order_relaxed);
+ }
+
+ void wait_for_worker_thread_state(WorkerThreadState state)
+ {
+ while (thread_state.load(std::memory_order_relaxed) != state);
+ }
+
+ void func1(std::promise<int> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value(3);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int j = 0;
+
+ void func3(std::promise<int&> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ j = 5;
+ p.set_value(j);
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ void func5(std::promise<void> p)
+ {
+ wait_for_worker_thread_state(WorkerThreadState::AllowedToRun);
+ p.set_value();
+ set_worker_thread_state(WorkerThreadState::Exiting);
+ }
+
+ int main()
+ {
+ typedef std::chrono::high_resolution_clock Clock;
+ {
+ typedef int T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func1, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef int& T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func3, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ {
+ typedef void T;
+ std::promise<T> p;
+ std::future<T> f = p.get_future();
+ std::thread(func5, std::move(p)).detach();
+ assert(f.valid());
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::timeout);
+ assert(f.valid());
+
+ // allow the worker thread to produce the result and wait until the worker is done
+ set_worker_thread_state(WorkerThreadState::AllowedToRun);
+ wait_for_worker_thread_state(WorkerThreadState::Exiting);
+
+ assert(f.wait_until(Clock::now() + ms(10)) == std::future_status::ready);
+ assert(f.valid());
+ Clock::time_point t0 = Clock::now();
+ f.wait();
+ Clock::time_point t1 = Clock::now();
+ assert(f.valid());
+ assert(t1-t0 < ms(5));
+ }
+ }
diff --git a/test/std/thread/futures/test_allocator.h b/test/std/thread/futures/test_allocator.h
new file mode 100644
index 0000000000000..50072909fa4e0
--- /dev/null
+++ b/test/std/thread/futures/test_allocator.h
@@ -0,0 +1,158 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TEST_ALLOCATOR_H
+#define TEST_ALLOCATOR_H
+
+#include <cstddef>
+#include <type_traits>
+#include <utility>
+#include <cstdlib>
+#include <new>
+#include <climits>
+
+class test_alloc_base
+{
+public:
+ static int count;
+public:
+ static int throw_after;
+};
+
+int test_alloc_base::count = 0;
+int test_alloc_base::throw_after = INT_MAX;
+
+template <class T>
+class test_allocator
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef typename std::add_lvalue_reference<value_type>::type reference;
+ typedef typename std::add_lvalue_reference<const value_type>::type const_reference;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+ pointer address(reference x) const {return &x;}
+ const_pointer address(const_reference x) const {return &x;}
+ pointer allocate(size_type n, const void* = 0)
+ {
+ if (count >= throw_after) {
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ throw std::bad_alloc();
+#else
+ std::terminate();
+#endif
+ }
+ ++count;
+ return (pointer)std::malloc(n * sizeof(T));
+ }
+ void deallocate(pointer p, size_type n)
+ {--count; std::free(p);}
+ size_type max_size() const throw()
+ {return UINT_MAX / sizeof(T);}
+ void construct(pointer p, const T& val)
+ {::new(p) T(val);}
+#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void construct(pointer p, T&& val)
+ {::new(p) T(std::move(val));}
+#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+ void destroy(pointer p) {p->~T();}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <>
+class test_allocator<void>
+ : public test_alloc_base
+{
+ int data_;
+
+ template <class U> friend class test_allocator;
+public:
+
+ typedef unsigned size_type;
+ typedef int difference_type;
+ typedef void value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ template <class U> struct rebind {typedef test_allocator<U> other;};
+
+ test_allocator() throw() : data_(-1) {}
+ explicit test_allocator(int i) throw() : data_(i) {}
+ test_allocator(const test_allocator& a) throw()
+ : data_(a.data_) {}
+ template <class U> test_allocator(const test_allocator<U>& a) throw()
+ : data_(a.data_) {}
+ ~test_allocator() throw() {data_ = 0;}
+
+ friend bool operator==(const test_allocator& x, const test_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const test_allocator& x, const test_allocator& y)
+ {return !(x == y);}
+};
+
+template <class T>
+class other_allocator
+{
+ int data_;
+
+ template <class U> friend class other_allocator;
+
+public:
+ typedef T value_type;
+
+ other_allocator() : data_(-1) {}
+ explicit other_allocator(int i) : data_(i) {}
+ template <class U> other_allocator(const other_allocator<U>& a)
+ : data_(a.data_) {}
+ T* allocate(std::size_t n)
+ {return (T*)std::malloc(n * sizeof(T));}
+ void deallocate(T* p, std::size_t n)
+ {std::free(p);}
+
+ other_allocator select_on_container_copy_construction() const
+ {return other_allocator(-2);}
+
+ friend bool operator==(const other_allocator& x, const other_allocator& y)
+ {return x.data_ == y.data_;}
+ friend bool operator!=(const other_allocator& x, const other_allocator& y)
+ {return !(x == y);}
+
+ typedef std::true_type propagate_on_container_copy_assignment;
+ typedef std::true_type propagate_on_container_move_assignment;
+ typedef std::true_type propagate_on_container_swap;
+
+#ifdef _LIBCPP_HAS_NO_ADVANCED_SFINAE
+ std::size_t max_size() const
+ {return UINT_MAX / sizeof(T);}
+#endif // _LIBCPP_HAS_NO_ADVANCED_SFINAE
+
+};
+
+#endif // TEST_ALLOCATOR_H
diff --git a/test/std/thread/futures/version.pass.cpp b/test/std/thread/futures/version.pass.cpp
new file mode 100644
index 0000000000000..6730a1477db7a
--- /dev/null
+++ b/test/std/thread/futures/version.pass.cpp
@@ -0,0 +1,22 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+
+// <future>
+
+#include <future>
+
+#ifndef _LIBCPP_VERSION
+#error _LIBCPP_VERSION not defined
+#endif
+
+int main()
+{
+}