]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/config/test/boost_no_decltype_n3276.ipp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / config / test / boost_no_decltype_n3276.ipp
1
2 // (C) Copyright Eric Niebler 2011
3
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)
7
8 // See http://www.boost.org/libs/config for more information.
9
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,
14 // March 2011:
15 // <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf>
16
17 namespace boost_no_cxx11_decltype_n3276 {
18
19 // A simplified result_of implementation.
20 // that uses decltype.
21 template<typename Sig>
22 struct result_of;
23
24 template<typename T>
25 T& declvar();
26
27 // use decltype
28 template<typename Fun, typename T>
29 struct result_of<Fun(T)>
30 {
31 typedef decltype(declvar<Fun>()(declvar<T>())) type;
32 };
33
34 template<typename Fun, typename T, typename U>
35 struct result_of<Fun(T, U)>
36 {
37 typedef decltype(declvar<Fun>()(declvar<T>(), declvar<U>())) type;
38 };
39
40 // simple tuple type
41 template<typename A0 = void, typename A1 = void, typename A2 = void>
42 struct tuple;
43
44 template<typename A0>
45 struct tuple<A0, void, void>
46 {
47 A0 a0_;
48
49 tuple(A0 const &a0)
50 : a0_(a0)
51 {}
52 };
53
54 template<typename A0, typename A1>
55 struct tuple<A0, A1>
56 {
57 A0 a0_;
58 A1 a1_;
59
60 tuple(A0 const &a0, A1 const & a1)
61 : a0_(a0)
62 , a1_(a1)
63 {}
64 };
65
66 // A node in an expression tree
67 template<class Tag, class Args> // Args is a tuple.
68 struct Expr;
69
70 // A function object that builds expression nodes
71 template<class Tag>
72 struct MakeExpr
73 {
74 template<class T>
75 Expr<Tag, tuple<T> > operator()(T const & t) const
76 {
77 return Expr<Tag, tuple<T> >(tuple<T>(t));
78 }
79
80 template<class T, typename U>
81 Expr<Tag, tuple<T, U> > operator()(T const & t, U const & u) const
82 {
83 return Expr<Tag, tuple<T, U> >(tuple<T, U>(t, u));
84 }
85 };
86
87 // Here are tag types that encode in an expression node
88 // what operation created the node.
89 struct Terminal;
90 struct BinaryPlus;
91 struct FunctionCall;
92
93 typedef MakeExpr<Terminal> MakeTerminal;
94 typedef MakeExpr<BinaryPlus> MakeBinaryPlus;
95 typedef MakeExpr<FunctionCall> MakeFunctionCall;
96
97 template<class Tag, class Args>
98 struct Expr
99 {
100 Args args_;
101
102 explicit Expr(Args const & t) : args_(t) {}
103
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
108 {
109 return MakeBinaryPlus()(*this, right);
110 }
111
112 // An overloaded function call operator that creates a unary
113 // function call node
114 typename result_of<MakeFunctionCall(Expr)>::type
115 operator()() const
116 {
117 return MakeFunctionCall()(*this);
118 }
119 };
120
121 int test()
122 {
123 // This is a terminal in an expression tree
124 Expr<Terminal, tuple<int> > i = MakeTerminal()(42);
125
126 i + i; // OK, this creates a binary plus node.
127
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
132 // memory.
133
134 return 0;
135 }
136
137 }