1 // Copyright (C) 2007-8 Anthony Williams
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 3
7 #define BOOST_TEST_MODULE Boost.Threads: thread launching test suite
8
9 #include <boost/thread/thread_only.hpp>
10 #include <boost/test/unit_test.hpp>
11 #include <boost/ref.hpp>
12 #include <boost/utility.hpp>
13 #include <string>
14 #include <vector>
15
16 bool normal_function_called=false;
17
normal_function()18 void normal_function()
19 {
20 normal_function_called=true;
21 }
22
BOOST_AUTO_TEST_CASE(test_thread_function_no_arguments)23 BOOST_AUTO_TEST_CASE(test_thread_function_no_arguments)
24 {
25 boost::thread function(&normal_function);
26 function.join();
27 BOOST_CHECK(normal_function_called);
28 }
29
30 int nfoa_res=0;
31
normal_function_one_arg(int i)32 void normal_function_one_arg(int i)
33 {
34 nfoa_res=i;
35 }
36
BOOST_AUTO_TEST_CASE(test_thread_function_one_argument)37 BOOST_AUTO_TEST_CASE(test_thread_function_one_argument)
38 {
39 boost::thread function(&normal_function_one_arg,42);
40 function.join();
41 BOOST_CHECK_EQUAL(42,nfoa_res);
42 }
43
44 struct callable_no_args
45 {
46 static bool called;
47
operator ()callable_no_args48 void operator()() const
49 {
50 called=true;
51 }
52 };
53
54 bool callable_no_args::called=false;
55
BOOST_AUTO_TEST_CASE(test_thread_callable_object_no_arguments)56 BOOST_AUTO_TEST_CASE(test_thread_callable_object_no_arguments)
57 {
58 callable_no_args func;
59 boost::thread callable(func);
60 callable.join();
61 BOOST_CHECK(callable_no_args::called);
62 }
63
64 struct callable_noncopyable_no_args:
65 boost::noncopyable
66 {
callable_noncopyable_no_argscallable_noncopyable_no_args67 callable_noncopyable_no_args() : boost::noncopyable() {}
68 static bool called;
69
operator ()callable_noncopyable_no_args70 void operator()() const
71 {
72 called=true;
73 }
74 };
75
76 bool callable_noncopyable_no_args::called=false;
77
BOOST_AUTO_TEST_CASE(test_thread_callable_object_ref_no_arguments)78 BOOST_AUTO_TEST_CASE(test_thread_callable_object_ref_no_arguments)
79 {
80 callable_noncopyable_no_args func;
81
82 boost::thread callable(boost::ref(func));
83 callable.join();
84 BOOST_CHECK(callable_noncopyable_no_args::called);
85 }
86
87 struct callable_one_arg
88 {
89 static bool called;
90 static int called_arg;
91
operator ()callable_one_arg92 void operator()(int arg) const
93 {
94 called=true;
95 called_arg=arg;
96 }
97 };
98
99 bool callable_one_arg::called=false;
100 int callable_one_arg::called_arg=0;
101
BOOST_AUTO_TEST_CASE(test_thread_callable_object_one_argument)102 BOOST_AUTO_TEST_CASE(test_thread_callable_object_one_argument)
103 {
104 callable_one_arg func;
105 boost::thread callable(func,42);
106 callable.join();
107 BOOST_CHECK(callable_one_arg::called);
108 BOOST_CHECK_EQUAL(callable_one_arg::called_arg,42);
109 }
110
111 struct callable_multiple_arg
112 {
113 static bool called_two;
114 static int called_two_arg1;
115 static double called_two_arg2;
116 static bool called_three;
117 static std::string called_three_arg1;
118 static std::vector<int> called_three_arg2;
119 static int called_three_arg3;
120
operator ()callable_multiple_arg121 void operator()(int arg1,double arg2) const
122 {
123 called_two=true;
124 called_two_arg1=arg1;
125 called_two_arg2=arg2;
126 }
operator ()callable_multiple_arg127 void operator()(std::string const& arg1,std::vector<int> const& arg2,int arg3) const
128 {
129 called_three=true;
130 called_three_arg1=arg1;
131 called_three_arg2=arg2;
132 called_three_arg3=arg3;
133 }
134 };
135
136 bool callable_multiple_arg::called_two=false;
137 bool callable_multiple_arg::called_three=false;
138 int callable_multiple_arg::called_two_arg1;
139 double callable_multiple_arg::called_two_arg2;
140 std::string callable_multiple_arg::called_three_arg1;
141 std::vector<int> callable_multiple_arg::called_three_arg2;
142 int callable_multiple_arg::called_three_arg3;
143
BOOST_AUTO_TEST_CASE(test_thread_callable_object_multiple_arguments)144 BOOST_AUTO_TEST_CASE(test_thread_callable_object_multiple_arguments)
145 {
146 std::vector<int> x;
147 for(unsigned i=0;i<7;++i)
148 {
149 x.push_back(i*i);
150 }
151
152 callable_multiple_arg func;
153 // Avoid
154 // boost/bind/bind.hpp(392) : warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data
155
156 boost::thread callable3(func,"hello",x,1);
157 callable3.join();
158 BOOST_CHECK(callable_multiple_arg::called_three);
159 BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg1,"hello");
160 BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.size(),x.size());
161 for(unsigned j=0;j<x.size();++j)
162 {
163 BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg2.at(j),x[j]);
164 }
165
166 BOOST_CHECK_EQUAL(callable_multiple_arg::called_three_arg3,1);
167
168 double const dbl=1.234;
169
170 boost::thread callable2(func,19,dbl);
171 callable2.join();
172 BOOST_CHECK(callable_multiple_arg::called_two);
173 BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg1,19);
174 BOOST_CHECK_EQUAL(callable_multiple_arg::called_two_arg2,dbl);
175 }
176
177 struct X
178 {
179 bool function_called;
180 int arg_value;
181
XX182 X():
183 function_called(false),
184 arg_value(0)
185 {}
186
187
f0X188 void f0()
189 {
190 function_called=true;
191 }
192
f1X193 void f1(int i)
194 {
195 arg_value=i;
196 }
197
198 };
199
BOOST_AUTO_TEST_CASE(test_thread_member_function_no_arguments)200 BOOST_AUTO_TEST_CASE(test_thread_member_function_no_arguments)
201 {
202 X x;
203
204 boost::thread function(&X::f0,&x);
205 function.join();
206 BOOST_CHECK(x.function_called);
207 }
208
209
BOOST_AUTO_TEST_CASE(test_thread_member_function_one_argument)210 BOOST_AUTO_TEST_CASE(test_thread_member_function_one_argument)
211 {
212 X x;
213 boost::thread function(&X::f1,&x,42);
214 function.join();
215 BOOST_CHECK_EQUAL(42,x.arg_value);
216 }
217