Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / thread / test / sync / futures / promise / set_rvalue_pass.cpp
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 // Copyright (C) 2011,2014 Vicente J. Botet Escriba
11 //
12 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
13 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
14
15 // <boost/thread/future.hpp>
16
17 // class promise<R>
18
19 // void promise::set_value(R&& r);
20
21 #define BOOST_THREAD_VERSION 3
22
23 #include <boost/thread/future.hpp>
24 #include <boost/detail/lightweight_test.hpp>
25 #include <boost/static_assert.hpp>
26
27 struct A
28 {
29   A() :
30     value(0)
31   {
32   }
33   A(int i) :
34     value(i)
35   {
36   }
37   BOOST_THREAD_MOVABLE_ONLY(A)
38
39   A(BOOST_THREAD_RV_REF(A) rhs)
40   {
41     if(rhs.value==0)
42     throw 9;
43     else
44     {
45       value=rhs.value;
46       rhs.value=0;
47     }
48   }
49   A& operator=(BOOST_THREAD_RV_REF(A) rhs)
50   {
51     if(rhs.value==0)
52     throw 9;
53     else
54     {
55       value=rhs.value;
56       rhs.value=0;
57     }
58     return *this;
59   }
60   int value;
61 };
62
63 A make(int i) {
64   return A(i);
65 }
66
67 struct movable2
68 {
69    int value_;
70    BOOST_THREAD_MOVABLE_ONLY(movable2)
71    movable2() : value_(1){}
72    movable2(int i) : value_(i){}
73
74    //Move constructor and assignment
75    movable2(BOOST_RV_REF(movable2) m)
76    {  value_ = m.value_;   m.value_ = 0;  }
77
78    movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
79    {  value_ = m.value_;   m.value_ = 0;  return *this;  }
80
81    bool moved() const //Observer
82    {  return !value_; }
83
84    int value() const //Observer
85    {  return value_; }
86 };
87
88
89 movable2 move_return_function2(int i) {
90   return movable2(i);
91 }
92
93 int main()
94 {
95 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
96   BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
97   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
98   BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
99   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
100 #endif
101
102   {
103     typedef A T;
104     T i;
105     boost::promise<T> p;
106     boost::future<T> f = p.get_future();
107     try
108     {
109       p.set_value(boost::move(i));
110       BOOST_TEST(false);
111     }
112     catch (int j)
113     {
114       BOOST_TEST(j == 9);
115     }
116     catch (...)
117     {
118       BOOST_TEST(false);
119     }
120   }
121   {
122     typedef A T;
123     T i;
124     boost::promise<T> p;
125     boost::future<T> f = p.get_future();
126     try
127     {
128       p.set_value((T()));
129       BOOST_TEST(false);
130     }
131     catch (int j)
132     {
133       BOOST_TEST(j == 9);
134     }
135     catch (...)
136     {
137       BOOST_TEST(false);
138     }
139   }
140   {
141     typedef A T;
142     T i(3);
143     boost::promise<T> p;
144     boost::future<T> f = p.get_future();
145     p.set_value(boost::move(i));
146     BOOST_TEST(f.get().value == 3);
147     try
148     {
149       T j(3);
150       p.set_value(boost::move(j));
151       BOOST_TEST(false);
152     }
153     catch (const boost::future_error& e)
154     {
155       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
156     }
157     catch (...)
158     {
159       BOOST_TEST(false);
160     }
161
162   }
163   {
164     movable2 i(3);
165     boost::promise<movable2> p;
166     boost::future<movable2> f = p.get_future();
167     p.set_value(move_return_function2(3));
168     BOOST_TEST(f.get().value_ == 3);
169     try
170     {
171       movable2 j(3);
172       p.set_value(boost::move(j));
173       BOOST_TEST(false);
174     }
175     catch (const boost::future_error& e)
176     {
177       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
178     }
179     catch (...)
180     {
181       BOOST_TEST(false);
182     }
183
184   }
185   {
186     boost::promise<A> p;
187     boost::future<A> f = p.get_future();
188     p.set_value(make(3));
189     BOOST_TEST(f.get().value == 3);
190     try
191     {
192       A j(3);
193       p.set_value(boost::move(j));
194       BOOST_TEST(false);
195     }
196     catch (const boost::future_error& e)
197     {
198       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
199     }
200     catch (...)
201     {
202       BOOST_TEST(false);
203     }
204
205   }
206   {
207     typedef A T;
208     T i(3);
209     boost::promise<T> p;
210     boost::future<T> f = p.get_future();
211     p.set_value(boost::move(i));
212     BOOST_TEST(i.value == 0);
213     boost::promise<T> p2(boost::move(p));
214     BOOST_TEST(f.get().value == 3);
215
216   }
217   {
218     typedef A T;
219     T i(3);
220     boost::promise<T> p;
221     boost::future<T> f = p.get_future();
222     p.set_value(boost::move(i));
223     BOOST_TEST(i.value == 0);
224     boost::promise<T> p2(boost::move(p));
225     boost::future<T> f2(boost::move(f));
226     BOOST_TEST(f2.get().value == 3);
227
228   }
229   {
230     typedef A T;
231     T i(3);
232     boost::promise<T> p;
233     p.set_value(boost::move(i));
234     BOOST_TEST(i.value == 0);
235     boost::promise<T> p2(boost::move(p));
236     boost::future<T> f = p2.get_future();
237     BOOST_TEST(f.get().value == 3);
238
239   }
240
241   {
242     typedef boost::future<int> T;
243     boost::promise<int> pi;
244     T fi=pi.get_future();
245     pi.set_value(3);
246
247     boost::promise<T> p;
248     boost::future<T> f = p.get_future();
249     p.set_value(boost::move(fi));
250     boost::future<T> f2(boost::move(f));
251     BOOST_TEST(f2.get().get() == 3);
252   }
253
254   return boost::report_errors();
255 }
256