1 // Copyright Daniel Wallin 2006.
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     (BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY < 2)
13 #error Define BOOST_PARAMETER_EXPONENTIAL_OVERLOAD_THRESHOLD_ARITY \
14 as 2 or greater.
15 #endif
16 
17 #include <boost/parameter/preprocessor.hpp>
18 #include <boost/parameter/name.hpp>
19 #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
20 #include <boost/tuple/tuple.hpp>
21 #include <boost/core/enable_if.hpp>
22 #include <string>
23 
24 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
25 #include <boost/mp11/utility.hpp>
26 #include <type_traits>
27 #else
28 #include <boost/mpl/bool.hpp>
29 #include <boost/mpl/if.hpp>
30 #include <boost/type_traits/is_convertible.hpp>
31 #endif
32 
33 namespace test {
34 
35     BOOST_PARAMETER_NAME(x)
36 
37 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
38     template <typename T, typename Args>
39     using predicate = std::is_convertible<T,char const*>;
40 
41     BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag,
42         (deduced
43             (optional
44                 (x
45                   , *(boost::mp11::mp_quote<test::predicate>)
46                   , static_cast<char const*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
47                 )
48             )
49         )
50     )
51 #else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
52     struct predicate
53     {
54         template <typename T, typename Args>
55         struct apply
56           : boost::mpl::if_<
57                 boost::is_convertible<T,char const*>
58               , boost::mpl::true_
59               , boost::mpl::false_
60             >
61         {
62         };
63     };
64 
65     BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag,
66         (deduced
67             (optional
68                 (x
69                   , *(test::predicate)
70                   , static_cast<char const*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
71                 )
72             )
73         )
74     )
75 #endif  // BOOST_PARAMETER_CAN_USE_MP11
76     {
77         return 1;
78     }
79 
80     template <typename A0>
81     typename boost::enable_if<
82 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
83         std::is_same<int,A0>
84 #else
85         typename boost::mpl::if_<
86             boost::is_same<int,A0>
87           , boost::mpl::true_
88           , boost::mpl::false_
89         >::type
90 #endif
91       , int
92     >::type
sfinae(A0 const & a0)93         sfinae(A0 const& a0)
94     {
95         return 0;
96     }
97 } // namespace test
98 
99 #include <boost/core/lightweight_test.hpp>
100 
main()101 int main()
102 {
103     BOOST_TEST_EQ(1, test::sfinae());
104     BOOST_TEST_EQ(1, test::sfinae("foo"));
105     BOOST_TEST_EQ(0, test::sfinae(1));
106     return boost::report_errors();
107 }
108 
109