1 // Copyright David Abrahams, Daniel Wallin 2003.
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 < 2)
9 #error Define BOOST_PARAMETER_MAX_ARITY as 2 or greater.
10 #endif
11 #if !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
12 #if (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 3)
13 #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \
14 as 3 or greater.
15 #endif
16 #endif
17 
18 #include <boost/parameter/name.hpp>
19 
20 namespace test {
21 
22     BOOST_PARAMETER_NAME((name, keywords) in(name))
23     BOOST_PARAMETER_NAME((value, keywords) in(value))
24 } // namespace test
25 
26 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
27 #include <type_traits>
28 #else
29 #include <boost/mpl/bool.hpp>
30 #include <boost/mpl/if.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
32 #endif
33 
34 namespace test {
35 
36     template <typename To>
37     struct f_predicate
38     {
39         template <typename From, typename Args>
40 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
41         using fn = std::is_convertible<From,To>;
42 #else
43         struct apply
44           : boost::mpl::if_<
45                 boost::is_convertible<From,To>
46               , boost::mpl::true_
47               , boost::mpl::false_
48             >
49         {
50         };
51 #endif
52     };
53 } // namespace test
54 
55 #include <boost/parameter/parameters.hpp>
56 #include <boost/parameter/optional.hpp>
57 #include <string>
58 
59 namespace test {
60 
61     struct f_parameters
62       : boost::parameter::parameters<
63             boost::parameter::optional<
64                 test::keywords::name
65               , test::f_predicate<std::string>
66             >
67           , boost::parameter::optional<
68                 test::keywords::value
69               , test::f_predicate<float>
70             >
71         >
72     {
73     };
74 } // namespace test
75 
76 #include <boost/core/lightweight_test.hpp>
77 
78 namespace test {
79 
80     // The use of assert_equal_string is just a nasty workaround for a
81     // vc++ 6 ICE.
assert_equal_string(std::string x,std::string y)82     void assert_equal_string(std::string x, std::string y)
83     {
84         BOOST_TEST(x == y);
85     }
86 
87     template <typename P>
f_impl(P const & p)88     void f_impl(P const& p)
89     {
90         float v = p[test::value | 3.f];
91         BOOST_TEST_EQ(v, 3.f);
92         test::assert_equal_string(p[test::name | "bar"], "foo");
93     }
94 
f()95     void f()
96     {
97         test::f_impl(f_parameters()());
98     }
99 } // namespace test
100 
101 #include <boost/parameter/match.hpp>
102 
103 namespace test {
104 
105     template <typename A0>
106     void
107         f(
108             A0 const& a0
109           , BOOST_PARAMETER_MATCH(f_parameters, (A0), args)
110         )
111     {
112         test::f_impl(args(a0));
113     }
114 
115     template <typename A0, typename A1>
116     void
117         f(
118             A0 const& a0
119           , A1 const& a1
120           , BOOST_PARAMETER_MATCH(f_parameters, (A0)(A1), args)
121         )
122     {
123         test::f_impl(args(a0, a1));
124     }
125 } // namespace test
126 
127 #if !defined(BOOST_NO_SFINAE) && \
128     !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592))
129 #include <boost/core/enable_if.hpp>
130 
131 #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
132 #include <boost/type_traits/is_same.hpp>
133 #endif
134 
135 namespace test {
136 
137     // On compilers that actually support SFINAE, add another overload that is
138     // an equally good match and can only be in the overload set when the
139     // others are not.  This tests that the SFINAE is actually working.  On
140     // all other compilers we're just checking that everything about
141     // SFINAE-enabled code will work, except of course the SFINAE.
142     template <typename A0, typename A1>
143     typename boost::enable_if<
144 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
145         std::is_same<int,A0>
146 #else
147         typename boost::mpl::if_<
148             boost::is_same<int,A0>
149           , boost::mpl::true_
150           , boost::mpl::false_
151         >::type
152 #endif
153       , int
154     >::type
f(A0 const & a0,A1 const & a1)155         f(A0 const& a0, A1 const& a1)
156     {
157         return 0;
158     }
159 } // namespace test
160 
161 #endif  // SFINAE enabled, no Borland workarounds needed.
162 
main()163 int main()
164 {
165     test::f("foo");
166     test::f("foo", 3.f);
167     test::f(test::value = 3.f, test::name = "foo");
168 #if !defined(BOOST_NO_SFINAE) && \
169     !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592))
170     BOOST_TEST_EQ(0, test::f(3, 4));
171 #endif
172     return boost::report_errors();
173 }
174 
175