1 // Copyright (C) 2014 Vicente Botet
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #define BOOST_THREAD_VERSION 4
7     #include <iostream>
8     #include <fstream>
9     #include <stdio.h>
10     #include <boost/function.hpp>
11     #include <boost/make_shared.hpp>
12     #include <boost/shared_ptr.hpp>
13     #include <boost/bind.hpp>
14     #include <boost/asio.hpp>
15     #include <boost/thread.hpp>
16     #include <boost/thread/future.hpp>
17 
18 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
19     #define EXAMPLE_1
20     #define EXAMPLE_2
21     #define EXAMPLE_3
22     #define EXAMPLE_4
23     #define EXAMPLE_5
24     #define EXAMPLE_6
25     #define EXAMPLE_7
26 #else
27     #define EXAMPLE_1
28     #define EXAMPLE_2
29     //#define EXAMPLE_3
30     //#define EXAMPLE_4
31     //#define EXAMPLE_5
32     //#define EXAMPLE_6
33     //#define EXAMPLE_7
34 #endif
35 
36     // Test functions
37 
int_no_params()38     int int_no_params()
39     {
40         return 42;
41     }
42 
int_with_params(int i)43     int int_with_params(int i)
44     {
45         return i;
46     }
47 
string_no_params()48     std::string string_no_params()
49     {
50         return std::string("forty two");
51     }
52 
string_with_params(std::string & ans)53     std::string string_with_params(std::string& ans)
54     {
55         return ans;
56     }
57 
main(int,char **)58     int main(int /*argc*/, char ** /*argv[]*/)
59     {
60         std::string ans("forty two");
61 
62     #if defined EXAMPLE_1
63         //! Compiles and produces correct result.
64         {
65             boost::packaged_task<int()> example(int_no_params);
66             boost::future<int> f = example.get_future();
67             boost::thread task(boost::move(example));
68             int answer = f.get();
69             std::cout << "Answer to life and whatnot, in English: " << answer << std::endl;
70             task.join();
71         }
72     #endif
73 
74     #if defined EXAMPLE_2
75         //! Compiles and produces correct result.
76         {
77             boost::packaged_task<std::string()> example(string_no_params);
78             boost::future<std::string> f = example.get_future();
79             boost::thread task(boost::move(example));
80             std::string answer = f.get();
81             std::cout << "string_no_params: " << answer << std::endl;
82             task.join();
83         }
84 
85     #endif
86 
87     #if defined EXAMPLE_3
88         //! Doesn't compile in C++03.
89         //! error: variable �boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)> example� has initializer but incomplete type
90 
91         {
92             boost::packaged_task<std::string(std::string&)> example(string_with_params);
93             boost::future<std::string> f = example.get_future();
94             example(ans);
95             std::string answer = f.get();
96             std::cout << "string_with_params: " << answer << std::endl;
97         }
98 
99     #endif
100 
101     #if defined EXAMPLE_4
102         //! Doesn't compile in C++11
103 //        In file included from test_9303.cpp:10:
104 //        In file included from ../../../boost/thread.hpp:13:
105 //        In file included from ../../../boost/thread/thread.hpp:12:
106 //        In file included from ../../../boost/thread/thread_only.hpp:22:
107 //        ../../../boost/thread/detail/thread.hpp:76:15: error: no matching function for call to 'invoke'
108 //                      invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...);
109 //                      ^~~~~~
110 
111         {
112             boost::packaged_task<std::string(std::string&)> example(string_with_params);
113             boost::future<std::string> f = example.get_future();
114             boost::thread task(boost::move(example), boost::ref(ans));
115             std::string answer = f.get();
116             std::cout << "string_with_params: " << answer << std::endl;
117             task.join();
118         }
119     #endif
120 
121     #if defined EXAMPLE_5
122         //! Doesn't compile in C++03, C++11 only.
123         //! error: extended initializer lists only available with -std=c++11 or -std=gnu++11 [-Werror]
124         {
125             boost::packaged_task<std::string(std::string&)> example
126             { boost::bind(&string_with_params, ans) };
127             boost::future<std::string> f = example.get_future();
128             boost::thread task(boost::move(example), boost::ref(ans));
129             std::string answer = f.get();
130             std::cout << "string_with_params: " << answer << std::endl;
131             task.join();
132         }
133     #endif
134 
135     #if defined EXAMPLE_6
136         //! Doesn't compile in C++03, C++11 only.
137         // packagedTestTest.cpp:94:43: error: invalid use of incomplete type ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
138         // packagedTestTest.cpp:95:37: error: incomplete type ‘task_t {aka boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>}’ used in nested name specifier
139         // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
140         {
141           //typedef boost::packaged_task<std::string(std::string&)> task_t;
142           typedef boost::packaged_task<std::string()> task_t;
143             boost::shared_ptr<task_t> example = boost::make_shared<task_t>(boost::bind(&string_with_params, boost::ref(ans)));
144             boost::future<std::string> f = example->get_future();
145             boost::thread task(boost::bind(&task_t::operator(), example));
146             std::string answer = f.get();
147             std::cout << "string_with_params: " << answer << std::endl;
148             task.join();
149         }
150     #endif
151 
152     #if defined EXAMPLE_7
153         //! Doesn't compile in C++03, C++11 only.
154         // packagedTestTest.cpp:94:43: error: invalid use of incomplete type ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
155         // packagedTestTest.cpp:95:37: error: incomplete type ‘task_t {aka boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>}’ used in nested name specifier
156         // boost/thread/future.hpp:1320:11: error: declaration of ‘class boost::packaged_task<std::basic_string<char>(std::basic_string<char>&)>’
157         {
158             boost::asio::io_service io_service;
159             boost::thread_group threads;
160             boost::asio::io_service::work work(io_service);
161 
162             for (int i = 0; i < 3; ++i)
163             {
164                 threads.create_thread(boost::bind(&boost::asio::io_service::run,
165                     &io_service));
166             }
167             typedef boost::packaged_task<std::string()> task_t;
168             boost::shared_ptr<task_t> example = boost::make_shared<task_t>(boost::bind(&string_with_params, ans));
169             boost::future<std::string> f = example->get_future();
170             io_service.post(boost::bind(&task_t::operator(), example));
171             std::string answer = f.get();
172             std::cout << "string_with_params: " << answer << std::endl;
173             threads.join_all();
174         }
175     #endif
176         return 0;
177     }
178