1 // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
2 // distribution is subject to 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.hpp>
7 #include <boost/parameter/match.hpp>
8 #include <boost/detail/lightweight_test.hpp>
9 #include <string>
10 #include <boost/type_traits/is_convertible.hpp>
11 
12 #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
13 # include <boost/utility/enable_if.hpp>
14 # include <boost/type_traits/is_same.hpp>
15 #endif
16 
17 namespace test
18 {
19   BOOST_PARAMETER_KEYWORD(keywords,name)
20   BOOST_PARAMETER_KEYWORD(keywords,value)
21 
22   using namespace boost::parameter;
23 
24   struct f_parameters
25     : parameters<
26           optional<
27               keywords::name
28             , boost::is_convertible<boost::mpl::_, std::string>
29           >
30         , optional<
31               keywords::value
32             , boost::is_convertible<boost::mpl::_, float>
33           >
34       >
35   {};
36 
37   // The use of assert_equal_string is just a nasty workaround for a
38   // vc++ 6 ICE.
assert_equal_string(std::string x,std::string y)39   void assert_equal_string(std::string x, std::string y)
40   {
41         BOOST_TEST(x == y);
42   }
43 
44   template<class P>
f_impl(P const & p)45   void f_impl(P const& p)
46   {
47       float v = p[value | 3.f];
48       BOOST_TEST(v == 3.f);
49       assert_equal_string(p[name | "bar"], "foo");
50   }
51 
f()52   void f()
53   {
54       f_impl(f_parameters()());
55   }
56 
57   template<class A0>
58   void f(
59       A0 const& a0
60     , BOOST_PARAMETER_MATCH(f_parameters, (A0), args))
61   {
62       f_impl(args(a0));
63   }
64 
65   template<class A0, class A1>
66   void f(
67       A0 const& a0, A1 const& a1
68     , BOOST_PARAMETER_MATCH(f_parameters,(A0)(A1), args))
69   {
70       f_impl(args(a0, a1));
71   }
72 
73 #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
74   // On compilers that actually support SFINAE, add another overload
75   // that is an equally good match and can only be in the overload set
76   // when the others are not.  This tests that the SFINAE is actually
77   // working.  On all other compilers we're just checking that
78   // everything about SFINAE-enabled code will work, except of course
79   // the SFINAE.
80   template<class A0, class A1>
81   typename boost::enable_if<boost::is_same<int,A0>, int>::type
f(A0 const & a0,A1 const & a1)82   f(A0 const& a0, A1 const& a1)
83   {
84       return 0;
85   }
86 #endif
87 } // namespace test
88 
main()89 int main()
90 {
91     using test::name;
92     using test::value;
93     using test::f;
94 
95     f("foo");
96     f("foo", 3.f);
97     f(value = 3.f, name = "foo");
98 
99 #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
100     BOOST_TEST(f(3, 4) == 0);
101 #endif
102     return boost::report_errors();
103 }
104 
105