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
24typedef std::chrono::high_resolution_clock Clock;
25typedef std::chrono::milliseconds ms;
26
27int f0()
28{
29    std::this_thread::sleep_for(ms(200));
30    return 3;
31}
32
33int i = 0;
34
35int& f1()
36{
37    std::this_thread::sleep_for(ms(200));
38    return i;
39}
40
41void f2()
42{
43    std::this_thread::sleep_for(ms(200));
44}
45
46std::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
52std::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
58void f5(int i)
59{
60    std::this_thread::sleep_for(ms(200));
61    throw i;
62}
63
64int 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