1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: libcpp-has-no-threads
10 // UNSUPPORTED: c++03
11
12 // <future>
13
14 // class packaged_task<R(ArgTypes...)>
15
16 // void operator()(ArgTypes... args);
17
18 #include <future>
19 #include <cassert>
20
21 #include "make_test_thread.h"
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(int,char **)84 int main(int, char**)
85 {
86 {
87 std::packaged_task<double(int, char)> p(A(5));
88 std::future<double> f = p.get_future();
89 support::make_test_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 support::make_test_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 = support::make_test_thread(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 = support::make_test_thread(func3, std::move(p));
117 t.join();
118 }
119 #endif
120
121 return 0;
122 }
123