// (C) Copyright Eric Niebler 2011 // Use, modification and distribution are 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) // See http://www.boost.org/libs/config for more information. // MACRO: BOOST_NO_CXX11_DECLTYPE_N3276 // TITLE: C++0x decltype v1.1 unavailable // DESCRIPTION: The compiler does not support extensions to C++0x // decltype as described in N3276 and accepted in Madrid, // March 2011: // namespace boost_no_cxx11_decltype_n3276 { // A simplified result_of implementation. // that uses decltype. template struct result_of; template T& declvar(); // use decltype template struct result_of { typedef decltype(declvar()(declvar())) type; }; template struct result_of { typedef decltype(declvar()(declvar(), declvar())) type; }; // simple tuple type template struct tuple; template struct tuple { A0 a0_; tuple(A0 const &a0) : a0_(a0) {} }; template struct tuple { A0 a0_; A1 a1_; tuple(A0 const &a0, A1 const & a1) : a0_(a0) , a1_(a1) {} }; // A node in an expression tree template // Args is a tuple. struct Expr; // A function object that builds expression nodes template struct MakeExpr { template Expr > operator()(T const & t) const { return Expr >(tuple(t)); } template Expr > operator()(T const & t, U const & u) const { return Expr >(tuple(t, u)); } }; // Here are tag types that encode in an expression node // what operation created the node. struct Terminal; struct BinaryPlus; struct FunctionCall; typedef MakeExpr MakeTerminal; typedef MakeExpr MakeBinaryPlus; typedef MakeExpr MakeFunctionCall; template struct Expr { Args args_; explicit Expr(Args const & t) : args_(t) {} // An overloaded operator+ that creates a binary plus node template typename result_of)>::type operator+(Expr const &right) const { return MakeBinaryPlus()(*this, right); } // An overloaded function call operator that creates a unary // function call node typename result_of::type operator()() const { return MakeFunctionCall()(*this); } }; int test() { // This is a terminal in an expression tree Expr > i = MakeTerminal()(42); i + i; // OK, this creates a binary plus node. i(); // OK, this creates a unary function-call node. // NOTE: If N3276 has not been implemented, this // line will set off an infinite cascade of template // instantiations that will run the compiler out of // memory. return 0; } }