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 // UNSUPPORTED: c++98, c++03
12 
13 // <future>
14 
15 // class shared_future<R>
16 
17 // const R& shared_future::get();
18 // R& shared_future<R&>::get();
19 // void shared_future<void>::get();
20 
21 #include <future>
22 #include <cassert>
23 
24 void func1(std::promise<int> p)
25 {
26     std::this_thread::sleep_for(std::chrono::milliseconds(500));
27     p.set_value(3);
28 }
29 
30 void func2(std::promise<int> p)
31 {
32     std::this_thread::sleep_for(std::chrono::milliseconds(500));
33     p.set_exception(std::make_exception_ptr(3));
34 }
35 
36 int j = 0;
37 
38 void func3(std::promise<int&> p)
39 {
40     std::this_thread::sleep_for(std::chrono::milliseconds(500));
41     j = 5;
42     p.set_value(j);
43 }
44 
45 void func4(std::promise<int&> p)
46 {
47     std::this_thread::sleep_for(std::chrono::milliseconds(500));
48     p.set_exception(std::make_exception_ptr(3.5));
49 }
50 
51 void func5(std::promise<void> p)
52 {
53     std::this_thread::sleep_for(std::chrono::milliseconds(500));
54     p.set_value();
55 }
56 
57 void func6(std::promise<void> p)
58 {
59     std::this_thread::sleep_for(std::chrono::milliseconds(500));
60     p.set_exception(std::make_exception_ptr('c'));
61 }
62 
63 int main()
64 {
65     {
66         typedef int T;
67         {
68             std::promise<T> p;
69             std::shared_future<T> f = p.get_future();
70             std::thread(func1, std::move(p)).detach();
71             assert(f.valid());
72             assert(f.get() == 3);
73             assert(f.valid());
74         }
75         {
76             std::promise<T> p;
77             std::shared_future<T> f = p.get_future();
78             std::thread(func2, std::move(p)).detach();
79             try
80             {
81                 assert(f.valid());
82                 assert(f.get() == 3);
83                 assert(false);
84             }
85             catch (int i)
86             {
87                 assert(i == 3);
88             }
89             assert(f.valid());
90         }
91     }
92     {
93         typedef int& T;
94         {
95             std::promise<T> p;
96             std::shared_future<T> f = p.get_future();
97             std::thread(func3, std::move(p)).detach();
98             assert(f.valid());
99             assert(f.get() == 5);
100             assert(f.valid());
101         }
102         {
103             std::promise<T> p;
104             std::shared_future<T> f = p.get_future();
105             std::thread(func4, std::move(p)).detach();
106             try
107             {
108                 assert(f.valid());
109                 assert(f.get() == 3);
110                 assert(false);
111             }
112             catch (double i)
113             {
114                 assert(i == 3.5);
115             }
116             assert(f.valid());
117         }
118     }
119     {
120         typedef void T;
121         {
122             std::promise<T> p;
123             std::shared_future<T> f = p.get_future();
124             std::thread(func5, std::move(p)).detach();
125             assert(f.valid());
126             f.get();
127             assert(f.valid());
128         }
129         {
130             std::promise<T> p;
131             std::shared_future<T> f = p.get_future();
132             std::thread(func6, std::move(p)).detach();
133             try
134             {
135                 assert(f.valid());
136                 f.get();
137                 assert(false);
138             }
139             catch (char i)
140             {
141                 assert(i == 'c');
142             }
143             assert(f.valid());
144         }
145     }
146 }
147