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 // <boost/thread/detail/invoke.hpp>
16
17 #include <boost/thread/detail/invoke.hpp>
18 #include <boost/detail/lightweight_test.hpp>
19
20 int count = 0;
21
22 // 1 arg, return void
23
f_void_1(int i)24 void f_void_1(int i)
25 {
26 count += i;
27 }
28
29 struct A_void_1
30 {
operator ()A_void_131 void operator()(int i)
32 {
33 count += i;
34 }
35
mem1A_void_136 void mem1() {++count;}
mem2A_void_137 void mem2() const {count += 2;}
38 };
39
40 void
test_void_1()41 test_void_1()
42 {
43 int save_count = count;
44 // function
45 {
46 boost::detail::invoke(f_void_1, 2);
47 BOOST_TEST(count == save_count + 2);
48 save_count = count;
49 }
50 // function pointer
51 {
52 void (*fp)(int) = f_void_1;
53 boost::detail::invoke(fp, 3);
54 BOOST_TEST(count == save_count+3);
55 save_count = count;
56 }
57 // functor
58 {
59 A_void_1 a0;
60 #if defined BOOST_THREAD_PROVIDES_INVOKE
61 boost::detail::invoke(a0, 4);
62 BOOST_TEST(count == save_count+4);
63 save_count = count;
64 #endif
65 boost::detail::invoke<void>(a0, 4);
66 BOOST_TEST(count == save_count+4);
67 save_count = count;
68 }
69 // member function pointer
70 {
71 #if defined BOOST_THREAD_PROVIDES_INVOKE
72 void (A_void_1::*fp)() = &A_void_1::mem1;
73 boost::detail::invoke(fp, A_void_1());
74 BOOST_TEST(count == save_count+1);
75 save_count = count;
76 //BUG
77 boost::detail::invoke<void>(fp, A_void_1());
78 BOOST_TEST(count == save_count+1);
79 save_count = count;
80
81 #endif
82 #if defined BOOST_THREAD_PROVIDES_INVOKE
83 A_void_1 a;
84 boost::detail::invoke(fp, &a);
85 BOOST_TEST(count == save_count+1);
86 save_count = count;
87 //BUG
88 boost::detail::invoke<int>(fp, &a);
89 BOOST_TEST(count == save_count+1);
90 save_count = count;
91
92 #endif
93 }
94 // const member function pointer
95 {
96 void (A_void_1::*fp)() const = &A_void_1::mem2;
97 boost::detail::invoke(fp, A_void_1());
98 BOOST_TEST(count == save_count+2);
99 save_count = count;
100 A_void_1 a;
101 boost::detail::invoke(fp, &a);
102 BOOST_TEST(count == save_count+2);
103 save_count = count;
104 }
105 }
106
107 // 1 arg, return int
108
f_int_1(int i)109 int f_int_1(int i)
110 {
111 return i + 1;
112 }
113
114 struct A_int_1
115 {
A_int_1A_int_1116 A_int_1() : data_(5) {}
operator ()A_int_1117 int operator()(int i)
118 {
119 return i - 1;
120 }
121
mem1A_int_1122 int mem1() {return 3;}
mem2A_int_1123 int mem2() const {return 4;}
124 int data_;
125 };
126
127 void
test_int_1()128 test_int_1()
129 {
130 // function
131 {
132 BOOST_TEST(boost::detail::invoke(f_int_1, 2) == 3);
133 }
134 // function pointer
135 {
136 int (*fp)(int) = f_int_1;
137 BOOST_TEST(boost::detail::invoke(fp, 3) == 4);
138 }
139 // functor
140 {
141 #if defined BOOST_THREAD_PROVIDES_INVOKE
142 BOOST_TEST(boost::detail::invoke(A_int_1(), 4) == 3);
143 BOOST_TEST(boost::detail::invoke<int>(A_int_1(), 4) == 3);
144 #endif
145 }
146 // member function pointer
147 {
148 #if defined BOOST_THREAD_PROVIDES_INVOKE
149 BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, A_int_1()) == 3);
150 BOOST_TEST(boost::detail::invoke<int>(&A_int_1::mem1, A_int_1()) == 3);
151 #endif
152
153 A_int_1 a;
154 BOOST_TEST(boost::detail::invoke(&A_int_1::mem1, &a) == 3);
155 }
156 // const member function pointer
157 {
158 BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, A_int_1()) == 4);
159 A_int_1 a;
160 BOOST_TEST(boost::detail::invoke(&A_int_1::mem2, &a) == 4);
161 }
162 // member data pointer
163 {
164 #if defined BOOST_THREAD_PROVIDES_INVOKE
165 BOOST_TEST(boost::detail::invoke(&A_int_1::data_, A_int_1()) == 5);
166 BOOST_TEST(boost::detail::invoke<int>(&A_int_1::data_, A_int_1()) == 5);
167 A_int_1 a;
168 BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 5);
169 boost::detail::invoke(&A_int_1::data_, a) = 6;
170 BOOST_TEST(boost::detail::invoke(&A_int_1::data_, a) == 6);
171 BOOST_TEST(boost::detail::invoke(&A_int_1::data_, &a) == 6);
172 boost::detail::invoke(&A_int_1::data_, &a) = 7;
173 BOOST_TEST(boost::detail::invoke(&A_int_1::data_, &a) == 7);
174 #endif
175 }
176 }
177
178 // 2 arg, return void
179
f_void_2(int i,int j)180 void f_void_2(int i, int j)
181 {
182 count += i+j;
183 }
184
185 struct A_void_2
186 {
operator ()A_void_2187 void operator()(int i, int j)
188 {
189 count += i+j;
190 }
191
mem1A_void_2192 void mem1(int i) {count += i;}
mem2A_void_2193 void mem2(int i) const {count += i;}
194 };
195
196 void
test_void_2()197 test_void_2()
198 {
199 int save_count = count;
200 // function
201 {
202 boost::detail::invoke(f_void_2, 2, 3);
203 BOOST_TEST(count == save_count+5);
204 save_count = count;
205 }
206 // member function pointer
207 {
208 #if defined BOOST_THREAD_PROVIDES_INVOKE
209 boost::detail::invoke(&A_void_2::mem1, A_void_2(), 3);
210 BOOST_TEST(count == save_count+3);
211 save_count = count;
212
213 boost::detail::invoke<void>(&A_void_2::mem1, A_void_2(), 3);
214 BOOST_TEST(count == save_count+3);
215 save_count = count;
216 #endif
217
218 }
219 }
220
main()221 int main()
222 {
223 test_void_1();
224 test_int_1();
225 test_void_2();
226 return boost::report_errors();
227 }
228