• 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 
17 // template <class Executor, class F, class... Args>
18 //     future<typename result_of<F(Args...)>::type>
19 //     async(Executor& ex, F&& f, Args&&... args);
20 
21 #define BOOST_THREAD_VERSION 5
22 #include <boost/config.hpp>
23 #if ! defined  BOOST_NO_CXX11_DECLTYPE
24 #define BOOST_RESULT_OF_USE_DECLTYPE
25 #endif
26 #include <iostream>
27 #include <boost/thread/future.hpp>
28 #include <boost/thread/thread.hpp>
29 #include <boost/thread/detail/memory.hpp>
30 #include <boost/thread/csbl/memory/unique_ptr.hpp>
31 #include <memory>
32 #include <boost/detail/lightweight_test.hpp>
33 #include <boost/thread/executors/basic_thread_pool.hpp>
34 #include <boost/thread/executor.hpp>
35 
36 typedef boost::chrono::high_resolution_clock Clock;
37 typedef boost::chrono::milliseconds ms;
38 
39 class A
40 {
41   long data_;
42 
43 public:
44   typedef long result_type;
45 
A(long i)46   explicit A(long i) :
47     data_(i)
48   {
49   }
50 
doit() const51   long doit() const
52   {
53     boost::this_thread::sleep_for(ms(200));
54     return data_;
55   }
operator ()() const56   long operator()() const
57   {
58     boost::this_thread::sleep_for(ms(200));
59     return data_;
60   }
61 };
62 
63 class MoveOnly
64 {
65 public:
66   typedef int result_type;
67 
68   int value;
69 
70 BOOST_THREAD_MOVABLE_ONLY(MoveOnly)
MoveOnly()71   MoveOnly()
72   {
73     value = 0;
74   }
MoveOnly(BOOST_THREAD_RV_REF (MoveOnly))75   MoveOnly( BOOST_THREAD_RV_REF(MoveOnly))
76       {
77         value = 1;
78       }
operator =(BOOST_THREAD_RV_REF (MoveOnly))79       MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly))
80       {
81         value = 2;
82         return *this;
83       }
84 
operator ()()85       int operator()()
86       {
87         boost::this_thread::sleep_for(ms(200));
88         return 3;
89       }
90       template <typename OS>
operator <<(OS & os,MoveOnly const & v)91       friend OS& operator<<(OS& os, MoveOnly const& v)
92       {
93         os << v.value;
94         return os;
95       }
96     };
97 
98     namespace boost
99     {
100 BOOST_THREAD_DCL_MOVABLE    (MoveOnly)
101   }
102 
f0()103 int f0()
104 {
105   boost::this_thread::sleep_for(ms(200));
106   return 3;
107 }
108 
109 int i = 0;
110 
f1()111 int& f1()
112 {
113   boost::this_thread::sleep_for(ms(200));
114   return i;
115 }
116 
f2()117 void f2()
118 {
119   boost::this_thread::sleep_for(ms(200));
120 }
121 
f3_0()122 boost::csbl::unique_ptr<int> f3_0()
123 {
124   boost::this_thread::sleep_for(ms(200));
125   boost::csbl::unique_ptr<int> r( (new int(3)));
126   return boost::move(r);
127 }
f3_1()128 MoveOnly f3_1()
129 {
130   boost::this_thread::sleep_for(ms(200));
131   MoveOnly r;
132   return boost::move(r);
133 }
134 
f3(int i)135 boost::csbl::unique_ptr<int> f3(int i)
136 {
137   boost::this_thread::sleep_for(ms(200));
138   return boost::csbl::unique_ptr<int>(new int(i));
139 }
140 
f4(BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p)141 boost::csbl::unique_ptr<int> f4(
142     BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p
143 )
144 {
145   boost::this_thread::sleep_for(ms(200));
146   return boost::move(p);
147 }
148 
149 struct check_timer {
150   boost::chrono::nanoseconds delay;
151   Clock::time_point start;
check_timercheck_timer152   check_timer(boost::chrono::nanoseconds delay)
153   : delay(delay)
154   , start(Clock::now())
155   {
156   }
~check_timercheck_timer157   ~check_timer() {
158     Clock::time_point now = Clock::now();
159     BOOST_TEST(now - start < delay);
160     std::cout << __FILE__ << "[" << __LINE__ << "] " << (now - start).count() << std::endl;
161   }
162 
163 };
164 
main()165 int main()
166 {
167   std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
168 #if defined BOOST_THREAD_PROVIDES_EXECUTORS
169   {
170     try
171     {
172       boost::executor_adaptor<boost::basic_thread_pool> ex(1);
173       boost::future<int> f = boost::async(ex, &f0);
174       boost::this_thread::sleep_for(ms(300));
175       int res;
176       {
177         check_timer timer(ms(500));
178         res = f.get();
179       }
180       BOOST_TEST(res == 3);
181     }
182     catch (std::exception& ex)
183     {
184       std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
185       BOOST_TEST(false && "exception thrown");
186     }
187     catch (...)
188     {
189       BOOST_TEST(false && "exception thrown");
190     }
191   }
192 #endif
193 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS
194   std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
195   {
196     try
197     {
198       boost::executor_adaptor<boost::basic_thread_pool> ex(1);
199       boost::future<long> f = boost::async(ex, A(3));
200       boost::this_thread::sleep_for(ms(300));
201       int res;
202       {
203         check_timer timer(ms(500));
204         res = f.get();
205       }
206       BOOST_TEST(res == 3);
207     }
208     catch (std::exception& ex)
209     {
210       std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
211       BOOST_TEST(false && "exception thrown");
212     }
213     catch (...)
214     {
215       BOOST_TEST(false && "exception thrown");
216     }
217 
218   }
219 #endif
220 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS
221   std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl;
222   {
223     try
224     {
225       boost::executor_adaptor<boost::basic_thread_pool> ex(1);
226       MoveOnly mo;
227       boost::future<int> f = boost::async(ex, boost::move(mo));
228       //boost::future<int> f = boost::async(ex, MoveOnly());
229       boost::this_thread::sleep_for(ms(300));
230       int res;
231       {
232         check_timer timer(ms(500));
233         res = f.get();
234       }
235       BOOST_TEST(res == 3);
236     }
237     catch (std::exception& ex)
238     {
239       std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl;
240       BOOST_TEST(false && "exception thrown");
241     }
242     catch (...)
243     {
244       BOOST_TEST(false && "exception thrown");
245     }
246   }
247 #endif
248 
249   return boost::report_errors();
250 }
251