preprocessor_deduced.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 172 行

CPP
172
字号
// Copyright Daniel Wallin 2006. Use, modification and distribution is// subject to the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#include <boost/parameter/preprocessor.hpp>#include <boost/parameter/name.hpp>#include <boost/type_traits/is_convertible.hpp>#include <boost/tuple/tuple.hpp>#include <string>#include "basics.hpp"#ifndef BOOST_NO_SFINAE# include <boost/utility/enable_if.hpp>#endifnamespace test {namespace mpl = boost::mpl;using mpl::_;using boost::is_convertible;BOOST_PARAMETER_NAME(expected)BOOST_PARAMETER_NAME(x)BOOST_PARAMETER_NAME(y)BOOST_PARAMETER_NAME(z)// Sun has problems with this syntax:////   template1< r* ( template2<x> ) >//// Workaround: factor template2<x> into a separate typedeftypedef is_convertible<_, int> predicate1;typedef is_convertible<_, std::string> predicate2;#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))BOOST_PARAMETER_FUNCTION((int), f, tag,    (required       (expected, *)    )    (deduced       (required          (x, *(predicate1))          (y, *(predicate2))       )    ))#elseBOOST_PARAMETER_FUNCTION((int), f, tag,    (required       (expected, *)    )    (deduced       (required          (x, *(is_convertible<_, int>))          (y, *(is_convertible<_, std::string>))       )    ))#endif {    assert(equal(x, boost::tuples::get<0>(expected)));    assert(equal(y, boost::tuples::get<1>(expected)));    return 1;}struct X {    X(int x = -1)      : x(x)    {}        bool operator==(X const& other) const    {        return x == other.x;    }        int x;};typedef is_convertible<_, X> predicate3;  // SunPro workaround; see aboveBOOST_PARAMETER_FUNCTION((int), g, tag,    (required      (expected, *)    )    (deduced       (required          (x, *(is_convertible<_, int>))          (y, *(is_convertible<_, std::string>))       )       (optional          (z, *(predicate3), X())       )    )){    assert(equal(x, boost::tuples::get<0>(expected)));    assert(equal(y, boost::tuples::get<1>(expected)));    assert(equal(z, boost::tuples::get<2>(expected)));    return 1;}BOOST_PARAMETER_FUNCTION(    (int), sfinae, tag,    (deduced      (required        (x, *(predicate2))      )    )){    return 1;}#ifndef BOOST_NO_SFINAE// On compilers that actually support SFINAE, add another overload// that is an equally good match and can only be in the overload set// when the others are not.  This tests that the SFINAE is actually// working.  On all other compilers we're just checking that// everything about SFINAE-enabled code will work, except of course// the SFINAE.template<class A0>typename boost::enable_if<boost::is_same<int,A0>, int>::typesfinae(A0 const& a0){    return 0;}#endif} // namespace testusing boost::make_tuple;// make_tuple doesn't work with char arrays.char const* str(char const* s){    return s;}int main(){    using namespace test;    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");    f(make_tuple(0, str("foo")), 0, "foo");    f(make_tuple(0, str("foo")), "foo", 0);    f(make_tuple(0, str("foo")), _y = "foo", 0);    f(make_tuple(0, str("foo")), _x = 0, "foo");    f(make_tuple(0, str("foo")), 0, _y = "foo");    g(make_tuple(0, str("foo"), X()), _x = 0, _y = "foo");    g(make_tuple(0, str("foo"), X()), 0, "foo");    g(make_tuple(0, str("foo"), X()), "foo", 0);    g(make_tuple(0, str("foo"), X()), _y = "foo", 0);       g(make_tuple(0, str("foo"), X()), _x = 0, "foo");    g(make_tuple(0, str("foo"), X()), 0, _y = "foo");    g(make_tuple(0, str("foo"), X(1)), 0, _y = "foo", X(1));    g(make_tuple(0, str("foo"), X(1)), X(1), 0, _y = "foo");#ifndef BOOST_NO_SFINAE    assert(sfinae("foo") == 1);    assert(sfinae(0) == 0);#endif    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?