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