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) 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 
16 // <boost/thread/detail/invoke.hpp>
17 
18 #include <boost/thread/detail/invoke.hpp>
19 #include <boost/detail/lightweight_test.hpp>
20 
21 int count = 0;
22 
23 // 1 arg, return void
24 
f_void_1(int i)25 void f_void_1(int i)
26 {
27     count += i;
28 }
29 
30 struct A_void_1
31 {
operator ()A_void_132     void operator()(int i)
33     {
34         count += i;
35     }
36 
mem1A_void_137     void mem1() {++count;}
mem2A_void_138     void mem2() const {count += 2;}
39 };
40 
41 void
test_void_1()42 test_void_1()
43 {
44     int save_count = count;
45     // function
46 #if defined BOOST_THREAD_PROVIDES_INVOKE
47     {
48     int i = 2;
49     boost::detail::invoke(f_void_1, i);
50     BOOST_TEST(count == save_count + 2);
51     save_count = count;
52     }
53 #endif
54     {
55     int i = 2;
56     boost::detail::invoke<void>(f_void_1, i);
57     BOOST_TEST(count == save_count + 2);
58     save_count = count;
59     }
60     // function pointer
61 #if defined BOOST_THREAD_PROVIDES_INVOKE
62     {
63     void (*fp)(int) = f_void_1;
64     int i = 3;
65     boost::detail::invoke(fp, i);
66     BOOST_TEST(count == save_count+3);
67     save_count = count;
68     }
69 #endif
70     {
71     void (*fp)(int) = f_void_1;
72     int i = 3;
73     boost::detail::invoke<void>(fp, i);
74     BOOST_TEST(count == save_count+3);
75     save_count = count;
76     }
77 #if defined BOOST_THREAD_PROVIDES_INVOKE
78     {
79     void (*fp)(int) = f_void_1;
80     int i = 3;
81     boost::detail::invoke(fp, i);
82     BOOST_TEST(count == save_count+3);
83     save_count = count;
84     }
85 #endif
86     {
87     void (*fp)(int) = f_void_1;
88     int i = 3;
89     boost::detail::invoke<void>(fp, i);
90     BOOST_TEST(count == save_count+3);
91     save_count = count;
92     }
93     // functor
94 #if defined BOOST_THREAD_PROVIDES_INVOKE
95     {
96     A_void_1 a0;
97     int i = 4;
98     boost::detail::invoke(a0, i);
99     BOOST_TEST(count == save_count+4);
100     save_count = count;
101     }
102 #endif
103     {
104     A_void_1 a0;
105     int i = 4;
106     boost::detail::invoke<void>(a0, i);
107     BOOST_TEST(count == save_count+4);
108     save_count = count;
109     }
110     // member function pointer
111 #if defined BOOST_THREAD_PROVIDES_INVOKE
112     {
113     void (A_void_1::*fp)() = &A_void_1::mem1;
114     A_void_1 a;
115     boost::detail::invoke(fp, a);
116     BOOST_TEST(count == save_count+1);
117     save_count = count;
118     A_void_1* ap = &a;
119     boost::detail::invoke(fp, ap);
120     BOOST_TEST(count == save_count+1);
121     save_count = count;
122     }
123 #endif
124     {
125     void (A_void_1::*fp)() = &A_void_1::mem1;
126     A_void_1 a;
127     boost::detail::invoke<void>(fp, a);
128     BOOST_TEST(count == save_count+1);
129     save_count = count;
130     A_void_1* ap = &a;
131     boost::detail::invoke<void>(fp, ap);
132     BOOST_TEST(count == save_count+1);
133     save_count = count;
134     }
135     // const member function pointer
136 #if defined BOOST_THREAD_PROVIDES_INVOKE
137     {
138     void (A_void_1::*fp)() const = &A_void_1::mem2;
139     A_void_1 a;
140     boost::detail::invoke(fp, a);
141     BOOST_TEST(count == save_count+2);
142     save_count = count;
143     A_void_1* ap = &a;
144     boost::detail::invoke(fp, ap);
145     BOOST_TEST(count == save_count+2);
146     save_count = count;
147     }
148 #endif
149     {
150     void (A_void_1::*fp)() const = &A_void_1::mem2;
151     A_void_1 a;
152     boost::detail::invoke<void>(fp, a);
153     BOOST_TEST(count == save_count+2);
154     save_count = count;
155     A_void_1* ap = &a;
156     boost::detail::invoke<void>(fp, ap);
157     BOOST_TEST(count == save_count+2);
158     save_count = count;
159     }
160 }
161 
162 // 1 arg, return int
163 
f_int_1(int i)164 int f_int_1(int i)
165 {
166     return i + 1;
167 }
168 
169 struct A_int_1
170 {
A_int_1A_int_1171     A_int_1() : data_(5) {}
operator ()A_int_1172     int operator()(int i)
173     {
174         return i - 1;
175     }
176 
mem1A_int_1177     int mem1() {return 3;}
mem2A_int_1178     int mem2() const {return 4;}
179     int data_;
180 };
181 
182 void
test_int_1()183 test_int_1()
184 {
185     // function
186     {
187     int i = 2;
188 #if defined BOOST_THREAD_PROVIDES_INVOKE
189     BOOST_TEST(boost::detail::invoke(f_int_1, i) == 3);
190 #endif
191     BOOST_TEST(boost::detail::invoke<int>(f_int_1, i) == 3);
192     }
193     // function pointer
194     {
195     int (*fp)(int) = f_int_1;
196     int i = 3;
197 #if defined BOOST_THREAD_PROVIDES_INVOKE
198     BOOST_TEST(boost::detail::invoke(fp, i) == 4);
199 #endif
200     BOOST_TEST(boost::detail::invoke<int>(fp, i) == 4);
201     }
202     // functor
203     {
204     int i = 4;
205 #if defined BOOST_THREAD_PROVIDES_INVOKE
206     BOOST_TEST(boost::detail::invoke(A_int_1(), i) == 3);
207 #endif
208     const A_int_1 ca;
209     A_int_1 a;
210     BOOST_TEST(boost::detail::invoke<int>(a, i) == 3);
211     //BOOST_TEST(boost::detail::invoke<int>(ca, i) == 3);
212 #if defined BOOST_THREAD_PROVIDES_INVOKE
213     BOOST_TEST(boost::detail::invoke<int>(A_int_1(), i) == 3);
214 #endif
215     }
216     // member function pointer
217     {
218     A_int_1 a;
219 #if defined BOOST_THREAD_PROVIDES_INVOKE
220     BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, a) == 3);
221 #endif
222     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, a) == 3);
223     A_int_1* ap = &a;
224 #if defined BOOST_THREAD_PROVIDES_INVOKE
225     BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, ap) == 3);
226 #endif
227     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, ap) == 3);
228     }
229     // const member function pointer
230     {
231     A_int_1 a;
232 #if defined BOOST_THREAD_PROVIDES_INVOKE
233     BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, A_int_1()) == 4);
234 #endif
235     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, A_int_1()) == 4);
236     A_int_1* ap = &a;
237 #if defined BOOST_THREAD_PROVIDES_INVOKE
238     BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, ap) == 4);
239 #endif
240     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem2, ap) == 4);
241     }
242     // member data pointer
243     {
244     A_int_1 a;
245 #if defined BOOST_THREAD_PROVIDES_INVOKE
246     BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 5);
247 
248     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 5);
249 
250 #endif
251 #if defined BOOST_THREAD_PROVIDES_INVOKE
252     A_int_1* ap = &a;
253 
254     boost::detail::invoke(&A_int_1::data_, a) = 6;
255     BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 6);
256 
257     boost::detail::invoke<int>(&A_int_1::data_, a) = 6;
258     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, a) == 6);
259 
260 #endif
261 
262 #if defined BOOST_THREAD_PROVIDES_INVOKE
263     BOOST_TEST(boost::detail::invoke(&A_int_1::data_, ap) == 6);
264     boost::detail::invoke(&A_int_1::data_, ap) = 7;
265     BOOST_TEST(boost::detail::invoke(&A_int_1::data_, ap) == 7);
266 
267     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 7);
268     boost::detail::invoke<int>(&A_int_1::data_, ap) = 8;
269     BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, ap) == 8);
270 #endif
271 
272     }
273 }
274 
275 // 2 arg, return void
276 
f_void_2(int i,int j)277 void f_void_2(int i, int j)
278 {
279     count += i+j;
280 }
281 
282 struct A_void_2
283 {
operator ()A_void_2284     void operator()(int i, int j)
285     {
286         count += i+j;
287     }
288 
mem1A_void_2289     void mem1(int i) {count += i;}
mem2A_void_2290     void mem2(int i) const {count += i;}
291 };
292 
293 void
test_void_2()294 test_void_2()
295 {
296     int save_count = count;
297     // function
298     {
299     int i = 2;
300     int j = 3;
301 #if defined BOOST_THREAD_PROVIDES_INVOKE
302     boost::detail::invoke(f_void_2, i, j);
303     BOOST_TEST(count == save_count+5);
304     save_count = count;
305 #endif
306     boost::detail::invoke<void>(f_void_2, i, j);
307     BOOST_TEST(count == save_count+5);
308     save_count = count;
309     }
310     // member function pointer
311     {
312 #if defined BOOST_THREAD_PROVIDES_INVOKE
313       int j = 3;
314     boost::detail::invoke(&A_void_2::mem1, A_void_2(), j);
315     BOOST_TEST(count == save_count+3);
316     save_count = count;
317 
318     boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), j);
319     BOOST_TEST(count == save_count+3);
320     save_count = count;
321 #endif
322 //    A_void_2 a2;
323 //    boost::detail::invoke<void>(&A_void_2::mem1, a2, j);
324 //    BOOST_TEST(count == save_count+3);
325 //    save_count = count;
326     }
327 }
328 
main()329 int main()
330 {
331     test_void_1();
332     test_int_1();
333     test_void_2();
334     return boost::report_errors();
335 
336 }
337