• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 // class packaged_task<R>
17 
18 // template <class F>
19 //     explicit packaged_task(F&& f);
20 
21 
22 #define BOOST_THREAD_VERSION 4
23 
24 #include <boost/thread/future.hpp>
25 #include <boost/detail/lightweight_test.hpp>
26 
27 #if BOOST_THREAD_VERSION == 4
28 #define BOOST_THREAD_DETAIL_SIGNATURE double()
29 #define BOOST_THREAD_DETAIL_VOID_SIGNATURE void()
30 #else
31 #define BOOST_THREAD_DETAIL_SIGNATURE double
32 #define BOOST_THREAD_DETAIL_VOID_SIGNATURE void
33 #endif
34 
35 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
36 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
37 #define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char)
38 #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a'
39 #define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void(int)
40 #else
41 #define BOOST_THREAD_DETAIL_SIGNATURE_2 double()
42 #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
43 #define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void()
44 #endif
45 #else
46 #define BOOST_THREAD_DETAIL_SIGNATURE_2 double
47 #define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5
48 #define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void
49 #endif
50 
void_fct()51 void void_fct()
52 {
53   return;
54 }
fct()55 double fct()
56 {
57   return 5.0;
58 }
lfct()59 long lfct()
60 {
61   return 5;
62 }
63 
64 class A
65 {
66 public:
67   long data_;
68 
69   static int n_moves;
70   static int n_copies;
BOOST_THREAD_COPYABLE_AND_MOVABLE(A)71   BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
72   static void reset()
73   {
74     n_moves=0;
75     n_copies=0;
76   }
77 
A(long i)78   explicit A(long i) : data_(i)
79   {
80   }
A(BOOST_THREAD_RV_REF (A)a)81   A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
82   {
83     BOOST_THREAD_RV(a).data_ = -1;
84     ++n_moves;
85   }
operator =(BOOST_THREAD_RV_REF (A)a)86   A& operator=(BOOST_THREAD_RV_REF(A) a)
87   {
88     data_ = BOOST_THREAD_RV(a).data_;
89     BOOST_THREAD_RV(a).data_ = -1;
90     ++n_moves;
91     return *this;
92   }
A(const A & a)93   A(const A& a) : data_(a.data_)
94   {
95     ++n_copies;
96   }
operator =(BOOST_THREAD_COPY_ASSIGN_REF (A)a)97   A& operator=(BOOST_THREAD_COPY_ASSIGN_REF(A) a)
98   {
99     data_ = a.data_;
100     ++n_copies;
101     return *this;
102   }
~A()103   ~A()
104   {
105   }
106 
operator ()(int) const107   void operator()(int) const
108   { }
operator ()() const109   long operator()() const
110   { return data_;}
operator ()(long i,long j) const111   long operator()(long i, long j) const
112   { return data_ + i + j;}
113 };
114 
115 int A::n_moves = 0;
116 int A::n_copies = 0;
117 
118 class M
119 {
120 
121 public:
122   long data_;
123   static int n_moves;
124 
BOOST_THREAD_MOVABLE_ONLY(M)125   BOOST_THREAD_MOVABLE_ONLY(M)
126   static void reset() {
127     n_moves=0;
128   }
M(long i)129   explicit M(long i) : data_(i)
130   {
131   }
M(BOOST_THREAD_RV_REF (M)a)132   M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_)
133   {
134     BOOST_THREAD_RV(a).data_ = -1;
135     ++n_moves;
136   }
operator =(BOOST_THREAD_RV_REF (M)a)137   M& operator=(BOOST_THREAD_RV_REF(M) a)
138   {
139     data_ = BOOST_THREAD_RV(a).data_;
140     BOOST_THREAD_RV(a).data_ = -1;
141     ++n_moves;
142     return *this;
143   }
~M()144   ~M()
145   {
146   }
147 
operator ()(int) const148   void operator()(int) const
149   { }
operator ()() const150   long operator()() const
151   { return data_;}
operator ()(long i,long j) const152   long operator()(long i, long j) const
153   { return data_ + i + j;}
154 };
155 
156 int M::n_moves = 0;
157 
158 class C
159 {
160 public:
161   long data_;
162 
163   static int n_copies;
reset()164   static void reset()
165   {
166     n_copies=0;
167   }
168 
C(long i)169   explicit C(long i) : data_(i)
170   {
171   }
C(const C & a)172   C(const C& a) : data_(a.data_)
173   {
174     ++n_copies;
175   }
operator =(C const & a)176   C& operator=(C const& a)
177   {
178     data_ = a.data_;
179     ++n_copies;
180     return *this;
181   }
~C()182   ~C()
183   {
184   }
185 
operator ()(int) const186   void operator()(int) const
187   { }
operator ()() const188   long operator()() const
189   { return data_;}
operator ()(long i,long j) const190   long operator()(long i, long j) const
191   { return data_ + i + j;}
192 };
193 int C::n_copies = 0;
194 
main()195 int main()
196 {
197   {
198       A::reset();
199       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
200       BOOST_TEST(p.valid());
201       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
202 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
203       p(3, 'a');
204 #else
205       p();
206 #endif
207       BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
208       BOOST_TEST(A::n_copies == 0);
209       BOOST_TEST_EQ(A::n_moves, 1);
210   }
211   {
212     A::reset();
213       A a(5);
214       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
215       BOOST_TEST(p.valid());
216       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
217       //p(3, 'a');
218       p();
219       BOOST_TEST(f.get() == 5.0);
220       BOOST_TEST_EQ(A::n_copies, 1);
221       BOOST_TEST_EQ(A::n_moves, 0);
222   }
223   {
224     A::reset();
225       const A a(5);
226       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
227       BOOST_TEST(p.valid());
228       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
229       //p(3, 'a');
230       p();
231       BOOST_TEST(f.get() == 5.0);
232       BOOST_TEST_EQ(A::n_copies, 1);
233       BOOST_TEST_EQ(A::n_moves, 0);
234   }
235 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
236   {
237     A::reset();
238       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5)));
239       BOOST_TEST(p.valid());
240       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
241       p(1);
242       BOOST_TEST(A::n_copies == 0);
243       BOOST_TEST_EQ(A::n_moves, 1);
244   }
245   {
246     A::reset();
247       A a(5);
248       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
249       BOOST_TEST(p.valid());
250       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
251       p(1);
252       BOOST_TEST_EQ(A::n_copies, 1);
253       BOOST_TEST_EQ(A::n_moves, 0);
254   }
255   {
256     A::reset();
257       const A a(5);
258       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
259       BOOST_TEST(p.valid());
260       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
261       p(1);
262       BOOST_TEST_EQ(A::n_copies, 1);
263       BOOST_TEST_EQ(A::n_moves, 0);
264   }
265 #endif
266   {
267     M::reset();
268       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
269       BOOST_TEST(p.valid());
270       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
271 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
272       p(3, 'a');
273 #else
274       p();
275 #endif
276       BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
277       BOOST_TEST_EQ(M::n_moves, 1);
278   }
279   {
280     M::reset();
281       M a(5);
282       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::move(a));
283       BOOST_TEST(p.valid());
284       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
285       //p(3, 'a');
286       p();
287       BOOST_TEST(f.get() == 5.0);
288       BOOST_TEST_EQ(M::n_moves, 1);
289   }
290 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
291   {
292     M::reset();
293       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
294       BOOST_TEST(p.valid());
295       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
296       p(1);
297       BOOST_TEST_EQ(M::n_moves, 1);
298   }
299   {
300     M::reset();
301       M a(5);
302       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(boost::move(a));
303       BOOST_TEST(p.valid());
304       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
305       p(1);
306       BOOST_TEST_EQ(M::n_moves, 1);
307   }
308 #endif
309   {
310     C::reset();
311       C a(5);
312       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
313       BOOST_TEST(p.valid());
314       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
315       //p(3, 'a');
316       p();
317       BOOST_TEST(f.get() == 5.0);
318       BOOST_TEST_EQ(C::n_copies, 1);
319   }
320 
321   {
322     C::reset();
323       const C a(5);
324       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
325       BOOST_TEST(p.valid());
326       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
327       //p(3, 'a');
328       p();
329       BOOST_TEST(f.get() == 5.0);
330       BOOST_TEST_EQ(C::n_copies, 1);
331   }
332 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
333   {
334     C::reset();
335       C a(5);
336       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
337       BOOST_TEST(p.valid());
338       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
339       p(1);
340       BOOST_TEST_EQ(C::n_copies, 1);
341   }
342 
343   {
344     C::reset();
345       const C a(5);
346       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a);
347       BOOST_TEST(p.valid());
348       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
349       p(1);
350       BOOST_TEST_EQ(C::n_copies, 1);
351   }
352 #endif
353   {
354       boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE> p(void_fct);
355       BOOST_TEST(p.valid());
356       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
357       p();
358   }
359   {
360       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct);
361       BOOST_TEST(p.valid());
362       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
363       //p(3, 'a');
364       p();
365       BOOST_TEST(f.get() == 5.0);
366   }
367   {
368       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(&lfct);
369       BOOST_TEST(p.valid());
370       boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
371       //p(3, 'a');
372       p();
373       BOOST_TEST(f.get() == 5.0);
374   }
375 
376   return boost::report_errors();
377 }
378 
379