preprocessor.cpp

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

CPP
483
字号
// 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/keyword.hpp>#include <boost/type_traits/is_const.hpp>#include <string>#include "basics.hpp"#ifndef BOOST_NO_SFINAE# include <boost/utility/enable_if.hpp>#endifnamespace test {BOOST_PARAMETER_BASIC_FUNCTION((int), f, tag,    (required      (tester, *)      (name, *)    )    (optional      (value, *)      (out(index), (int))    )){    typedef typename boost::parameter::binding<        Args, tag::index, int&    >::type index_type;    BOOST_MPL_ASSERT((boost::is_same<index_type, int&>));    args[tester](        args[name]      , args[value | 1.f]      , args[index | 2]    );    return 1;}BOOST_PARAMETER_BASIC_FUNCTION((int), g, tag,    (required      (tester, *)      (name, *)    )    (optional      (value, *)      (out(index), (int))    )){    typedef typename boost::parameter::binding<        Args, tag::index, int const&    >::type index_type;    BOOST_MPL_ASSERT((boost::is_same<index_type, int const&>));    args[tester](        args[name]      , args[value | 1.f]      , args[index | 2]    );    return 1;}BOOST_PARAMETER_FUNCTION((int), h, tag,    (required      (tester, *)      (name, *)    )    (optional      (value, *, 1.f)      (out(index), (int), 2)    )){# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \  && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)    BOOST_MPL_ASSERT((boost::is_same<index_type, int>));# endif    tester(        name      , value      , index    );    return 1;}BOOST_PARAMETER_FUNCTION((int), h2, tag,    (required      (tester, *)      (name, *)    )    (optional      (value, *, 1.f)      (out(index), (int), (int)value * 2)    )){# if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) \  && !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)    BOOST_MPL_ASSERT((boost::is_same<index_type, int>));# endif    tester(        name      , value      , index    );    return 1;}struct base{    template <class Args>    base(Args const& args)    {        args[tester](            args[name]          , args[value | 1.f]          , args[index | 2]        );    }};struct class_ : base{    BOOST_PARAMETER_CONSTRUCTOR(class_, (base), tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *)          (index, *)        )    )    BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *)          (index, *)        )    )    {        args[tester](            args[name]          , args[value | 1.f]          , args[index | 2]        );        return 1;    }    BOOST_PARAMETER_BASIC_CONST_MEMBER_FUNCTION((int), f, tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *)          (index, *)        )    )    {        args[tester](            args[name]          , args[value | 1.f]          , args[index | 2]        );        return 1;    }    BOOST_PARAMETER_MEMBER_FUNCTION((int), f2, tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *, 1.f)          (index, *, 2)        )    )    {        tester(name, value, index);        return 1;    }    BOOST_PARAMETER_CONST_MEMBER_FUNCTION((int), f2, tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *, 1.f)          (index, *, 2)        )    )    {        tester(name, value, index);        return 1;    }    BOOST_PARAMETER_MEMBER_FUNCTION((int), static f_static, tag,        (required          (tester, *)          (name, *)        )        (optional          (value, *, 1.f)          (index, *, 2)        )    )    {        tester(name, value, index);        return 1;    }};BOOST_PARAMETER_FUNCTION(    (int), sfinae, tag,    (required       (name, (std::string))    )){    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#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))// Sun has problems with this syntax:////   template1< r* ( template2<x> ) >//// Workaround: factor template2<x> into a separate typedeftypedef boost::is_convertible<boost::mpl::_, std::string> predicate;BOOST_PARAMETER_FUNCTION(    (int), sfinae1, tag,    (required       (name, *(predicate))    )){    return 1;}#elseBOOST_PARAMETER_FUNCTION(    (int), sfinae1, tag,    (required       (name, *(boost::is_convertible<boost::mpl::_, std::string>))    )){    return 1;}#endif #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>::typesfinae1(A0 const& a0){    return 0;}#endiftemplate <class T>T const& as_lvalue(T const& x){    return x;}struct udt{    udt(int foo, int bar)      : foo(foo)      , bar(bar)    {}    int foo;    int bar;};BOOST_PARAMETER_FUNCTION((int), lazy_defaults, tag,    (required      (name, *)    )    (optional      (value, *, name.foo)      (index, *, name.bar)    )){    return 0;}} // namespace testint main(){    using namespace test;    f(        values(S("foo"), 1.f, 2)      , S("foo")    );    f(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    int index_lvalue = 2;    f(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")      , value = 1.f      , test::index = index_lvalue    );    f(        values(S("foo"), 1.f, 2)      , S("foo")      , 1.f      , index_lvalue    );    g(        values(S("foo"), 1.f, 2)      , S("foo")      , 1.f#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)      , as_lvalue(2)#else      , 2#endif    );    h(        values(S("foo"), 1.f, 2)      , S("foo")      , 1.f#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)      , as_lvalue(2)#else      , 2#endif    );    h2(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")      , value = 1.f    );    class_ x(        values(S("foo"), 1.f, 2)      , S("foo"), test::index = 2    );    x.f(        values(S("foo"), 1.f, 2)      , S("foo")    );    x.f(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    x.f2(        values(S("foo"), 1.f, 2)      , S("foo")    );    x.f2(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    class_ const& x_const = x;    x_const.f(        values(S("foo"), 1.f, 2)      , S("foo")    );    x_const.f(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    x_const.f2(        values(S("foo"), 1.f, 2)      , S("foo")    );    x_const.f2(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    x_const.f2(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );    class_::f_static(        values(S("foo"), 1.f, 2)      , S("foo")    );    class_::f_static(        tester = values(S("foo"), 1.f, 2)      , name = S("foo")    );#if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))    assert(sfinae("foo") == 1);    assert(sfinae(1) == 0);# if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))    // Sun actually eliminates the desired overload for some reason.    // Disabling this part of the test because SFINAE abilities are    // not the point of this test.    assert(sfinae1("foo") == 1);# endif        assert(sfinae1(1) == 0);#endif    lazy_defaults(        name = udt(0,1)    );    lazy_defaults(        name = 0      , value = 1      , test::index = 2    );    return 0;}

⌨️ 快捷键说明

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