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