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. |
82 | void assert_equal_string(std::string x, std::string y) |
83 | { |
84 | BOOST_TEST(x == y); |
85 | } |
86 | |
87 | template <typename 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(x: p[test::name | "bar" ], y: "foo" ); |
93 | } |
94 | |
95 | void f() |
96 | { |
97 | test::f_impl(p: 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 |
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 | |
163 | int main() |
164 | { |
165 | test::f(a0: "foo" ); |
166 | test::f(a0: "foo" , a1: 3.f); |
167 | test::f(a0: test::value = 3.f, a1: 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 | |