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 
12 // <future>
13 
14 // template <class F, class... Args>
15 //     future<typename result_of<F(Args...)>::type>
16 //     async(F&& f, Args&&... args);
17 
18 // template <class F, class... Args>
19 //     future<typename result_of<F(Args...)>::type>
20 //     async(launch policy, F&& f, Args&&... args);
21 
22 #include <future>
23 #include <memory>
24 #include <cassert>
25 
26 typedef std::chrono::high_resolution_clock Clock;
27 typedef std::chrono::milliseconds ms;
28 
f0()29 int f0()
30 {
31     std::this_thread::sleep_for(ms(200));
32     return 3;
33 }
34 
35 int i = 0;
36 
f1()37 int& f1()
38 {
39     std::this_thread::sleep_for(ms(200));
40     return i;
41 }
42 
f2()43 void f2()
44 {
45     std::this_thread::sleep_for(ms(200));
46 }
47 
f3(int i)48 std::unique_ptr<int> f3(int i)
49 {
50     std::this_thread::sleep_for(ms(200));
51     return std::unique_ptr<int>(new int(i));
52 }
53 
f4(std::unique_ptr<int> && p)54 std::unique_ptr<int> f4(std::unique_ptr<int>&& p)
55 {
56     std::this_thread::sleep_for(ms(200));
57     return std::move(p);
58 }
59 
f5(int i)60 void f5(int i)
61 {
62     std::this_thread::sleep_for(ms(200));
63     throw i;
64 }
65 
main()66 int main()
67 {
68     {
69         std::future<int> f = std::async(f0);
70         std::this_thread::sleep_for(ms(300));
71         Clock::time_point t0 = Clock::now();
72         assert(f.get() == 3);
73         Clock::time_point t1 = Clock::now();
74         assert(t1-t0 < ms(100));
75     }
76     {
77         std::future<int> f = std::async(std::launch::async, f0);
78         std::this_thread::sleep_for(ms(300));
79         Clock::time_point t0 = Clock::now();
80         assert(f.get() == 3);
81         Clock::time_point t1 = Clock::now();
82         assert(t1-t0 < ms(100));
83     }
84     {
85         std::future<int> f = std::async(std::launch::any, f0);
86         std::this_thread::sleep_for(ms(300));
87         Clock::time_point t0 = Clock::now();
88         assert(f.get() == 3);
89         Clock::time_point t1 = Clock::now();
90         assert(t1-t0 < ms(100));
91     }
92     {
93         std::future<int> f = std::async(std::launch::deferred, f0);
94         std::this_thread::sleep_for(ms(300));
95         Clock::time_point t0 = Clock::now();
96         assert(f.get() == 3);
97         Clock::time_point t1 = Clock::now();
98         assert(t1-t0 > ms(100));
99     }
100 
101     {
102         std::future<int&> f = std::async(f1);
103         std::this_thread::sleep_for(ms(300));
104         Clock::time_point t0 = Clock::now();
105         assert(&f.get() == &i);
106         Clock::time_point t1 = Clock::now();
107         assert(t1-t0 < ms(100));
108     }
109     {
110         std::future<int&> f = std::async(std::launch::async, f1);
111         std::this_thread::sleep_for(ms(300));
112         Clock::time_point t0 = Clock::now();
113         assert(&f.get() == &i);
114         Clock::time_point t1 = Clock::now();
115         assert(t1-t0 < ms(100));
116     }
117     {
118         std::future<int&> f = std::async(std::launch::any, f1);
119         std::this_thread::sleep_for(ms(300));
120         Clock::time_point t0 = Clock::now();
121         assert(&f.get() == &i);
122         Clock::time_point t1 = Clock::now();
123         assert(t1-t0 < ms(100));
124     }
125     {
126         std::future<int&> f = std::async(std::launch::deferred, f1);
127         std::this_thread::sleep_for(ms(300));
128         Clock::time_point t0 = Clock::now();
129         assert(&f.get() == &i);
130         Clock::time_point t1 = Clock::now();
131         assert(t1-t0 > ms(100));
132     }
133 
134     {
135         std::future<void> f = std::async(f2);
136         std::this_thread::sleep_for(ms(300));
137         Clock::time_point t0 = Clock::now();
138         f.get();
139         Clock::time_point t1 = Clock::now();
140         assert(t1-t0 < ms(100));
141     }
142     {
143         std::future<void> f = std::async(std::launch::async, f2);
144         std::this_thread::sleep_for(ms(300));
145         Clock::time_point t0 = Clock::now();
146         f.get();
147         Clock::time_point t1 = Clock::now();
148         assert(t1-t0 < ms(100));
149     }
150     {
151         std::future<void> f = std::async(std::launch::any, f2);
152         std::this_thread::sleep_for(ms(300));
153         Clock::time_point t0 = Clock::now();
154         f.get();
155         Clock::time_point t1 = Clock::now();
156         assert(t1-t0 < ms(100));
157     }
158     {
159         std::future<void> f = std::async(std::launch::deferred, f2);
160         std::this_thread::sleep_for(ms(300));
161         Clock::time_point t0 = Clock::now();
162         f.get();
163         Clock::time_point t1 = Clock::now();
164         assert(t1-t0 > ms(100));
165     }
166 
167     {
168         std::future<std::unique_ptr<int>> f = std::async(f3, 3);
169         std::this_thread::sleep_for(ms(300));
170         Clock::time_point t0 = Clock::now();
171         assert(*f.get() == 3);
172         Clock::time_point t1 = Clock::now();
173         assert(t1-t0 < ms(100));
174     }
175 
176     {
177         std::future<std::unique_ptr<int>> f =
178                                std::async(f4, std::unique_ptr<int>(new int(3)));
179         std::this_thread::sleep_for(ms(300));
180         Clock::time_point t0 = Clock::now();
181         assert(*f.get() == 3);
182         Clock::time_point t1 = Clock::now();
183         assert(t1-t0 < ms(100));
184     }
185 
186     {
187         std::future<void> f = std::async(f5, 3);
188         std::this_thread::sleep_for(ms(300));
189         try { f.get(); assert (false); } catch ( int ex ) {}
190     }
191 
192     {
193         std::future<void> f = std::async(std::launch::deferred, f5, 3);
194         std::this_thread::sleep_for(ms(300));
195         try { f.get(); assert (false); } catch ( int ex ) {}
196     }
197 
198 }
199