]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright Daniel Wallin 2006. Use, modification and distribution is |
2 | // subject to the Boost Software License, Version 1.0. (See accompanying | |
3 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
4 | ||
5 | #include <boost/parameter/preprocessor.hpp> | |
6 | #include <boost/parameter/keyword.hpp> | |
7 | #include <boost/type_traits/is_const.hpp> | |
8 | #include <string> | |
9 | #include "basics.hpp" | |
10 | ||
11 | #ifndef BOOST_NO_SFINAE | |
12 | # include <boost/utility/enable_if.hpp> | |
13 | #endif | |
14 | ||
15 | namespace test { | |
16 | ||
17 | BOOST_PARAMETER_BASIC_FUNCTION((int), f, tag, | |
18 | (required | |
19 | (tester, *) | |
20 | (name, *) | |
21 | ) | |
22 | (optional | |
23 | (value, *) | |
24 | (out(index), (int)) | |
25 | ) | |
26 | ) | |
27 | { | |
28 | typedef typename boost::parameter::binding< | |
29 | Args, tag::index, int& | |
30 | >::type index_type; | |
31 | ||
32 | BOOST_MPL_ASSERT((boost::is_same<index_type, int&>)); | |
33 | ||
34 | args[tester]( | |
35 | args[name] | |
36 | , args[value | 1.f] | |
37 | , args[index | 2] | |
38 | ); | |
39 | ||
40 | return 1; | |
41 | } | |
42 | ||
43 | BOOST_PARAMETER_BASIC_FUNCTION((int), g, tag, | |
44 | (required | |
45 | (tester, *) | |
46 | (name, *) | |
47 | ) | |
48 | (optional | |
49 | (value, *) | |
50 | (out(index), (int)) | |
51 | ) | |
52 | ) | |
53 | { | |
54 | typedef typename boost::parameter::binding< | |
55 | Args, tag::index, int const& | |
56 | >::type index_type; | |
57 | ||
58 | BOOST_MPL_ASSERT((boost::is_same<index_type, int const&>)); | |
59 | ||
60 | args[tester]( | |
61 | args[name] | |
62 | , args[value | 1.f] | |
63 | , args[index | 2] | |
64 | ); | |
65 | ||
66 | return 1; | |
67 | } | |
68 | ||
69 | BOOST_PARAMETER_FUNCTION((int), h, tag, | |
70 | (required | |
71 | (tester, *) | |
72 | (name, *) | |
73 | ) | |
74 | (optional | |
75 | (value, *, 1.f) | |
76 | (out(index), (int), 2) | |
77 | ) | |
78 | ) | |
79 | { | |
80 | # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ | |
81 | && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
82 | BOOST_MPL_ASSERT((boost::is_same<index_type, int>)); | |
83 | # endif | |
84 | ||
85 | tester( | |
86 | name | |
87 | , value | |
88 | , index | |
89 | ); | |
90 | ||
91 | return 1; | |
92 | } | |
93 | ||
94 | BOOST_PARAMETER_FUNCTION((int), h2, tag, | |
95 | (required | |
96 | (tester, *) | |
97 | (name, *) | |
98 | ) | |
99 | (optional | |
100 | (value, *, 1.f) | |
101 | (out(index), (int), (int)value * 2) | |
102 | ) | |
103 | ) | |
104 | { | |
105 | # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \ | |
106 | && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) | |
107 | BOOST_MPL_ASSERT((boost::is_same<index_type, int>)); | |
108 | # endif | |
109 | ||
110 | tester( | |
111 | name | |
112 | , value | |
113 | , index | |
114 | ); | |
115 | ||
116 | return 1; | |
117 | } | |
118 | ||
119 | struct base | |
120 | { | |
121 | template <class Args> | |
122 | base(Args const& args) | |
123 | { | |
124 | args[tester]( | |
125 | args[name] | |
126 | , args[value | 1.f] | |
127 | , args[index | 2] | |
128 | ); | |
129 | } | |
130 | }; | |
131 | ||
132 | struct class_ : base | |
133 | { | |
134 | BOOST_PARAMETER_CONSTRUCTOR(class_, (base), tag, | |
135 | (required | |
136 | (tester, *) | |
137 | (name, *) | |
138 | ) | |
139 | (optional | |
140 | (value, *) | |
141 | (index, *) | |
142 | ) | |
143 | ) | |
144 | ||
145 | BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag, | |
146 | (required | |
147 | (tester, *) | |
148 | (name, *) | |
149 | ) | |
150 | (optional | |
151 | (value, *) | |
152 | (index, *) | |
153 | ) | |
154 | ) | |
155 | { | |
156 | args[tester]( | |
157 | args[name] | |
158 | , args[value | 1.f] | |
159 | , args[index | 2] | |
160 | ); | |
161 | ||
162 | return 1; | |
163 | } | |
164 | ||
165 | BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, tag, | |
166 | (required | |
167 | (tester, *) | |
168 | (name, *) | |
169 | ) | |
170 | (optional | |
171 | (value, *) | |
172 | (index, *) | |
173 | ) | |
174 | ) | |
175 | { | |
176 | args[tester]( | |
177 | args[name] | |
178 | , args[value | 1.f] | |
179 | , args[index | 2] | |
180 | ); | |
181 | ||
182 | return 1; | |
183 | } | |
184 | ||
185 | BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, tag, | |
186 | (required | |
187 | (tester, *) | |
188 | (name, *) | |
189 | ) | |
190 | (optional | |
191 | (value, *, 1.f) | |
192 | (index, *, 2) | |
193 | ) | |
194 | ) | |
195 | { | |
196 | tester(name, value, index); | |
197 | return 1; | |
198 | } | |
199 | ||
200 | BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, tag, | |
201 | (required | |
202 | (tester, *) | |
203 | (name, *) | |
204 | ) | |
205 | (optional | |
206 | (value, *, 1.f) | |
207 | (index, *, 2) | |
208 | ) | |
209 | ) | |
210 | { | |
211 | tester(name, value, index); | |
212 | return 1; | |
213 | } | |
214 | ||
215 | ||
216 | BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, tag, | |
217 | (required | |
218 | (tester, *) | |
219 | (name, *) | |
220 | ) | |
221 | (optional | |
222 | (value, *, 1.f) | |
223 | (index, *, 2) | |
224 | ) | |
225 | ) | |
226 | { | |
227 | tester(name, value, index); | |
228 | return 1; | |
229 | } | |
230 | }; | |
231 | ||
232 | BOOST_PARAMETER_FUNCTION( | |
233 | (int), sfinae, tag, | |
234 | (required | |
235 | (name, (std::string)) | |
236 | ) | |
237 | ) | |
238 | { | |
239 | return 1; | |
240 | } | |
241 | ||
242 | #ifndef BOOST_NO_SFINAE | |
243 | // On compilers that actually support SFINAE, add another overload | |
244 | // that is an equally good match and can only be in the overload set | |
245 | // when the others are not. This tests that the SFINAE is actually | |
246 | // working. On all other compilers we're just checking that | |
247 | // everything about SFINAE-enabled code will work, except of course | |
248 | // the SFINAE. | |
249 | template<class A0> | |
250 | typename boost::enable_if<boost::is_same<int,A0>, int>::type | |
251 | sfinae(A0 const& a0) | |
252 | { | |
253 | return 0; | |
254 | } | |
255 | #endif | |
256 | ||
257 | #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) | |
258 | ||
259 | // Sun has problems with this syntax: | |
260 | // | |
261 | // template1< r* ( template2<x> ) > | |
262 | // | |
263 | // Workaround: factor template2<x> into a separate typedef | |
264 | typedef boost::is_convertible<boost::mpl::_, std::string> predicate; | |
265 | ||
266 | BOOST_PARAMETER_FUNCTION( | |
267 | (int), sfinae1, tag, | |
268 | (required | |
269 | (name, *(predicate)) | |
270 | ) | |
271 | ) | |
272 | { | |
273 | return 1; | |
274 | } | |
275 | ||
276 | #else | |
277 | ||
278 | BOOST_PARAMETER_FUNCTION( | |
279 | (int), sfinae1, tag, | |
280 | (required | |
281 | (name, *(boost::is_convertible<boost::mpl::_, std::string>)) | |
282 | ) | |
283 | ) | |
284 | { | |
285 | return 1; | |
286 | } | |
287 | #endif | |
288 | ||
289 | #ifndef BOOST_NO_SFINAE | |
290 | // On compilers that actually support SFINAE, add another overload | |
291 | // that is an equally good match and can only be in the overload set | |
292 | // when the others are not. This tests that the SFINAE is actually | |
293 | // working. On all other compilers we're just checking that | |
294 | // everything about SFINAE-enabled code will work, except of course | |
295 | // the SFINAE. | |
296 | template<class A0> | |
297 | typename boost::enable_if<boost::is_same<int,A0>, int>::type | |
298 | sfinae1(A0 const& a0) | |
299 | { | |
300 | return 0; | |
301 | } | |
302 | #endif | |
303 | ||
304 | template <class T> | |
305 | T const& as_lvalue(T const& x) | |
306 | { | |
307 | return x; | |
308 | } | |
309 | ||
310 | struct udt | |
311 | { | |
312 | udt(int foo, int bar) | |
313 | : foo(foo) | |
314 | , bar(bar) | |
315 | {} | |
316 | ||
317 | int foo; | |
318 | int bar; | |
319 | }; | |
320 | ||
321 | BOOST_PARAMETER_FUNCTION((int), lazy_defaults, tag, | |
322 | (required | |
323 | (name, *) | |
324 | ) | |
325 | (optional | |
326 | (value, *, name.foo) | |
327 | (index, *, name.bar) | |
328 | ) | |
329 | ) | |
330 | { | |
331 | return 0; | |
332 | } | |
333 | ||
334 | } // namespace test | |
335 | ||
336 | int main() | |
337 | { | |
338 | using namespace test; | |
339 | ||
340 | f( | |
341 | values(S("foo"), 1.f, 2) | |
342 | , S("foo") | |
343 | ); | |
344 | ||
345 | f( | |
346 | tester = values(S("foo"), 1.f, 2) | |
347 | , name = S("foo") | |
348 | ); | |
349 | ||
350 | int index_lvalue = 2; | |
351 | ||
352 | f( | |
353 | tester = values(S("foo"), 1.f, 2) | |
354 | , name = S("foo") | |
355 | , value = 1.f | |
356 | , test::index = index_lvalue | |
357 | ); | |
358 | ||
359 | f( | |
360 | values(S("foo"), 1.f, 2) | |
361 | , S("foo") | |
362 | , 1.f | |
363 | , index_lvalue | |
364 | ); | |
365 | ||
366 | g( | |
367 | values(S("foo"), 1.f, 2) | |
368 | , S("foo") | |
369 | , 1.f | |
370 | #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) | |
371 | , as_lvalue(2) | |
372 | #else | |
373 | , 2 | |
374 | #endif | |
375 | ); | |
376 | ||
377 | h( | |
378 | values(S("foo"), 1.f, 2) | |
379 | , S("foo") | |
380 | , 1.f | |
381 | #if BOOST_WORKAROUND(BOOST_MSVC, == 1300) | |
382 | , as_lvalue(2) | |
383 | #else | |
384 | , 2 | |
385 | #endif | |
386 | ); | |
387 | ||
388 | h2( | |
389 | tester = values(S("foo"), 1.f, 2) | |
390 | , name = S("foo") | |
391 | , value = 1.f | |
392 | ); | |
393 | ||
394 | class_ x( | |
395 | values(S("foo"), 1.f, 2) | |
396 | , S("foo"), test::index = 2 | |
397 | ); | |
398 | ||
399 | x.f( | |
400 | values(S("foo"), 1.f, 2) | |
401 | , S("foo") | |
402 | ); | |
403 | ||
404 | x.f( | |
405 | tester = values(S("foo"), 1.f, 2) | |
406 | , name = S("foo") | |
407 | ); | |
408 | ||
409 | x.f2( | |
410 | values(S("foo"), 1.f, 2) | |
411 | , S("foo") | |
412 | ); | |
413 | ||
414 | x.f2( | |
415 | tester = values(S("foo"), 1.f, 2) | |
416 | , name = S("foo") | |
417 | ); | |
418 | ||
419 | class_ const& x_const = x; | |
420 | ||
421 | x_const.f( | |
422 | values(S("foo"), 1.f, 2) | |
423 | , S("foo") | |
424 | ); | |
425 | ||
426 | x_const.f( | |
427 | tester = values(S("foo"), 1.f, 2) | |
428 | , name = S("foo") | |
429 | ); | |
430 | ||
431 | x_const.f2( | |
432 | values(S("foo"), 1.f, 2) | |
433 | , S("foo") | |
434 | ); | |
435 | ||
436 | x_const.f2( | |
437 | tester = values(S("foo"), 1.f, 2) | |
438 | , name = S("foo") | |
439 | ); | |
440 | ||
441 | x_const.f2( | |
442 | tester = values(S("foo"), 1.f, 2) | |
443 | , name = S("foo") | |
444 | ); | |
445 | ||
446 | class_::f_static( | |
447 | values(S("foo"), 1.f, 2) | |
448 | , S("foo") | |
449 | ); | |
450 | ||
451 | class_::f_static( | |
452 | tester = values(S("foo"), 1.f, 2) | |
453 | , name = S("foo") | |
454 | ); | |
455 | ||
456 | #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592)) | |
457 | assert(sfinae("foo") == 1); | |
458 | assert(sfinae(1) == 0); | |
459 | ||
460 | # if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)) | |
461 | // Sun actually eliminates the desired overload for some reason. | |
462 | // Disabling this part of the test because SFINAE abilities are | |
463 | // not the point of this test. | |
464 | assert(sfinae1("foo") == 1); | |
465 | # endif | |
466 | ||
467 | assert(sfinae1(1) == 0); | |
468 | #endif | |
469 | ||
470 | lazy_defaults( | |
471 | name = udt(0,1) | |
472 | ); | |
473 | ||
474 | lazy_defaults( | |
475 | name = 0 | |
476 | , value = 1 | |
477 | , test::index = 2 | |
478 | ); | |
479 | ||
480 | return 0; | |
481 | } | |
482 |