1 | /*============================================================================= |
2 | Copyright (c) 2001-2007 Joel de Guzman |
3 | |
4 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
5 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
6 | ==============================================================================*/ |
7 | #include <iostream> |
8 | #include <cmath> |
9 | #include <algorithm> |
10 | #include <vector> |
11 | |
12 | #include <boost/phoenix/core/limits.hpp> |
13 | |
14 | #include <boost/detail/lightweight_test.hpp> |
15 | #include <boost/fusion/tuple.hpp> |
16 | #include <boost/phoenix/core.hpp> |
17 | #include <boost/phoenix/operator.hpp> |
18 | #include <boost/phoenix/function.hpp> |
19 | #include <boost/phoenix/fusion.hpp> |
20 | #include <boost/phoenix/scope.hpp> |
21 | #include <boost/phoenix/object/construct.hpp> |
22 | |
23 | #include <typeinfo> |
24 | |
25 | namespace fusion = boost::fusion; |
26 | namespace mpl = boost::mpl; |
27 | |
28 | int |
29 | main() |
30 | { |
31 | using boost::phoenix::let; |
32 | using boost::phoenix::val; |
33 | using boost::phoenix::arg_names::_1; |
34 | using boost::phoenix::arg_names::_2; |
35 | using boost::phoenix::arg_names::_3; |
36 | using boost::phoenix::local_names::_a; |
37 | using boost::phoenix::local_names::_b; |
38 | using boost::phoenix::local_names::_c; |
39 | using boost::phoenix::local_names::_d; |
40 | using boost::phoenix::local_names::_e; |
41 | using boost::phoenix::local_names::_x; |
42 | using boost::phoenix::local_names::_y; |
43 | using boost::phoenix::local_names::_z; |
44 | using boost::phoenix::placeholders::arg1; |
45 | |
46 | { |
47 | int x = 1; |
48 | BOOST_TEST( |
49 | let(_a = _1) |
50 | [ |
51 | _a |
52 | ] |
53 | (x) == x |
54 | ) |
55 | ; |
56 | } |
57 | |
58 | { |
59 | int x = 1, y = 10; |
60 | BOOST_TEST( |
61 | let(_a = _1, _b = _2) |
62 | [ |
63 | _a + _b |
64 | ] |
65 | (x, y) == x + y |
66 | ); |
67 | } |
68 | |
69 | { |
70 | int x = 1, y = 10, z = 13; |
71 | BOOST_TEST( |
72 | let(_x = _1, _y = _2) |
73 | [ |
74 | let(_z = _3) |
75 | [ |
76 | _x + _y + _z |
77 | ] |
78 | ] |
79 | (x, y, z) == x + y + z |
80 | ); |
81 | } |
82 | |
83 | { |
84 | int x = 1, y = 10; |
85 | BOOST_TEST( |
86 | let(_x = _1) |
87 | [ |
88 | _x + |
89 | let(_x = _2) |
90 | [ |
91 | -_x |
92 | ] |
93 | ] |
94 | (x, y) == x + -y |
95 | ); |
96 | } |
97 | |
98 | { |
99 | int x = 999; |
100 | BOOST_TEST( |
101 | let(_x = _1) // _x is a reference to x |
102 | [ |
103 | _x += 888 |
104 | ] |
105 | (x) == 999 + 888 |
106 | ); |
107 | |
108 | BOOST_TEST(x == 888 + 999); |
109 | } |
110 | |
111 | { |
112 | int x = 999; |
113 | /* |
114 | BOOST_TEST( |
115 | let(_x = val(_1)) // _x holds x by value |
116 | [ |
117 | _x += 888 |
118 | ] |
119 | (x) == x + 888 |
120 | ); |
121 | |
122 | BOOST_TEST(x == 999); |
123 | */ |
124 | BOOST_TEST( |
125 | let(_x = val(_1)) // _x holds x by value |
126 | [ |
127 | val(_x += 888) |
128 | ] |
129 | (x) == x + 888 |
130 | ); |
131 | |
132 | BOOST_TEST(x == 999); |
133 | } |
134 | |
135 | { |
136 | BOOST_TEST( |
137 | let(_a = 1, _b = 2, _c = 3, _d = 4, _e = 5) |
138 | [ |
139 | _a + _b + _c + _d + _e |
140 | ] |
141 | () == 1 + 2 + 3 + 4 + 5 |
142 | ); |
143 | } |
144 | |
145 | #ifdef PHOENIX_SHOULD_NOT_COMPILE_TEST |
146 | { |
147 | // disallow this: |
148 | int i; |
149 | (_a + _b)(i); |
150 | } |
151 | #endif |
152 | |
153 | { |
154 | // show that we can return a local from an outer scope |
155 | int y = 0; |
156 | #if defined(__OPTIMIZE__) && __OPTIMIZE__ |
157 | int x = (let(a: _a = _2)[let(a: _b = _1)[ _a ]])(y,1); |
158 | #else |
159 | int x = (let(_a = 1)[let(_b = _1)[ _a ]])(y); |
160 | #endif |
161 | BOOST_TEST(x == 1); |
162 | } |
163 | |
164 | { |
165 | // show that this code returns an lvalue |
166 | int i = 1; |
167 | let(a: _a = arg1)[ _a ](i)++; |
168 | BOOST_TEST(i == 2); |
169 | } |
170 | |
171 | { |
172 | // show that what you put in is what you get out |
173 | int i = 1; |
174 | int& j = let(a: _a = arg1)[_a](i); |
175 | BOOST_TEST(&i == &j); |
176 | } |
177 | |
178 | { |
179 | // show that a let with a void result can compile |
180 | using boost::phoenix::construct; |
181 | |
182 | let(a: _a = 1)[ // need at least one expression here |
183 | construct<void>() // produce a void result |
184 | ](); |
185 | } |
186 | |
187 | { |
188 | using boost::phoenix::at_c; |
189 | |
190 | boost::fusion::tuple<int, int> t = boost::fusion::make_tuple(arg: 0, arg: 1); |
191 | int i = let(a: _a = at_c<0>(tuple: _1))[_a](t); |
192 | |
193 | BOOST_TEST( i == 0 ); |
194 | } |
195 | |
196 | { |
197 | int i = 0; |
198 | let(a: _a = _1)[_a = _2](i, 2); |
199 | BOOST_TEST(i == 2); |
200 | } |
201 | |
202 | return boost::report_errors(); |
203 | } |
204 | |
205 | |