1 // Copyright Cromwell D. Enage 2017.
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 (BOOST_PARAMETER_MAX_ARITY < 4)
9 #error Define BOOST_PARAMETER_MAX_ARITY as 4 or greater.
10 #endif
11 #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) && \
12 (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 5)
13 #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \
14 as 5 or greater.
15 #endif
16
17 #include <boost/parameter/name.hpp>
18
19 namespace test {
20
21 BOOST_PARAMETER_NAME((_lrc0, kw) in(lrc0))
22 BOOST_PARAMETER_NAME((_lr0, kw) in_out(lr0))
23 BOOST_PARAMETER_NAME((_rrc0, kw) in(rrc0))
24 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
25 BOOST_PARAMETER_NAME((_rr0, kw) consume(rr0))
26 #else
27 BOOST_PARAMETER_NAME((_rr0, kw) rr0)
28 #endif
29 } // namespace test
30
31 #include <boost/parameter/preprocessor.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 <boost/type_traits/remove_reference.hpp>
37 #include "evaluate_category.hpp"
38
39 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
40 #include <utility>
41 #endif
42
43 namespace test {
44
45 BOOST_PARAMETER_FUNCTION((bool), evaluate, kw,
46 (required
47 (lrc0, *)
48 (lr0, *)
49 (rrc0, *)
50 (rr0, *)
51 )
52 )
53 {
54 BOOST_TEST((
55 test::passed_by_lvalue_reference_to_const == test::A<
56 typename boost::remove_const<
57 typename boost::parameter::value_type<
58 Args
59 , test::kw::lrc0
60 >::type
61 >::type
62 >::evaluate_category(args[test::_lrc0])
63 ));
64 BOOST_TEST_EQ(
65 test::passed_by_lvalue_reference_to_const
66 , test::A<
67 typename boost::remove_const<
68 typename boost::remove_reference<lrc0_type>::type
69 >::type
70 >::evaluate_category(lrc0)
71 );
72 BOOST_TEST((
73 test::passed_by_lvalue_reference == test::A<
74 typename boost::remove_const<
75 typename boost::parameter::value_type<
76 Args
77 , test::kw::lr0
78 >::type
79 >::type
80 >::evaluate_category(args[test::_lr0])
81 ));
82 BOOST_TEST_EQ(
83 test::passed_by_lvalue_reference
84 , test::A<
85 typename boost::remove_const<
86 typename boost::remove_reference<lr0_type>::type
87 >::type
88 >::evaluate_category(lr0)
89 );
90
91 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
92 if (
93 boost::is_scalar<
94 typename boost::remove_const<
95 typename boost::remove_reference<rrc0_type>::type
96 >::type
97 >::value
98 )
99 {
100 BOOST_TEST((
101 test::passed_by_lvalue_reference_to_const == test::A<
102 typename boost::remove_const<
103 typename boost::parameter::value_type<
104 Args
105 , test::kw::rrc0
106 >::type
107 >::type
108 >::evaluate_category(args[test::_rrc0])
109 ));
110 BOOST_TEST_EQ(
111 test::passed_by_lvalue_reference_to_const
112 , test::A<
113 typename boost::remove_const<
114 typename boost::remove_reference<rrc0_type>::type
115 >::type
116 >::evaluate_category(std::forward<rrc0_type>(rrc0))
117 );
118 BOOST_TEST((
119 test::passed_by_lvalue_reference_to_const == test::A<
120 typename boost::remove_const<
121 typename boost::parameter::value_type<
122 Args
123 , test::kw::rr0
124 >::type
125 >::type
126 >::evaluate_category(args[test::_rr0])
127 ));
128 BOOST_TEST_EQ(
129 test::passed_by_lvalue_reference_to_const
130 , test::A<
131 typename boost::remove_const<
132 typename boost::remove_reference<rr0_type>::type
133 >::type
134 >::evaluate_category(std::forward<rr0_type>(rr0))
135 );
136 }
137 else // rrc0's value type isn't scalar
138 {
139 BOOST_TEST((
140 test::passed_by_rvalue_reference_to_const == test::A<
141 typename boost::remove_const<
142 typename boost::parameter::value_type<
143 Args
144 , test::kw::rrc0
145 >::type
146 >::type
147 >::evaluate_category(args[test::_rrc0])
148 ));
149 BOOST_TEST_EQ(
150 test::passed_by_rvalue_reference_to_const
151 , test::A<
152 typename boost::remove_const<
153 typename boost::remove_reference<rrc0_type>::type
154 >::type
155 >::evaluate_category(std::forward<rrc0_type>(rrc0))
156 );
157 BOOST_TEST((
158 test::passed_by_rvalue_reference == test::A<
159 typename boost::remove_const<
160 typename boost::parameter::value_type<
161 Args
162 , test::kw::rr0
163 >::type
164 >::type
165 >::evaluate_category(args[test::_rr0])
166 ));
167 BOOST_TEST_EQ(
168 test::passed_by_rvalue_reference
169 , test::A<
170 typename boost::remove_const<
171 typename boost::remove_reference<rr0_type>::type
172 >::type
173 >::evaluate_category(std::forward<rr0_type>(rr0))
174 );
175 }
176 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
177 BOOST_TEST((
178 test::passed_by_lvalue_reference_to_const == test::A<
179 typename boost::remove_const<
180 typename boost::parameter::value_type<
181 Args
182 , test::kw::rrc0
183 >::type
184 >::type
185 >::evaluate_category(args[test::_rrc0])
186 ));
187 BOOST_TEST_EQ(
188 test::passed_by_lvalue_reference_to_const
189 , test::A<
190 typename boost::remove_const<
191 typename boost::remove_reference<rrc0_type>::type
192 >::type
193 >::evaluate_category(rrc0)
194 );
195 BOOST_TEST((
196 test::passed_by_lvalue_reference_to_const == test::A<
197 typename boost::remove_const<
198 typename boost::parameter::value_type<
199 Args
200 , test::kw::rr0
201 >::type
202 >::type
203 >::evaluate_category(args[test::_rr0])
204 ));
205 BOOST_TEST_EQ(
206 test::passed_by_lvalue_reference_to_const
207 , test::A<
208 typename boost::remove_const<
209 typename boost::remove_reference<rr0_type>::type
210 >::type
211 >::evaluate_category(rr0)
212 );
213 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
214
215 return true;
216 }
217 } // namespace test
218
219 #include <boost/mpl/bool.hpp>
220 #include <boost/mpl/if.hpp>
221
222 #if !defined(BOOST_NO_SFINAE)
223 #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
224 #include <boost/core/enable_if.hpp>
225 #include <boost/type_traits/is_base_of.hpp>
226 #endif
227
228 namespace test {
229
230 char const* baz = "baz";
231
232 struct B
233 {
234 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
235 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
Btest::B236 B()
237 {
238 }
239 #endif
240
241 template <typename Args>
Btest::B242 explicit B(
243 Args const& args
244 #if !defined(BOOST_NO_SFINAE)
245 , typename boost::disable_if<
246 typename boost::mpl::if_<
247 boost::is_base_of<B,Args>
248 , boost::mpl::true_
249 , boost::mpl::false_
250 >::type
251 >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR
252 #endif // BOOST_NO_SFINAE
253 )
254 {
255 test::evaluate(
256 args[test::_lrc0]
257 , args[test::_lr0]
258 , args[test::_rrc0]
259 , args[test::_rr0]
260 );
261 }
262
263 #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
264 typedef test::string_predicate<test::kw::lr0> rr0_pred;
265
266 BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
267 (required
268 (lrc0, (char))
269 )
270 (deduced
271 (optional
272 (rrc0, (float), 0.0f)
273 (lr0, (char const*), test::baz)
274 (rr0, *(rr0_pred), std::string(lr0))
275 )
276 )
277 )
278 #else // !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
279 BOOST_PARAMETER_MEMBER_FUNCTION((bool), static evaluate, kw,
280 (required
281 (lrc0, (char))
282 )
283 (deduced
284 (optional
285 (rrc0, (float), 0.0f)
286 (lr0, (char const*), test::baz)
287 (rr0
288 , *(test::string_predicate<test::kw::lr0>)
289 , std::string(lr0)
290 )
291 )
292 )
293 )
294 #endif // SunPro CC workarounds needed.
295 {
296 BOOST_TEST((
297 test::passed_by_lvalue_reference_to_const == test::A<
298 typename boost::remove_const<
299 typename boost::parameter::value_type<
300 Args
301 , test::kw::lrc0
302 >::type
303 >::type
304 >::evaluate_category(args[test::_lrc0])
305 ));
306 BOOST_TEST_EQ(
307 test::passed_by_lvalue_reference_to_const
308 , test::A<
309 typename boost::remove_const<
310 typename boost::remove_reference<lrc0_type>::type
311 >::type
312 >::evaluate_category(lrc0)
313 );
314 BOOST_TEST((
315 test::passed_by_lvalue_reference == test::A<
316 typename boost::remove_const<
317 typename boost::parameter::value_type<
318 Args
319 , test::kw::lr0
320 >::type
321 >::type
322 >::evaluate_category(args[test::_lr0])
323 ));
324 BOOST_TEST_EQ(
325 test::passed_by_lvalue_reference
326 , test::A<
327 typename boost::remove_const<
328 typename boost::remove_reference<lr0_type>::type
329 >::type
330 >::evaluate_category(lr0)
331 );
332 BOOST_TEST((
333 test::passed_by_lvalue_reference_to_const == test::A<
334 typename boost::remove_const<
335 typename boost::parameter::value_type<
336 Args
337 , test::kw::rrc0
338 >::type
339 >::type
340 >::evaluate_category(args[test::_rrc0])
341 ));
342 BOOST_TEST_EQ(
343 test::passed_by_lvalue_reference_to_const
344 , test::A<
345 typename boost::remove_const<
346 typename boost::remove_reference<rrc0_type>::type
347 >::type
348 >::evaluate_category(rrc0)
349 );
350
351 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
352 BOOST_TEST((
353 test::passed_by_rvalue_reference == test::A<
354 typename boost::remove_const<
355 typename boost::parameter::value_type<
356 Args
357 , test::kw::rr0
358 >::type
359 >::type
360 >::evaluate_category(args[test::_rr0])
361 ));
362 BOOST_TEST_EQ(
363 test::passed_by_rvalue_reference
364 , test::A<
365 typename boost::remove_const<
366 typename boost::remove_reference<rr0_type>::type
367 >::type
368 >::evaluate_category(std::forward<rr0_type>(rr0))
369 );
370 #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
371 BOOST_TEST((
372 test::passed_by_lvalue_reference_to_const == test::A<
373 typename boost::remove_const<
374 typename boost::parameter::value_type<
375 Args
376 , test::kw::rr0
377 >::type
378 >::type
379 >::evaluate_category(args[test::_rr0])
380 ));
381 BOOST_TEST_EQ(
382 test::passed_by_lvalue_reference_to_const
383 , test::A<
384 typename boost::remove_const<
385 typename boost::remove_reference<rr0_type>::type
386 >::type
387 >::evaluate_category(rr0)
388 );
389 #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
390
391 return true;
392 }
393 };
394
395 struct C : B
396 {
397 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
398 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
Ctest::C399 C() : B()
400 {
401 }
402 #endif
403
404 BOOST_PARAMETER_CONSTRUCTOR(C, (B), kw,
405 (required
406 (lrc0, *)
407 (lr0, *)
408 (rrc0, *)
409 (rr0, *)
410 )
411 )
412 };
413 } // namespace test
414
main()415 int main()
416 {
417 test::evaluate(
418 test::lvalue_const_float()
419 , test::lvalue_float()
420 , test::rvalue_const_float()
421 , test::rvalue_float()
422 );
423 test::evaluate(
424 test::lvalue_const_char_ptr()
425 , test::lvalue_char_ptr()
426 , test::rvalue_const_char_ptr()
427 , test::rvalue_char_ptr()
428 );
429 test::evaluate(
430 test::lvalue_const_str()
431 , test::lvalue_str()
432 , test::rvalue_const_str()
433 , test::rvalue_str()
434 );
435 test::evaluate(
436 test::_lr0 = test::lvalue_float()
437 , test::_rrc0 = test::rvalue_const_float()
438 , test::_rr0 = test::rvalue_float()
439 , test::_lrc0 = test::lvalue_const_float()
440 );
441 test::evaluate(
442 test::_lr0 = test::lvalue_char_ptr()
443 , test::_rrc0 = test::rvalue_const_char_ptr()
444 , test::_rr0 = test::rvalue_char_ptr()
445 , test::_lrc0 = test::lvalue_const_char_ptr()
446 );
447 test::evaluate(
448 test::_lr0 = test::lvalue_str()
449 , test::_rrc0 = test::rvalue_const_str()
450 , test::_rr0 = test::rvalue_str()
451 , test::_lrc0 = test::lvalue_const_str()
452 );
453
454 test::C cf0(
455 test::lvalue_const_float()
456 , test::lvalue_float()
457 , test::rvalue_const_float()
458 , test::rvalue_float()
459 );
460 test::C cc0(
461 test::lvalue_const_char_ptr()
462 , test::lvalue_char_ptr()
463 , test::rvalue_const_char_ptr()
464 , test::rvalue_char_ptr()
465 );
466 test::C cs0(
467 test::lvalue_const_str()
468 , test::lvalue_str()
469 , test::rvalue_const_str()
470 , test::rvalue_str()
471 );
472 test::C cf1(
473 test::_lr0 = test::lvalue_float()
474 , test::_rrc0 = test::rvalue_const_float()
475 , test::_rr0 = test::rvalue_float()
476 , test::_lrc0 = test::lvalue_const_float()
477 );
478 test::C cc1(
479 test::_lr0 = test::lvalue_char_ptr()
480 , test::_rrc0 = test::rvalue_const_char_ptr()
481 , test::_rr0 = test::rvalue_char_ptr()
482 , test::_lrc0 = test::lvalue_const_char_ptr()
483 );
484 test::C cs1(
485 test::_lr0 = test::lvalue_str()
486 , test::_rrc0 = test::rvalue_const_str()
487 , test::_rr0 = test::rvalue_str()
488 , test::_lrc0 = test::lvalue_const_str()
489 );
490
491 char baz_arr[4] = "qux";
492 typedef char char_arr[4];
493
494 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
495 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
496 // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
497 #else
498 test::evaluate(
499 "q2x"
500 , baz_arr
501 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
502 , static_cast<char_arr const&&>("mos")
503 , static_cast<char_arr&&>(baz_arr)
504 #else
505 , "crg"
506 , "uir"
507 #endif
508 );
509 test::evaluate(
510 test::_lr0 = baz_arr
511 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
512 , test::_rrc0 = static_cast<char_arr const&&>("def")
513 , test::_rr0 = static_cast<char_arr&&>(baz_arr)
514 #else
515 , test::_rrc0 = "grl"
516 , test::_rr0 = "grp"
517 #endif
518 , test::_lrc0 = "wld"
519 );
520 #endif // MSVC-12+
521 test::B::evaluate(test::lvalue_const_str()[0]);
522 test::C::evaluate(
523 test::lvalue_const_str()[0]
524 , test::rvalue_const_float()
525 );
526
527 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
528 BOOST_WORKAROUND(BOOST_MSVC, >= 1800)
529 // MSVC-12+ treats static_cast<char_arr&&>(baz_arr) as an lvalue.
530 test::C cp0;
531 test::C cp1;
532 #else
533 test::C cp0(
534 "frd"
535 , baz_arr
536 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
537 , static_cast<char_arr const&&>("dfs")
538 , static_cast<char_arr&&>(baz_arr)
539 #else
540 , "plg"
541 , "thd"
542 #endif
543 );
544 test::C cp1(
545 test::_lr0 = baz_arr
546 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
547 , test::_rrc0 = static_cast<char_arr const&&>("dgx")
548 , test::_rr0 = static_cast<char_arr&&>(baz_arr)
549 #else
550 , test::_rrc0 = "hnk"
551 , test::_rr0 = "xzz"
552 #endif
553 , test::_lrc0 = "zts"
554 );
555 #endif // MSVC-12+
556
557 cp0.evaluate(
558 test::lvalue_const_str()[0]
559 , test::lvalue_char_ptr()
560 , test::rvalue_str()
561 , test::rvalue_const_float()
562 );
563 cp1.evaluate(
564 test::lvalue_const_str()[0]
565 , test::rvalue_str()
566 , test::rvalue_const_float()
567 , test::lvalue_char_ptr()
568 );
569 return boost::report_errors();
570 }
571
572