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