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
25namespace fusion = boost::fusion;
26namespace mpl = boost::mpl;
27
28int
29main()
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

source code of boost/libs/phoenix/test/scope/let_tests.cpp