• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Rene Rivera 2006.
2 // Copyright Cromwell D. Enage 2017.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 
7 #include <boost/parameter/nested_keyword.hpp>
8 #include <boost/parameter/name.hpp>
9 #include <boost/parameter/config.hpp>
10 
11 namespace param {
12 
13     BOOST_PARAMETER_NESTED_KEYWORD(tag, a0, a_zero)
14     BOOST_PARAMETER_NESTED_KEYWORD(tag, a1, a_one)
15     BOOST_PARAMETER_NAME(a2)
16     BOOST_PARAMETER_NAME(a3)
17     BOOST_PARAMETER_NAME(in(lrc))
18     BOOST_PARAMETER_NAME(out(lr))
19 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
20     BOOST_PARAMETER_NAME(consume(rr))
21 #else
22     BOOST_PARAMETER_NAME(rr)
23 #endif
24 }
25 
26 #include <boost/parameter/is_argument_pack.hpp>
27 #include <boost/mpl/void.hpp>
28 #include <boost/mpl/bool.hpp>
29 #include <boost/mpl/int.hpp>
30 #include <boost/mpl/if.hpp>
31 #include <boost/mpl/has_key.hpp>
32 #include <boost/mpl/key_type.hpp>
33 #include <boost/mpl/order.hpp>
34 #include <boost/mpl/count.hpp>
35 #include <boost/mpl/equal_to.hpp>
36 #include <boost/mpl/assert.hpp>
37 #include <boost/type_traits/is_same.hpp>
38 
39 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
40 #include <boost/mp11/list.hpp>
41 #include <boost/mp11/map.hpp>
42 #include <type_traits>
43 #endif
44 
45 #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
46 #include <boost/function.hpp>
47 #else
48 #include <functional>
49 #endif
50 
51 namespace test {
52 
53     struct A
54     {
55         int i;
56         int j;
57 
58         template <typename ArgPack>
Atest::A59         A(ArgPack const& args) : i(args[param::a0]), j(args[param::a1])
60         {
61 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
62             static_assert(
63                 boost::mp11::mp_map_contains<ArgPack,param::tag::a0>::value
64               , "param::tag::a0 must be in ArgPack"
65             );
66             static_assert(
67                 boost::mp11::mp_map_contains<ArgPack,param::tag::a1>::value
68               , "param::tag::a1 must be in ArgPack"
69             );
70             static_assert(
71                 !boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
72               , "param::tag::lrc must not be in ArgPack"
73             );
74             static_assert(
75                 !boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
76               , "param::tag::lr must not be in ArgPack"
77             );
78             static_assert(
79                 !boost::mp11::mp_map_contains<ArgPack,param::tag::rr>::value
80               , "param::tag::rr must not be in ArgPack"
81             );
82             static_assert(
83                 !std::is_same<
84                     ::boost::mp11::mp_map_find<ArgPack,param::tag::a0>
85                   , void
86                 >::value
87               , "param::tag::a0 must be found in ArgPack"
88             );
89             static_assert(
90                 !std::is_same<
91                     ::boost::mp11::mp_map_find<ArgPack,param::tag::a1>
92                   , void
93                 >::value
94               , "param::tag::a1 must be found in ArgPack"
95             );
96             static_assert(
97                 std::is_same<
98                     ::boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
99                   , void
100                 >::value
101               , "param::tag::lrc must not be found in ArgPack"
102             );
103             static_assert(
104                 std::is_same<
105                     ::boost::mp11::mp_map_find<ArgPack,param::tag::lr>
106                   , void
107                 >::value
108               , "param::tag::lr must not be found in ArgPack"
109             );
110             static_assert(
111                 std::is_same<
112                     ::boost::mp11::mp_map_find<ArgPack,param::tag::rr>
113                   , void
114                 >::value
115               , "param::tag::rr must not be found in ArgPack"
116             );
117 #endif  // BOOST_PARAMETER_CAN_USE_MP11
118             BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
119             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::a0>));
120             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::a1>));
121             BOOST_MPL_ASSERT_NOT((
122                 boost::mpl::has_key<ArgPack,param::tag::lrc>
123             ));
124             BOOST_MPL_ASSERT_NOT((
125                 boost::mpl::has_key<ArgPack,param::tag::lr>
126             ));
127             BOOST_MPL_ASSERT_NOT((
128                 boost::mpl::has_key<ArgPack,param::tag::rr>
129             ));
130             BOOST_MPL_ASSERT((
131                 boost::mpl::equal_to<
132                     typename boost::mpl::count<ArgPack,param::tag::a0>::type
133                   , boost::mpl::int_<1>
134                 >
135             ));
136             BOOST_MPL_ASSERT((
137                 boost::mpl::equal_to<
138                     typename boost::mpl::count<ArgPack,param::tag::a1>::type
139                   , boost::mpl::int_<1>
140                 >
141             ));
142             BOOST_MPL_ASSERT((
143                 typename boost::mpl::if_<
144                     boost::is_same<
145                         typename boost::mpl
146                         ::key_type<ArgPack,param::tag::a0>::type
147                       , param::tag::a0
148                     >
149                   , boost::mpl::true_
150                   , boost::mpl::false_
151                 >::type
152             ));
153             BOOST_MPL_ASSERT((
154                 typename boost::mpl::if_<
155                     boost::is_same<
156                         typename boost::mpl
157                         ::key_type<ArgPack,param::tag::a1>::type
158                       , param::tag::a1
159                     >
160                   , boost::mpl::true_
161                   , boost::mpl::false_
162                 >::type
163             ));
164             BOOST_MPL_ASSERT((
165                 typename boost::mpl::if_<
166                     boost::is_same<
167                         typename boost::mpl
168                         ::order<ArgPack,param::tag::a0>::type
169                       , boost::mpl::void_
170                     >
171                   , boost::mpl::false_
172                   , boost::mpl::true_
173                 >::type
174             ));
175             BOOST_MPL_ASSERT((
176                 typename boost::mpl::if_<
177                     boost::is_same<
178                         typename boost::mpl
179                         ::order<ArgPack,param::tag::a1>::type
180                       , boost::mpl::void_
181                     >
182                   , boost::mpl::false_
183                   , boost::mpl::true_
184                 >::type
185             ));
186         }
187     };
188 
F()189     float F()
190     {
191         return 4.0f;
192     }
193 
E()194     float E()
195     {
196         return 4.625f;
197     }
198 
D()199     double D()
200     {
201         return 198.9;
202     }
203 
204     struct C
205     {
206         struct result_type
207         {
operator ()test::C::result_type208             double operator()() const
209             {
210                 return 2.5;
211             }
212         };
213 
operator ()test::C214         result_type operator()() const
215         {
216             return result_type();
217         }
218     };
219 
220     struct B : A
221     {
222 #if defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
223         boost::function<float()> k;
224         boost::function<double()> l;
225 #else
226         std::function<float()> k;
227         std::function<double()> l;
228 #endif
229 
230         template <typename ArgPack>
Btest::B231         B(ArgPack const& args)
232           : A((args, param::tag::a0::a_zero = 1))
233           , k(args[param::_a2 | E])
234           , l(args[param::_a3 || C()])
235         {
236         }
237     };
238 
239     struct G
240     {
241         int i;
242         int& j;
243         int const& k;
244 
245         template <typename ArgPack>
Gtest::G246         G(ArgPack const& args)
247           : i(args[param::_rr])
248           , j(args[param::_lr])
249           , k(args[param::_lrc])
250         {
251 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
252             static_assert(
253                 boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
254               , "param::tag::lrc must be in ArgPack"
255             );
256             static_assert(
257                 boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
258               , "param::tag::lr must be in ArgPack"
259             );
260             static_assert(
261                 boost::mp11::mp_map_contains<ArgPack,param::tag::rr>::value
262               , "param::tag::rr must be in ArgPack"
263             );
264             static_assert(
265                 !boost::mp11::mp_map_contains<ArgPack,param::tag::a0>::value
266               , "param::tag::a0 must not be in ArgPack"
267             );
268             static_assert(
269                 !boost::mp11::mp_map_contains<ArgPack,param::tag::a1>::value
270               , "param::tag::a1 must not be in ArgPack"
271             );
272             static_assert(
273                 !boost::mp11::mp_map_contains<ArgPack,param::tag::a2>::value
274               , "param::tag::a2 must not be in ArgPack"
275             );
276             static_assert(
277                 !boost::mp11::mp_map_contains<ArgPack,param::tag::a3>::value
278               , "param::tag::a3 must not be in ArgPack"
279             );
280             static_assert(
281                 !std::is_same<
282                     boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
283                   , void
284                 >::value
285               , "param::tag::lrc must be found in ArgPack"
286             );
287             static_assert(
288                 !std::is_same<
289                     boost::mp11::mp_map_find<ArgPack,param::tag::lr>
290                   , void
291                 >::value
292               , "param::tag::lr must be found in ArgPack"
293             );
294             static_assert(
295                 !std::is_same<
296                     boost::mp11::mp_map_find<ArgPack,param::tag::rr>
297                   , void
298                 >::value
299               , "param::tag::rr must be found in ArgPack"
300             );
301             static_assert(
302                 std::is_same<
303                     boost::mp11::mp_map_find<ArgPack,param::tag::a0>
304                   , void
305                 >::value
306               , "param::tag::a0 must not be found in ArgPack"
307             );
308             static_assert(
309                 std::is_same<
310                     boost::mp11::mp_map_find<ArgPack,param::tag::a1>
311                   , void
312                 >::value
313               , "param::tag::a1 must not be found in ArgPack"
314             );
315             static_assert(
316                 std::is_same<
317                     boost::mp11::mp_map_find<ArgPack,param::tag::a2>
318                   , void
319                 >::value
320               , "param::tag::a2 must not be found in ArgPack"
321             );
322             static_assert(
323                 std::is_same<
324                     boost::mp11::mp_map_find<ArgPack,param::tag::a3>
325                   , void
326                 >::value
327               , "param::tag::a3 must not be found in ArgPack"
328             );
329 #endif  // BOOST_PARAMETER_CAN_USE_MP11
330             BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
331             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::rr>));
332             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lr>));
333             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lrc>));
334             BOOST_MPL_ASSERT_NOT((
335                 boost::mpl::has_key<ArgPack,param::tag::a0>
336             ));
337             BOOST_MPL_ASSERT_NOT((
338                 boost::mpl::has_key<ArgPack,param::tag::a1>
339             ));
340             BOOST_MPL_ASSERT_NOT((
341                 boost::mpl::has_key<ArgPack,param::tag::a2>
342             ));
343             BOOST_MPL_ASSERT_NOT((
344                 boost::mpl::has_key<ArgPack,param::tag::a3>
345             ));
346             BOOST_MPL_ASSERT((
347                 boost::mpl::equal_to<
348                     typename boost::mpl::count<ArgPack,param::tag::rr>::type
349                   , boost::mpl::int_<1>
350                 >
351             ));
352             BOOST_MPL_ASSERT((
353                 boost::mpl::equal_to<
354                     typename boost::mpl::count<ArgPack,param::tag::lr>::type
355                   , boost::mpl::int_<1>
356                 >
357             ));
358             BOOST_MPL_ASSERT((
359                 boost::mpl::equal_to<
360                     typename boost::mpl::count<ArgPack,param::tag::lrc>::type
361                   , boost::mpl::int_<1>
362                 >
363             ));
364             BOOST_MPL_ASSERT((
365                 typename boost::mpl::if_<
366                     boost::is_same<
367                         typename boost::mpl
368                         ::key_type<ArgPack,param::tag::rr>::type
369                       , param::tag::rr
370                     >
371                   , boost::mpl::true_
372                   , boost::mpl::false_
373                 >::type
374             ));
375             BOOST_MPL_ASSERT((
376                 typename boost::mpl::if_<
377                     boost::is_same<
378                         typename boost::mpl
379                         ::key_type<ArgPack,param::tag::lr>::type
380                       , param::tag::lr
381                     >
382                   , boost::mpl::true_
383                   , boost::mpl::false_
384                 >::type
385             ));
386             BOOST_MPL_ASSERT((
387                 typename boost::mpl::if_<
388                     boost::is_same<
389                         typename boost::mpl
390                         ::key_type<ArgPack,param::tag::lrc>::type
391                       , param::tag::lrc
392                     >
393                   , boost::mpl::true_
394                   , boost::mpl::false_
395                 >::type
396             ));
397             BOOST_MPL_ASSERT((
398                 typename boost::mpl::if_<
399                     boost::is_same<
400                         typename boost::mpl
401                         ::order<ArgPack,param::tag::rr>::type
402                       , boost::mpl::void_
403                     >
404                   , boost::mpl::false_
405                   , boost::mpl::true_
406                 >::type
407             ));
408             BOOST_MPL_ASSERT((
409                 typename boost::mpl::if_<
410                     boost::is_same<
411                         typename boost::mpl
412                         ::order<ArgPack,param::tag::lr>::type
413                       , boost::mpl::void_
414                     >
415                   , boost::mpl::false_
416                   , boost::mpl::true_
417                 >::type
418             ));
419             BOOST_MPL_ASSERT((
420                 typename boost::mpl::if_<
421                     boost::is_same<
422                         typename boost::mpl
423                         ::order<ArgPack,param::tag::lrc>::type
424                       , boost::mpl::void_
425                     >
426                   , boost::mpl::false_
427                   , boost::mpl::true_
428                 >::type
429             ));
430         }
431     };
432 } // namespace test
433 
434 #include <utility>
435 
436 namespace test {
437 
lvalue_const_pair()438     std::pair<int,int> const& lvalue_const_pair()
439     {
440         static std::pair<int,int> const clp = std::pair<int,int>(7, 10);
441         return clp;
442     }
443 
444     struct H
445     {
446         std::pair<int,int> i;
447         std::pair<int,int>& j;
448         std::pair<int,int> const& k;
449 
450         template <typename ArgPack>
Htest::H451         H(ArgPack const& args)
452           : i(args[param::_rr | test::lvalue_const_pair()])
453           , j(args[param::_lr])
454           , k(args[param::_lrc])
455         {
456 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
457             static_assert(
458                 boost::mp11::mp_map_contains<ArgPack,param::tag::lrc>::value
459               , "param::tag::lrc must be in ArgPack"
460             );
461             static_assert(
462                 boost::mp11::mp_map_contains<ArgPack,param::tag::lr>::value
463               , "param::tag::lr must be in ArgPack"
464             );
465             static_assert(
466                 !std::is_same<
467                     boost::mp11::mp_map_find<ArgPack,param::tag::lrc>
468                   , void
469                 >::value
470               , "param::tag::lrc must be found in ArgPack"
471             );
472             static_assert(
473                 !std::is_same<
474                     boost::mp11::mp_map_find<ArgPack,param::tag::lr>
475                   , void
476                 >::value
477               , "param::tag::lr must be found in ArgPack"
478             );
479 #endif  // BOOST_PARAMETER_CAN_USE_MP11
480             BOOST_MPL_ASSERT((boost::parameter::is_argument_pack<ArgPack>));
481             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lr>));
482             BOOST_MPL_ASSERT((boost::mpl::has_key<ArgPack,param::tag::lrc>));
483             BOOST_MPL_ASSERT((
484                 boost::mpl::equal_to<
485                     typename boost::mpl::count<ArgPack,param::tag::lr>::type
486                   , boost::mpl::int_<1>
487                 >
488             ));
489             BOOST_MPL_ASSERT((
490                 boost::mpl::equal_to<
491                     typename boost::mpl::count<ArgPack,param::tag::lrc>::type
492                   , boost::mpl::int_<1>
493                 >
494             ));
495             BOOST_MPL_ASSERT((
496                 typename boost::mpl::if_<
497                     boost::is_same<
498                         typename boost::mpl
499                         ::key_type<ArgPack,param::tag::lr>::type
500                       , param::tag::lr
501                     >
502                   , boost::mpl::true_
503                   , boost::mpl::false_
504                 >::type
505             ));
506             BOOST_MPL_ASSERT((
507                 typename boost::mpl::if_<
508                     boost::is_same<
509                         typename boost::mpl
510                         ::key_type<ArgPack,param::tag::lrc>::type
511                       , param::tag::lrc
512                     >
513                   , boost::mpl::true_
514                   , boost::mpl::false_
515                 >::type
516             ));
517             BOOST_MPL_ASSERT((
518                 typename boost::mpl::if_<
519                     boost::is_same<
520                         typename boost::mpl
521                         ::order<ArgPack,param::tag::lr>::type
522                       , boost::mpl::void_
523                     >
524                   , boost::mpl::false_
525                   , boost::mpl::true_
526                 >::type
527             ));
528             BOOST_MPL_ASSERT((
529                 typename boost::mpl::if_<
530                     boost::is_same<
531                         typename boost::mpl
532                         ::order<ArgPack,param::tag::lrc>::type
533                       , boost::mpl::void_
534                     >
535                   , boost::mpl::false_
536                   , boost::mpl::true_
537                 >::type
538             ));
539         }
540     };
541 } // namespace test
542 
543 #include <boost/core/lightweight_test.hpp>
544 
test_compose0()545 void test_compose0()
546 {
547 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
548     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
549     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
550     // MSVC 11.0 on AppVeyor fails without this workaround.
551     test::A a((
552         param::a0 = 1
553       , param::a1 = 13
554       , param::_a2 = std::function<double()>(test::D)
555     ));
556 #else
557     test::A a((param::a0 = 1, param::a1 = 13, param::_a2 = test::D));
558 #endif
559     BOOST_TEST_EQ(1, a.i);
560     BOOST_TEST_EQ(13, a.j);
561 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
562     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
563     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
564     // MSVC 11.0 on AppVeyor fails without this workaround.
565     test::B b0((
566         param::tag::a1::a_one = 13
567       , param::_a2 = std::function<float()>(test::F)
568     ));
569 #else
570     test::B b0((param::tag::a1::a_one = 13, param::_a2 = test::F));
571 #endif
572     BOOST_TEST_EQ(1, b0.i);
573     BOOST_TEST_EQ(13, b0.j);
574     BOOST_TEST_EQ(4.0f, b0.k());
575     BOOST_TEST_EQ(2.5, b0.l());
576 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
577     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
578     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
579     // MSVC 11.0 on AppVeyor fails without this workaround.
580     test::B b1((
581         param::_a3 = std::function<double()>(test::D)
582       , param::a1 = 13
583     ));
584 #else
585     test::B b1((param::_a3 = test::D, param::a1 = 13));
586 #endif
587     BOOST_TEST_EQ(1, b1.i);
588     BOOST_TEST_EQ(13, b1.j);
589     BOOST_TEST_EQ(4.625f, b1.k());
590     BOOST_TEST_EQ(198.9, b1.l());
591     int x = 23;
592     int const y = 42;
593 #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_0)
594     test::G g((param::_lr = 15, param::_rr = 16, param::_lrc = y));
595 #else
596     test::G g((param::_lr = x, param::_rr = 16, param::_lrc = y));
597 #endif
598     BOOST_TEST_EQ(16, g.i);
599     BOOST_TEST_EQ(23, g.j);
600     BOOST_TEST_EQ(42, g.k);
601     x = 1;
602     BOOST_TEST_EQ(1, g.j);
603     std::pair<int,int> p1(8, 9);
604     std::pair<int,int> const p2(11, 12);
605     test::H h0((param::_lr = p1, param::_lrc = p2));
606 #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_1)
607     test::H h1((
608         param::_lr = p2
609       , param::_rr = std::make_pair(7, 10)
610       , param::_lrc = p2
611     ));
612 #else
613     test::H h1((
614         param::_lr = p1
615       , param::_rr = std::make_pair(7, 10)
616       , param::_lrc = p2
617     ));
618 #endif
619     BOOST_TEST_EQ(h0.i.first, h1.i.first);
620     BOOST_TEST_EQ(h0.i.second, h1.i.second);
621     BOOST_TEST_EQ(p1.first, h1.j.first);
622     BOOST_TEST_EQ(p1.second, h1.j.second);
623     BOOST_TEST_EQ(p2.first, h1.k.first);
624     BOOST_TEST_EQ(p2.second, h1.k.second);
625     p1.first = 1;
626     BOOST_TEST_EQ(p1.first, h1.j.first);
627 }
628 
629 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) || \
630     (2 < BOOST_PARAMETER_COMPOSE_MAX_ARITY)
631 #include <boost/parameter/compose.hpp>
632 
test_compose1()633 void test_compose1()
634 {
635 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
636     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
637     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
638     // MSVC 11.0 on AppVeyor fails without this workaround.
639     test::A a(boost::parameter::compose(
640         param::a0 = 1
641       , param::a1 = 13
642       , param::_a2 = std::function<double()>(test::D)
643     ));
644 #else
645     test::A a(boost::parameter::compose(
646         param::a0 = 1
647       , param::a1 = 13
648       , param::_a2 = test::D
649     ));
650 #endif
651     BOOST_TEST_EQ(1, a.i);
652     BOOST_TEST_EQ(13, a.j);
653 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
654     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
655     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
656     // MSVC 11.0 on AppVeyor fails without this workaround.
657     test::B b0(boost::parameter::compose(
658         param::tag::a1::a_one = 13
659       , param::_a2 = std::function<float()>(test::F)
660     ));
661 #else
662     test::B b0(boost::parameter::compose(
663         param::tag::a1::a_one = 13
664       , param::_a2 = test::F
665     ));
666 #endif
667     BOOST_TEST_EQ(1, b0.i);
668     BOOST_TEST_EQ(13, b0.j);
669     BOOST_TEST_EQ(4.0f, b0.k());
670     BOOST_TEST_EQ(2.5, b0.l());
671 #if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) && \
672     BOOST_WORKAROUND(BOOST_MSVC, >= 1700) && \
673     BOOST_WORKAROUND(BOOST_MSVC, < 1800)
674     // MSVC 11.0 on AppVeyor fails without this workaround.
675     test::B b1(boost::parameter::compose(
676         param::_a3 = std::function<double()>(test::D)
677       , param::a1 = 13
678     ));
679 #else
680     test::B b1(boost::parameter::compose(
681         param::_a3 = test::D
682       , param::a1 = 13
683     ));
684 #endif
685     BOOST_TEST_EQ(1, b1.i);
686     BOOST_TEST_EQ(13, b1.j);
687     BOOST_TEST_EQ(4.625f, b1.k());
688     BOOST_TEST_EQ(198.9, b1.l());
689     int x = 23;
690     int const y = 42;
691 #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_0)
692     test::G g(boost::parameter::compose(
693         param::_lr = 15
694       , param::_rr = 16
695       , param::_lrc = y
696     ));
697 #else
698     test::G g(boost::parameter::compose(
699         param::_lr = x
700       , param::_rr = 16
701       , param::_lrc = y
702     ));
703 #endif
704     BOOST_TEST_EQ(16, g.i);
705     BOOST_TEST_EQ(23, g.j);
706     BOOST_TEST_EQ(42, g.k);
707     x = 1;
708     BOOST_TEST_EQ(1, g.j);
709     std::pair<int,int> p1(8, 9);
710     std::pair<int,int> const p2(11, 12);
711     test::H h0(boost::parameter::compose(param::_lr = p1, param::_lrc = p2));
712 #if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_1)
713     test::H h1(boost::parameter::compose(
714         param::_lr = p2
715       , param::_rr = std::make_pair(7, 10)
716       , param::_lrc = p2
717     ));
718 #else
719     test::H h1(boost::parameter::compose(
720         param::_lr = p1
721       , param::_rr = std::make_pair(7, 10)
722       , param::_lrc = p2
723     ));
724 #endif
725     BOOST_TEST_EQ(h0.i.first, h1.i.first);
726     BOOST_TEST_EQ(h0.i.second, h1.i.second);
727     BOOST_TEST_EQ(p1.first, h1.j.first);
728     BOOST_TEST_EQ(p1.second, h1.j.second);
729     BOOST_TEST_EQ(p2.first, h1.k.first);
730     BOOST_TEST_EQ(p2.second, h1.k.second);
731     p1.first = 1;
732     BOOST_TEST_EQ(p1.first, h1.j.first);
733 }
734 
735 #endif  // can invoke boost::parameter::compose
736 
main()737 int main()
738 {
739     test_compose0();
740 #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING) || \
741     (2 < BOOST_PARAMETER_COMPOSE_MAX_ARITY)
742     test_compose1();
743 #endif
744     return boost::report_errors();
745 }
746 
747