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 + -
显示快捷键?