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 \
14as 3 or greater.
15#endif
16#endif
17
18#include <boost/parameter/name.hpp>
19
20namespace 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
34namespace 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
59namespace 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
78namespace 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
103namespace 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
135namespace 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
163int 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

source code of boost/libs/parameter/test/sfinae.cpp