// Copyright 2005 Eric Niebler. // Distributed under 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 #include #include #include #include #include namespace impl_ { typedef char yes_type; typedef char (&no_type)[2]; yes_type is_true(boost::mpl::true_ *); no_type is_true(boost::mpl::false_ *); #define PROTECT(expr) \ (static_cast *>(0)) template inline boost::mpl::and_ *and_(Bool1 *, Bool2 *) { return 0; } template inline boost::mpl::not_ *not_(Bool *) { return 0; } template inline boost::mpl::false_ *is_rvalue(T &, int) { return 0; } template inline boost::mpl::true_ *is_rvalue(T const &, ...) { return 0; } template inline boost::is_array *is_array(T const &) { return 0; } template struct rvalue_probe { // can't ever return an array by value typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_, int, T>::type value_type; operator value_type(); operator T &() const; }; template rvalue_probe const make_probe(T const &t); template struct rvalue; } // namespace impl_ #define IS_RVALUE_IMPL(COL) \ impl_::and_(impl_::not_(impl_::is_array(COL)) \ , PROTECT(impl_::is_rvalue((true ? impl_::make_probe(COL) : (COL)), 0))) #define IS_RVALUE(COL) (1==sizeof(impl_::is_true(IS_RVALUE_IMPL(COL)))) #define IS_RVALUE_T(COL) impl_::rvalue ///////////////////////////////////////////////////////////////////////// // test begins here // struct foo { foo() {} }; foo const make_foo() { return foo(); } int main() { int i = 0; int const ci = 0; //~ char test1[ IS_RVALUE(1) ]; //~ char test2[ IS_RVALUE(int()) ]; //~ char test3[ ! IS_RVALUE(i) ]; //~ char test4[ ! IS_RVALUE(ci) ]; IS_RVALUE_T(1) test1; IS_RVALUE_T(int()) test2; IS_RVALUE_T(i) test3; IS_RVALUE_T(ci) test4; foo f; foo const cf; typedef foo const cfoo; //~ char test5[ IS_RVALUE(foo()) ]; //~ char test6[ IS_RVALUE(cfoo()) ]; //~ char test7[ IS_RVALUE(make_foo()) ]; //~ char test8[ ! IS_RVALUE(f) ]; //~ char test9[ ! IS_RVALUE(cf) ]; IS_RVALUE_T(foo()) test5; IS_RVALUE_T(cfoo()) test6; IS_RVALUE_T(make_foo()) test7; IS_RVALUE_T(f) test8; IS_RVALUE_T(cf) test9; int rgi[2] = {1,2}; int const crgi[2] = {1,2}; //~ char test10[ ! IS_RVALUE(rgi) ]; //~ char test11[ ! IS_RVALUE(crgi) ]; IS_RVALUE_T(rgi) test10; IS_RVALUE_T(crgi) test11; return 0; }