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 // template <class ...Args>
20 // void promise::emplace(Args&& ... args);
21 
22 #define BOOST_THREAD_VERSION 3
23 
24 #include <boost/thread/future.hpp>
25 #include <boost/detail/lightweight_test.hpp>
26 #include <boost/static_assert.hpp>
27 
28 struct A
29 {
AA30   A() :
31     value(0)
32   {
33   }
AA34   A(int i) :
35     value(i)
36   {
37   }
AA38   A(int i, int j) :
39     value(i+j)
40   {
41   }
42   BOOST_THREAD_MOVABLE_ONLY(A)
43 
AA44   A(BOOST_THREAD_RV_REF(A) rhs)
45   {
46     if(rhs.value==0)
47     throw 9;
48     else
49     {
50       value=rhs.value;
51       rhs.value=0;
52     }
53   }
operator =A54   A& operator=(BOOST_THREAD_RV_REF(A) rhs)
55   {
56     if(rhs.value==0)
57     throw 9;
58     else
59     {
60       value=rhs.value;
61       rhs.value=0;
62     }
63     return *this;
64   }
65   int value;
66 };
67 
make(int i)68 A make(int i) {
69   return A(i);
70 }
make(int i,int j)71 A make(int i, int j) {
72   return A(i, j);
73 }
74 
75 struct movable2
76 {
77    int value_;
78    BOOST_THREAD_MOVABLE_ONLY(movable2)
movable2movable279    movable2() : value_(1){}
movable2movable280    movable2(int i) : value_(i){}
movable2movable281    movable2(int i, int j) : value_(i+j){}
82 
83    //Move constructor and assignment
movable2movable284    movable2(BOOST_RV_REF(movable2) m)
85    {  value_ = m.value_;   m.value_ = 0;  }
86 
operator =movable287    movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m)
88    {  value_ = m.value_;   m.value_ = 0;  return *this;  }
89 
movedmovable290    bool moved() const //Observer
91    {  return !value_; }
92 
valuemovable293    int value() const //Observer
94    {  return value_; }
95 };
96 
97 
move_return_function2(int i)98 movable2 move_return_function2(int i) {
99   return movable2(i);
100 }
101 
main()102 int main()
103 {
104 #if defined  BOOST_NO_CXX11_RVALUE_REFERENCES
105   BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false));
106   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true));
107   BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false));
108   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true));
109 #endif
110 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
111 
112   {
113     typedef A T;
114     T i;
115     boost::promise<T> p;
116     boost::future<T> f = p.get_future();
117     p.emplace();
118     try
119     {
120       T a = f.get(); (void)a;
121       BOOST_TEST(false);
122     }
123     catch (int j)
124     {
125       BOOST_TEST(j == 9);
126     }
127     catch (...)
128     {
129       BOOST_TEST(false);
130     }
131   }
132   {
133     typedef A T;
134     boost::promise<T> p;
135     boost::future<T> f = p.get_future();
136     p.emplace(3);
137     BOOST_TEST(f.get().value == 3);
138     try
139     {
140       T j(3);
141       p.set_value(boost::move(j));
142       BOOST_TEST(false);
143     }
144     catch (const boost::future_error& e)
145     {
146       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
147     }
148     catch (...)
149     {
150       BOOST_TEST(false);
151     }
152 
153   }
154   {
155     boost::promise<movable2> p;
156     boost::future<movable2> f = p.get_future();
157     p.emplace(3);
158     BOOST_TEST(f.get().value_ == 3);
159     try
160     {
161       p.emplace(3);
162       BOOST_TEST(false);
163     }
164     catch (const boost::future_error& e)
165     {
166       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
167     }
168     catch (...)
169     {
170       BOOST_TEST(false);
171     }
172 
173   }
174   {
175     boost::promise<A> p;
176     boost::future<A> f = p.get_future();
177     p.emplace(1,2);
178     BOOST_TEST(f.get().value == 3);
179     try
180     {
181       p.emplace(1,2);
182       BOOST_TEST(false);
183     }
184     catch (const boost::future_error& e)
185     {
186       BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied));
187     }
188     catch (...)
189     {
190       BOOST_TEST(false);
191     }
192 
193   }
194   {
195     typedef A T;
196     boost::promise<T> p;
197     boost::future<T> f = p.get_future();
198     p.emplace(3);
199     boost::promise<T> p2(boost::move(p));
200     BOOST_TEST(f.get().value == 3);
201 
202   }
203 #endif
204 
205   return boost::report_errors();
206 }
207 
208