• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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