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