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