2 // (C) Copyright Eric Niebler 2011
4 // Use, modification and distribution are subject to the
5 // Boost Software License, Version 1.0. (See accompanying file
6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 // See http://www.boost.org/libs/config for more information.
10 // MACRO: BOOST_NO_CXX11_DECLTYPE_N3276
11 // TITLE: C++0x decltype v1.1 unavailable
12 // DESCRIPTION: The compiler does not support extensions to C++0x
13 // decltype as described in N3276 and accepted in Madrid,
15 // <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf>
17 namespace boost_no_cxx11_decltype_n3276 {
19 // A simplified result_of implementation.
20 // that uses decltype.
21 template<typename Sig>
28 template<typename Fun, typename T>
29 struct result_of<Fun(T)>
31 typedef decltype(declvar<Fun>()(declvar<T>())) type;
34 template<typename Fun, typename T, typename U>
35 struct result_of<Fun(T, U)>
37 typedef decltype(declvar<Fun>()(declvar<T>(), declvar<U>())) type;
41 template<typename A0 = void, typename A1 = void, typename A2 = void>
45 struct tuple<A0, void, void>
54 template<typename A0, typename A1>
60 tuple(A0 const &a0, A1 const & a1)
66 // A node in an expression tree
67 template<class Tag, class Args> // Args is a tuple.
70 // A function object that builds expression nodes
75 Expr<Tag, tuple<T> > operator()(T const & t) const
77 return Expr<Tag, tuple<T> >(tuple<T>(t));
80 template<class T, typename U>
81 Expr<Tag, tuple<T, U> > operator()(T const & t, U const & u) const
83 return Expr<Tag, tuple<T, U> >(tuple<T, U>(t, u));
87 // Here are tag types that encode in an expression node
88 // what operation created the node.
93 typedef MakeExpr<Terminal> MakeTerminal;
94 typedef MakeExpr<BinaryPlus> MakeBinaryPlus;
95 typedef MakeExpr<FunctionCall> MakeFunctionCall;
97 template<class Tag, class Args>
102 explicit Expr(Args const & t) : args_(t) {}
104 // An overloaded operator+ that creates a binary plus node
105 template<typename RTag, typename RArgs>
106 typename result_of<MakeBinaryPlus(Expr, Expr<RTag, RArgs>)>::type
107 operator+(Expr<RTag, RArgs> const &right) const
109 return MakeBinaryPlus()(*this, right);
112 // An overloaded function call operator that creates a unary
113 // function call node
114 typename result_of<MakeFunctionCall(Expr)>::type
117 return MakeFunctionCall()(*this);
123 // This is a terminal in an expression tree
124 Expr<Terminal, tuple<int> > i = MakeTerminal()(42);
126 i + i; // OK, this creates a binary plus node.
128 i(); // OK, this creates a unary function-call node.
129 // NOTE: If N3276 has not been implemented, this
130 // line will set off an infinite cascade of template
131 // instantiations that will run the compiler out of