1 // Copyright Cromwell D. Enage 2018.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 #include <boost/parameter/config.hpp>
7
8 #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \
9 (BOOST_PARAMETER_COMPOSE_MAX_ARITY < 8)
10 #error Define BOOST_PARAMETER_COMPOSE_MAX_ARITY as 8 or greater.
11 #endif
12
13 #include <boost/parameter/name.hpp>
14
15 namespace test {
16
17 BOOST_PARAMETER_NAME((_lrc0, kw0) in(lrc0))
18 BOOST_PARAMETER_NAME((_lr0, kw1) in_out(lr0))
19 BOOST_PARAMETER_NAME((_rrc0, kw2) in(rrc0))
20 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
21 BOOST_PARAMETER_NAME((_rr0, kw3) consume(rr0))
22 #else
23 BOOST_PARAMETER_NAME((_rr0, kw3) rr0)
24 #endif
25 BOOST_PARAMETER_NAME((_lrc1, kw4) in(lrc1))
26 BOOST_PARAMETER_NAME((_lr1, kw5) out(lr1))
27 BOOST_PARAMETER_NAME((_rrc1, kw6) in(rrc1))
28 BOOST_PARAMETER_NAME((_rr1, kw7) rr1)
29 } // namespace test
30
31 #include <boost/parameter/preprocessor_no_spec.hpp>
32 #include <boost/parameter/value_type.hpp>
33 #include <boost/core/lightweight_test.hpp>
34 #include <boost/type_traits/is_scalar.hpp>
35 #include <boost/type_traits/remove_const.hpp>
36 #include "evaluate_category.hpp"
37
38 namespace test {
39
40 BOOST_PARAMETER_NO_SPEC_FUNCTION((bool), evaluate)
41 {
42 BOOST_TEST((
43 test::passed_by_lvalue_reference_to_const == test::A<
44 typename boost::remove_const<
45 typename boost::parameter::value_type<
46 Args
47 , test::kw0::lrc0
48 >::type
49 >::type
50 >::evaluate_category(args[test::_lrc0])
51 ));
52 BOOST_TEST((
53 test::passed_by_lvalue_reference == test::A<
54 typename boost::remove_const<
55 typename boost::parameter::value_type<
56 Args
57 , test::kw1::lr0
58 >::type
59 >::type
60 >::evaluate_category(args[test::_lr0])
61 ));
62
63 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
64 if (
65 boost::is_scalar<
66 typename boost::remove_const<
67 typename boost::parameter::value_type<
68 Args
69 , test::kw2::rrc0
70 >::type
71 >::type
72 >::value
73 )
74 {
75 BOOST_TEST((
76 test::passed_by_lvalue_reference_to_const == test::A<
77 typename boost::remove_const<
78 typename boost::parameter::value_type<
79 Args
80 , test::kw2::rrc0
81 >::type
82 >::type
83 >::evaluate_category(args[test::_rrc0])
84 ));
85 BOOST_TEST((
86 test::passed_by_lvalue_reference_to_const == test::A<
87 typename boost::remove_const<
88 typename boost::parameter::value_type<
89 Args
90 , test::kw3::rr0
91 >::type
92 >::type
93 >::evaluate_category(args[test::_rr0])
94 ));
95 }
96 else // rrc0's value type isn't scalar
97 {
98 BOOST_TEST((
99 test::passed_by_rvalue_reference_to_const == test::A<
100 typename boost::remove_const<
101 typename boost::parameter::value_type<
102 Args
103 , test::kw2::rrc0
104 >::type
105 >::type
106 >::evaluate_category(args[test::_rrc0])
107 ));
108 BOOST_TEST((
109 test::passed_by_rvalue_reference == test::A<
110 typename boost::remove_const<
111 typename boost::parameter::value_type<
112 Args
113 , test::kw3::rr0
114 >::type
115 >::type
116 >::evaluate_category(args[test::_rr0])
117 ));
118 }
119 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
120 BOOST_TEST((
121 test::passed_by_lvalue_reference_to_const == test::A<
122 typename boost::remove_const<
123 typename boost::parameter::value_type<
124 Args
125 , test::kw2::rrc0
126 >::type
127 >::type
128 >::evaluate_category(args[test::_rrc0])
129 ));
130 BOOST_TEST((
131 test::passed_by_lvalue_reference_to_const == test::A<
132 typename boost::remove_const<
133 typename boost::parameter::value_type<
134 Args
135 , test::kw3::rr0
136 >::type
137 >::type
138 >::evaluate_category(args[test::_rr0])
139 ));
140 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
141
142 return true;
143 }
144 } // namespace test
145
146 #include <boost/mpl/bool.hpp>
147 #include <boost/mpl/if.hpp>
148
149 #if !defined(BOOST_NO_SFINAE)
150 #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
151 #include <boost/core/enable_if.hpp>
152 #include <boost/type_traits/is_base_of.hpp>
153 #endif
154
155 namespace test {
156
157 char const* baz = "baz";
158
159 struct B
160 {
161 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
162 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
Btest::B163 B()
164 {
165 }
166 #endif
167
168 template <typename Args>
Btest::B169 explicit B(
170 Args const& args
171 #if !defined(BOOST_NO_SFINAE)
172 , typename boost::disable_if<
173 typename boost::mpl::if_<
174 boost::is_base_of<B,Args>
175 , boost::mpl::true_
176 , boost::mpl::false_
177 >::type
178 >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR
179 #endif // BOOST_NO_SFINAE
180 )
181 {
182 test::evaluate(
183 test::_lrc0 = args[test::_lrc0]
184 , test::_lr0 = args[test::_lr0]
185 , test::_rrc0 = args[test::_rrc0]
186 , test::_rr0 = args[test::_rr0]
187 );
188 }
189
190 BOOST_PARAMETER_NO_SPEC_MEMBER_FUNCTION((bool), static evaluate)
191 {
192 BOOST_TEST((
193 test::passed_by_lvalue_reference_to_const == test::A<
194 typename boost::remove_const<
195 typename boost::parameter::value_type<
196 Args
197 , test::kw0::lrc0
198 >::type
199 >::type
200 >::evaluate_category(args[test::_lrc0])
201 ));
202 BOOST_TEST((
203 test::passed_by_lvalue_reference == test::A<
204 typename boost::remove_const<
205 typename boost::parameter::value_type<
206 Args
207 , test::kw1::lr0
208 , char const*
209 >::type
210 >::type
211 >::evaluate_category(args[test::_lr0 | test::baz])
212 ));
213 BOOST_TEST((
214 test::passed_by_lvalue_reference_to_const == test::A<
215 typename boost::remove_const<
216 typename boost::parameter::value_type<
217 Args
218 , test::kw2::rrc0
219 , float
220 >::type
221 >::type
222 >::evaluate_category(args[test::_rrc0 | 0.0f])
223 ));
224
225 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
226 BOOST_TEST((
227 test::passed_by_rvalue_reference == test::A<
228 typename boost::remove_const<
229 typename boost::parameter::value_type<
230 Args
231 , test::kw3::rr0
232 , std::string
233 >::type
234 >::type
235 >::evaluate_category(
236 args[
237 test::_rr0 | std::string(args[test::_lr0 | test::baz])
238 ]
239 )
240 ));
241 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
242 BOOST_TEST((
243 test::passed_by_lvalue_reference_to_const == test::A<
244 typename boost::remove_const<
245 typename boost::parameter::value_type<
246 Args
247 , test::kw3::rr0
248 , std::string
249 >::type
250 >::type
251 >::evaluate_category(
252 args[
253 test::_rr0 | std::string(args[test::_lr0 | test::baz])
254 ]
255 )
256 ));
257 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
258
259 return true;
260 }
261 };
262
263 struct C : B
264 {
265 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
266 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
Ctest::C267 C() : B()
268 {
269 }
270 #endif
271
272 BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(C, (B))
273 };
274
275 struct D
276 {
BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTORtest::D277 BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(D, D::_evaluate)
278
279 BOOST_PARAMETER_NO_SPEC_CONST_MEMBER_FUNCTION((bool), evaluate_m)
280 {
281 return D::_evaluate(args);
282 }
283
284 BOOST_PARAMETER_NO_SPEC_CONST_FUNCTION_CALL_OPERATOR((bool))
285 {
286 return D::_evaluate(args);
287 }
288
289 private:
290 template <typename Args>
_evaluatetest::D291 static bool _evaluate(Args const& args)
292 {
293 BOOST_TEST_EQ(
294 test::passed_by_lvalue_reference_to_const
295 , test::U::evaluate_category<0>(args[test::_lrc0])
296 );
297 BOOST_TEST_EQ(
298 test::passed_by_lvalue_reference
299 , test::U::evaluate_category<1>(args[test::_lr0])
300 );
301 BOOST_TEST_EQ(
302 test::passed_by_lvalue_reference_to_const
303 , test::U::evaluate_category<4>(args[test::_lrc1])
304 );
305 BOOST_TEST_EQ(
306 test::passed_by_lvalue_reference
307 , test::U::evaluate_category<5>(
308 args[test::_lr1 | test::lvalue_bitset<5>()]
309 )
310 );
311 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
312 BOOST_TEST_EQ(
313 test::passed_by_rvalue_reference_to_const
314 , test::U::evaluate_category<2>(args[test::_rrc0])
315 );
316 BOOST_TEST_EQ(
317 test::passed_by_rvalue_reference
318 , test::U::evaluate_category<3>(args[test::_rr0])
319 );
320 BOOST_TEST_EQ(
321 test::passed_by_rvalue_reference_to_const
322 , test::U::evaluate_category<6>(
323 args[test::_rrc1 | test::rvalue_const_bitset<6>()]
324 )
325 );
326 BOOST_TEST_EQ(
327 test::passed_by_rvalue_reference
328 , test::U::evaluate_category<7>(
329 args[test::_rr1 | test::rvalue_bitset<7>()]
330 )
331 );
332 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
333 BOOST_TEST_EQ(
334 test::passed_by_lvalue_reference_to_const
335 , test::U::evaluate_category<2>(args[test::_rrc0])
336 );
337 BOOST_TEST_EQ(
338 test::passed_by_lvalue_reference_to_const
339 , test::U::evaluate_category<3>(args[test::_rr0])
340 );
341 BOOST_TEST_EQ(
342 test::passed_by_lvalue_reference_to_const
343 , test::U::evaluate_category<6>(
344 args[test::_rrc1 | test::rvalue_const_bitset<6>()]
345 )
346 );
347 BOOST_TEST_EQ(
348 test::passed_by_lvalue_reference_to_const
349 , test::U::evaluate_category<7>(
350 args[test::_rr1 | test::rvalue_bitset<7>()]
351 )
352 );
353 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
354
355 return true;
356 }
357 };
358 } // namespace test
359
main()360 int main()
361 {
362 test::evaluate(
363 test::_lr0 = test::lvalue_float()
364 , test::_rrc0 = test::rvalue_const_float()
365 , test::_rr0 = test::rvalue_float()
366 , test::_lrc0 = test::lvalue_const_float()
367 );
368 test::evaluate(
369 test::_lr0 = test::lvalue_char_ptr()
370 , test::_rrc0 = test::rvalue_const_char_ptr()
371 , test::_rr0 = test::rvalue_char_ptr()
372 , test::_lrc0 = test::lvalue_const_char_ptr()
373 );
374 test::evaluate(
375 test::_lr0 = test::lvalue_str()
376 , test::_rrc0 = test::rvalue_const_str()
377 , test::_rr0 = test::rvalue_str()
378 , test::_lrc0 = test::lvalue_const_str()
379 );
380
381 test::C cf1(
382 test::_lr0 = test::lvalue_float()
383 , test::_rrc0 = test::rvalue_const_float()
384 , test::_rr0 = test::rvalue_float()
385 , test::_lrc0 = test::lvalue_const_float()
386 );
387 test::C cc1(
388 test::_lr0 = test::lvalue_char_ptr()
389 , test::_rrc0 = test::rvalue_const_char_ptr()
390 , test::_rr0 = test::rvalue_char_ptr()
391 , test::_lrc0 = test::lvalue_const_char_ptr()
392 );
393 test::C cs1(
394 test::_lr0 = test::lvalue_str()
395 , test::_rrc0 = test::rvalue_const_str()
396 , test::_rr0 = test::rvalue_str()
397 , test::_lrc0 = test::lvalue_const_str()
398 );
399
400 char baz_arr[4] = "qux";
401 typedef char char_arr[4];
402
403 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && ( \
404 BOOST_WORKAROUND(BOOST_GCC, < 40000) || \
405 BOOST_WORKAROUND(BOOST_MSVC, >= 1800) \
406 )
407 // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
408 // GCC 3- tries to bind string literals
409 // to non-const references to char const*.
410 #else
411 test::evaluate(
412 test::_lr0 = baz_arr
413 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
414 , test::_rrc0 = static_cast<char_arr const&&>("def")
415 , test::_rr0 = static_cast<char_arr&&>(baz_arr)
416 #else
417 , test::_rrc0 = "grl"
418 , test::_rr0 = "grp"
419 #endif
420 , test::_lrc0 = "wld"
421 );
422 #endif // MSVC-12+
423 test::B::evaluate(test::_lrc0 = test::lvalue_const_str()[0]);
424 test::C::evaluate(
425 test::_rrc0 = test::rvalue_const_float()
426 , test::_lrc0 = test::lvalue_const_str()[0]
427 );
428
429 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
430 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
431 // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
432 test::C cp0;
433 test::C cp1;
434 #else
435 test::C cp0(
436 test::_lrc0 = "frd"
437 , test::_lr0 = baz_arr
438 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
439 , test::_rrc0 = static_cast<char_arr const&&>("dfs")
440 , test::_rr0 = static_cast<char_arr&&>(baz_arr)
441 #else
442 , test::_rrc0 = "plg"
443 , test::_rr0 = "thd"
444 #endif
445 );
446 test::C cp1(
447 test::_lr0 = baz_arr
448 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
449 , test::_rrc0 = static_cast<char_arr const&&>("dgx")
450 , test::_rr0 = static_cast<char_arr&&>(baz_arr)
451 #else
452 , test::_rrc0 = "hnk"
453 , test::_rr0 = "xzz"
454 #endif
455 , test::_lrc0 = "zts"
456 );
457 #endif // MSVC-12+
458
459 cp0.evaluate(
460 test::_lrc0 = test::lvalue_const_str()[0]
461 , test::_lr0 = test::lvalue_char_ptr()
462 , test::_rr0 = test::rvalue_str()
463 , test::_rrc0 = test::rvalue_const_float()
464 );
465 cp1.evaluate(
466 test::_lrc0 = test::lvalue_const_str()[0]
467 , test::_rr0 = test::rvalue_str()
468 , test::_rrc0 = test::rvalue_const_float()
469 , test::_lr0 = test::lvalue_char_ptr()
470 );
471
472 test::D dp0(
473 test::_lrc1 = test::lvalue_const_bitset<4>()
474 , test::_lrc0 = test::lvalue_const_bitset<0>()
475 , test::_lr0 = test::lvalue_bitset<1>()
476 , test::_rrc0 = test::rvalue_const_bitset<2>()
477 , test::_rr0 = test::rvalue_bitset<3>()
478 );
479 test::D dp1(
480 test::_lrc1 = test::lvalue_const_bitset<4>()
481 , test::_lrc0 = test::lvalue_const_bitset<0>()
482 , test::_rrc1 = test::rvalue_const_bitset<6>()
483 , test::_lr0 = test::lvalue_bitset<1>()
484 , test::_rrc0 = test::rvalue_const_bitset<2>()
485 , test::_rr0 = test::rvalue_bitset<3>()
486 );
487
488 dp0.evaluate_m(
489 test::_lrc1 = test::lvalue_const_bitset<4>()
490 , test::_lrc0 = test::lvalue_const_bitset<0>()
491 , test::_rrc1 = test::rvalue_const_bitset<6>()
492 , test::_lr0 = test::lvalue_bitset<1>()
493 , test::_rrc0 = test::rvalue_const_bitset<2>()
494 , test::_rr0 = test::rvalue_bitset<3>()
495 );
496 dp1.evaluate_m(
497 test::_lr0 = test::lvalue_bitset<1>()
498 , test::_rrc0 = test::rvalue_const_bitset<2>()
499 , test::_rr0 = test::rvalue_bitset<3>()
500 , test::_lrc1 = test::lvalue_const_bitset<4>()
501 , test::_lr1 = test::lvalue_bitset<5>()
502 , test::_rrc1 = test::rvalue_const_bitset<6>()
503 , test::_rr1 = test::rvalue_bitset<7>()
504 , test::_lrc0 = test::lvalue_const_bitset<0>()
505 );
506 dp0(
507 test::_lrc1 = test::lvalue_const_bitset<4>()
508 , test::_lrc0 = test::lvalue_const_bitset<0>()
509 , test::_lr0 = test::lvalue_bitset<1>()
510 , test::_rrc0 = test::rvalue_const_bitset<2>()
511 , test::_rr0 = test::rvalue_bitset<3>()
512 );
513 dp1(
514 test::_lr0 = test::lvalue_bitset<1>()
515 , test::_rrc0 = test::rvalue_const_bitset<2>()
516 , test::_rr0 = test::rvalue_bitset<3>()
517 , test::_lrc1 = test::lvalue_const_bitset<4>()
518 , test::_lr1 = test::lvalue_bitset<5>()
519 , test::_rrc1 = test::rvalue_const_bitset<6>()
520 , test::_rr1 = test::rvalue_bitset<7>()
521 , test::_lrc0 = test::lvalue_const_bitset<0>()
522 );
523 return boost::report_errors();
524 }
525
526