123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // (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:
- // <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf>
- namespace boost_no_cxx11_decltype_n3276 {
- // A simplified result_of implementation.
- // that uses decltype.
- template<typename Sig>
- struct result_of;
- template<typename T>
- T& declvar();
- // use decltype
- template<typename Fun, typename T>
- struct result_of<Fun(T)>
- {
- typedef decltype(declvar<Fun>()(declvar<T>())) type;
- };
- template<typename Fun, typename T, typename U>
- struct result_of<Fun(T, U)>
- {
- typedef decltype(declvar<Fun>()(declvar<T>(), declvar<U>())) type;
- };
- // simple tuple type
- template<typename A0 = void, typename A1 = void, typename A2 = void>
- struct tuple;
- template<typename A0>
- struct tuple<A0, void, void>
- {
- A0 a0_;
- tuple(A0 const &a0)
- : a0_(a0)
- {}
- };
- template<typename A0, typename A1>
- struct tuple<A0, A1>
- {
- A0 a0_;
- A1 a1_;
- tuple(A0 const &a0, A1 const & a1)
- : a0_(a0)
- , a1_(a1)
- {}
- };
- // A node in an expression tree
- template<class Tag, class Args> // Args is a tuple.
- struct Expr;
- // A function object that builds expression nodes
- template<class Tag>
- struct MakeExpr
- {
- template<class T>
- Expr<Tag, tuple<T> > operator()(T const & t) const
- {
- return Expr<Tag, tuple<T> >(tuple<T>(t));
- }
- template<class T, typename U>
- Expr<Tag, tuple<T, U> > operator()(T const & t, U const & u) const
- {
- return Expr<Tag, tuple<T, U> >(tuple<T, U>(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<Terminal> MakeTerminal;
- typedef MakeExpr<BinaryPlus> MakeBinaryPlus;
- typedef MakeExpr<FunctionCall> MakeFunctionCall;
- template<class Tag, class Args>
- struct Expr
- {
- Args args_;
- explicit Expr(Args const & t) : args_(t) {}
- // An overloaded operator+ that creates a binary plus node
- template<typename RTag, typename RArgs>
- typename result_of<MakeBinaryPlus(Expr, Expr<RTag, RArgs>)>::type
- operator+(Expr<RTag, RArgs> const &right) const
- {
- return MakeBinaryPlus()(*this, right);
- }
- // An overloaded function call operator that creates a unary
- // function call node
- typename result_of<MakeFunctionCall(Expr)>::type
- operator()() const
- {
- return MakeFunctionCall()(*this);
- }
- };
- int test()
- {
- // This is a terminal in an expression tree
- Expr<Terminal, tuple<int> > 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;
- }
- }
|