1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // UNSUPPORTED: libcpp-has-no-threads
11 // UNSUPPORTED: c++98, c++03
12
13 // <future>
14
15 // class packaged_task<R(ArgTypes...)>
16
17 // void operator()(ArgTypes... args);
18
19 #include <future>
20 #include <cassert>
21
22 #include "test_macros.h"
23
24 class A
25 {
26 long data_;
27
28 public:
A(long i)29 explicit A(long i) : data_(i) {}
30
operator ()(long i,long j) const31 long operator()(long i, long j) const
32 {
33 if (j == 'z')
34 TEST_THROW(A(6));
35 return data_ + i + j;
36 }
37 };
38
func0(std::packaged_task<double (int,char)> p)39 void func0(std::packaged_task<double(int, char)> p)
40 {
41 std::this_thread::sleep_for(std::chrono::milliseconds(500));
42 p(3, 'a');
43 }
44
func1(std::packaged_task<double (int,char)> p)45 void func1(std::packaged_task<double(int, char)> p)
46 {
47 std::this_thread::sleep_for(std::chrono::milliseconds(500));
48 p(3, 'z');
49 }
50
func2(std::packaged_task<double (int,char)> p)51 void func2(std::packaged_task<double(int, char)> p)
52 {
53 #ifndef TEST_HAS_NO_EXCEPTIONS
54 p(3, 'a');
55 try
56 {
57 p(3, 'c');
58 }
59 catch (const std::future_error& e)
60 {
61 assert(e.code() == make_error_code(std::future_errc::promise_already_satisfied));
62 }
63 #else
64 ((void)p);
65 #endif
66 }
67
func3(std::packaged_task<double (int,char)> p)68 void func3(std::packaged_task<double(int, char)> p)
69 {
70 #ifndef TEST_HAS_NO_EXCEPTIONS
71 try
72 {
73 p(3, 'a');
74 }
75 catch (const std::future_error& e)
76 {
77 assert(e.code() == make_error_code(std::future_errc::no_state));
78 }
79 #else
80 ((void)p);
81 #endif
82 }
83
main()84 int main()
85 {
86 {
87 std::packaged_task<double(int, char)> p(A(5));
88 std::future<double> f = p.get_future();
89 std::thread(func0, std::move(p)).detach();
90 assert(f.get() == 105.0);
91 }
92 #ifndef TEST_HAS_NO_EXCEPTIONS
93 {
94 std::packaged_task<double(int, char)> p(A(5));
95 std::future<double> f = p.get_future();
96 std::thread(func1, std::move(p)).detach();
97 try
98 {
99 f.get();
100 assert(false);
101 }
102 catch (const A& e)
103 {
104 assert(e(3, 'a') == 106);
105 }
106 }
107 {
108 std::packaged_task<double(int, char)> p(A(5));
109 std::future<double> f = p.get_future();
110 std::thread t(func2, std::move(p));
111 assert(f.get() == 105.0);
112 t.join();
113 }
114 {
115 std::packaged_task<double(int, char)> p;
116 std::thread t(func3, std::move(p));
117 t.join();
118 }
119 #endif
120 }
121