1 // Boost.Units - A C++ library for zero-overhead dimensional analysis and
2 // unit/quantity manipulation and conversion
3 //
4 // Copyright (C) 2003-2008 Matthias Christian Schabel
5 // Copyright (C) 2008 Steven Watanabe
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See
8 // accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 
11 // $Id: test_lambda.cpp 27 2008-06-16 14:50:58Z maehne $
12 
13 ////////////////////////////////////////////////////////////////////////
14 ///
15 /// \file test_lambda.hpp
16 ///
17 /// \brief Unit test for checking the usage of Boost.Units' quantity,
18 ///        unit, and absolute types in functors created with the
19 ///        Boost.Lambda library.
20 ///
21 /// \author Torsten Maehne
22 /// \date   2008-06-16
23 ///
24 /// This unit test contains a check for each operator action, for
25 /// which a specialization of Boost.Lambda's return type deduction
26 /// system is made in lambda.hpp, i.e., for the operators defined for
27 /// Boost.Units' quantity, unit, and absolute types.
28 ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 #include <boost/function.hpp>
32 #include <boost/units/lambda.hpp>
33 #include <boost/units/absolute.hpp>
34 #include <boost/units/systems/si/temperature.hpp>
35 #include "test_header.hpp"
36 
37 
38 namespace bl = boost::lambda;
39 namespace bu = boost::units;
40 namespace si = boost::units::si;
41 
42 
test_main(int,char * [])43 int test_main(int, char *[])
44 {
45 
46     ////////////////////////////////////////////////////////////////////////
47     // Test for Boost.Lambda working with overloaded operators defined
48     // in <boost/units/quantity.hpp>
49     ////////////////////////////////////////////////////////////////////////
50 
51     bu::quantity<bu::length> lvar = 0.0 * bu::meter;
52 
53     bu::quantity<bu::dimensionless> dlvar = 3.0;
54 
55     // quantity<Unit, Y> += quantity<Unit2, YY>
56     boost::function<bu::quantity<bu::length> (bu::quantity<bu::length>)>
57         f = (bl::var(lvar) += bl::_1);
58 
59     lvar = 1.0 * bu::meter;
60     BOOST_CHECK((f(2.0 * bu::meter) == 3.0 * bu::meter));
61     BOOST_CHECK((f(6.0 * bu::meter) == 9.0 * bu::meter));
62 
63     // quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> += quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y>
64     dlvar = 4.0;
65     BOOST_CHECK(((bl::var(dlvar) += bl::_1)(3.0) == 7.0));
66 
67     // quantity<Unit, Y> -= quantity<Unit2, YY>
68     lvar = 3.0 * bu::meter;
69     BOOST_CHECK((f(-2.0 * bu::meter) == 1.0 * bu::meter));
70     BOOST_CHECK((f(6.0 * bu::meter) == 7.0 * bu::meter));
71 
72     // quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> -= quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y>
73     dlvar = 4.0;
74     BOOST_CHECK(((bl::var(dlvar) -= bl::_1)(3.0) == 1.0));
75 
76     // quantity<Unit, Y> *= quantity<Unit2, YY>
77     dlvar = 2.0;
78     BOOST_CHECK(((bl::var(dlvar) *= bl::_1)(3.0) == 6.0));
79 
80     // quantity<Unit, Y> /= quantity<Unit2, YY>
81     dlvar = 6.0;
82     BOOST_CHECK(((bl::var(dlvar) /= bl::_1)(3.0) == 2.0));
83 
84     // quantity<Unit, Y> *= Y
85     lvar = 3.0 * bu::meter;
86     BOOST_CHECK(((bl::var(lvar) *= bl::_1)(2.0) == 6.0 * bu::meter));
87 
88     // quantity<Unit, Y> /= Y
89     lvar = 6.0 * bu::meter;
90     BOOST_CHECK(((bl::var(lvar) /= bl::_1)(3.0) == 2.0 * bu::meter));
91 
92     // unit<Dim, System> * Y
93     BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 2.0) == 2.0 * bu::meter));
94     BOOST_CHECK(((bu::meter * bl::_1)(2.0) == 2.0 * bu::meter));
95 
96     // unit<Dim, System> / Y
97     BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5) == 2.0 * bu::meter));
98     BOOST_CHECK(((bu::meter / bl::_1)(0.5 * bu::second) == 2.0 * bu::meter_per_second));
99 
100     // Y * unit<Dim, System>
101     BOOST_CHECK(((bl::_1 * bl::_2)(2.0, bu::meter) == 2.0 * bu::meter));
102     BOOST_CHECK(((bl::_1 * bu::meter)(2.0 / bu::second) == 2.0 * bu::meter_per_second));
103 
104     // Y / unit<Dim, System>
105     BOOST_CHECK(((bl::_1 / bl::_2)(3.5, bu::second) == 3.5 / bu::second));
106     BOOST_CHECK(((bl::_1 / bu::second)(3.5 * bu::meter) == 3.5 * bu::meter_per_second));
107 
108     // quantity<Unit, X> * X
109     BOOST_CHECK(((bl::_1 * bl::_2)(2.0, 3.0 * bu::meter) == 6.0 * bu::meter));
110 
111     // X * quantity<Unit, X>
112     BOOST_CHECK(((bl::_1 * bl::_2)(4.0 * bu::joule, 2.0) == 8.0 * bu::joule));
113 
114     // quantity<Unit, X> / X
115     BOOST_CHECK(((bl::_1 / bl::_2)(4.0 * bu::joule, 2.0) == 2.0 * bu::joule));
116 
117     // X / quantity<Unit, X>
118     BOOST_CHECK(((3.0 / bl::_1)(2.0 * bu::second) == 1.5 / bu::second));
119 
120     // unit<Dim1, System1> * quantity<Unit2, Y>
121     BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 12.0 / bu::second) == 12.0 * bu::meter_per_second));
122     BOOST_CHECK(((bu::meter * bl::_1)(12.0 / bu::second) == 12.0 * bu::meter_per_second));
123 
124     // unit<Dim1, System1> / quantity<Unit2, Y>
125     BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5 * bu::second) == 2.0 * bu::meter_per_second));
126     BOOST_CHECK(((bu::meter / bl::_1)(0.25 * bu::second) == 4.0 * bu::meter_per_second));
127 
128     // quantity<Unit1, Y> * unit<Dim2, System2>
129     BOOST_CHECK(((bl::_1 * bl::_2)(2.0 / bu::second, bu::meter) == 2.0 * bu::meter_per_second));
130     BOOST_CHECK(((bl::_1 * bu::meter)(12.0 / bu::second) == 12.0 * bu::meter_per_second));
131 
132     // quantity<Unit1, Y> / unit<Dim2, System2>
133     BOOST_CHECK(((bl::_1 / bl::_2)(3.5 * bu::meter, bu::second) == 3.5 * bu::meter_per_second));
134     BOOST_CHECK(((bl::_1 / bu::second)(5.0 * bu::second) == 5.0));
135 
136     // +quantity<Unit, Y>
137     BOOST_CHECK(((+bl::_1)(5.0 * bu::second) == 5.0 * bu::second));
138 
139     // -quantity<Unit, Y>
140     BOOST_CHECK(((-bl::_1)(5.0 * bu::second) == -5.0 * bu::second));
141 
142     // quantity<Unit1, X> + quantity<Unit2, Y>
143     BOOST_CHECK(((bl::_1 + bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == 6.0 * bu::meter));
144 
145     // quantity<dimensionless, X> + Y
146     BOOST_CHECK(((bl::_1 + 1.0f)(bu::quantity<bu::dimensionless>(2.0)) == 3.0));
147 
148     // X + quantity<dimensionless, Y>
149     BOOST_CHECK(((1.0f + bl::_1)(bu::quantity<bu::dimensionless>(1.0)) == 2.0));
150 
151     // quantity<Unit1, X> - quantity<Unit2, Y>
152     BOOST_CHECK(((bl::_1 - bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == -2.0 * bu::meter));
153 
154     // quantity<dimensionless, X> - Y
155     BOOST_CHECK(((bl::_1 - 2.0f)(bu::quantity<bu::dimensionless>(1.0)) == -1.0));
156 
157     // X - quantity<dimensionless, Y>
158     BOOST_CHECK(((2.0f - bl::_1)(bu::quantity<bu::dimensionless>(1.0)) == 1.0));
159 
160     // quantity<Unit1, X> * quantity<Unit2, Y>
161     BOOST_CHECK(((bl::_1 * bl::_2)(2.0 * bu::kilogram, 4.0 * bu::meter_per_second) == 8.0 * bu::kilogram * bu::meter_per_second));
162 
163     // quantity<Unit1, X> / quantity<Unit2, Y>
164     BOOST_CHECK(((bl::_1 / bl::_2)(2.0 * bu::meter_per_second, 4.0 * bu::meter_per_second) == 0.5));
165 
166     // quantity<Unit, X> == quantity<Unit, Y>
167     BOOST_CHECK(((bl::_1 == bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true));
168     BOOST_CHECK(((bl::_1 == bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false));
169 
170     // quantity<Unit, X> != quantity<Unit, Y>
171     BOOST_CHECK(((bl::_1 != bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false));
172     BOOST_CHECK(((bl::_1 != bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true));
173 
174     // quantity<Unit, X> < quantity<Unit, Y>
175     BOOST_CHECK(((bl::_1 < bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false));
176     BOOST_CHECK(((bl::_1 < bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true));
177 
178     // quantity<Unit, X> <= quantity<Unit, Y>
179     BOOST_CHECK(((bl::_1 <= bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true));
180     BOOST_CHECK(((bl::_1 <= bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true));
181     BOOST_CHECK(((bl::_1 <= bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == false));
182 
183     // quantity<Unit, X> > quantity<Unit, Y>
184     BOOST_CHECK(((bl::_1 > bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false));
185     BOOST_CHECK(((bl::_1 > bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false));
186     BOOST_CHECK(((bl::_1 > bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == true));
187 
188     // quantity<Unit, X> >= quantity<Unit, Y>
189     BOOST_CHECK(((bl::_1 >= bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true));
190     BOOST_CHECK(((bl::_1 >= bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false));
191     BOOST_CHECK(((bl::_1 >= bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == true));
192 
193 
194     ////////////////////////////////////////////////////////////////////////
195     // Test for Boost.Lambda working with overloaded operators defined
196     // in <boost/units/unit.hpp>
197     ////////////////////////////////////////////////////////////////////////
198 
199     // +unit<Dim, System>
200     BOOST_CHECK(((+bl::_1)(bu::meter) == bu::meter));
201 
202     // -unit<Dim, System>
203     BOOST_CHECK(((-bl::_1)(bu::meter) == bu::meter));
204 
205     // unit<Dim1, System1> + unit<Dim2, System2>
206     BOOST_CHECK(((bl::_1 + bu::meter)(bu::meter) == bu::meter));
207     BOOST_CHECK(((bu::meter + bl::_1)(bu::meter) == bu::meter));
208     BOOST_CHECK(((bl::_1 + bl::_2)(bu::meter, bu::meter) == bu::meter));
209 
210     // unit<Dim1, System1> - unit<Dim2, System2>
211     BOOST_CHECK(((bl::_1 - bl::_2)(bu::meter, bu::meter) == bu::meter));
212     BOOST_CHECK(((bl::_1 - bu::meter)(bu::meter) == bu::meter));
213     BOOST_CHECK(((bu::meter - bl::_1)(bu::meter) == bu::meter));
214 
215     // unit<Dim1, System1> * unit<Dim2, System2>
216     BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, bu::meter) == bu::meter * bu::meter));
217     BOOST_CHECK(((bl::_1 * bu::meter)(bu::meter) == bu::meter * bu::meter));
218 
219     // unit<Dim1, System1> / unit<Dim2, System2>
220     BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, bu::second) == bu::meter_per_second));
221     BOOST_CHECK(((bl::_1 / bu::second)(bu::meter) == bu::meter_per_second));
222 
223     // unit<Dim1, System1> == unit<Dim2, System2>
224     BOOST_CHECK(((bl::_1 == bu::meter)(bu::meter) == true));
225     BOOST_CHECK(((bl::_1 == bu::meter)(bu::second) == false));
226 
227     // unit<Dim1, System1> != unit<Dim2, System2>
228     BOOST_CHECK(((bl::_1 != bu::meter)(bu::meter) == false));
229     BOOST_CHECK(((bl::_1 != bu::meter)(bu::second) == true));
230 
231 
232     ////////////////////////////////////////////////////////////////////////
233     // Test for Boost.Lambda working with overloaded operators defined
234     // in <boost/units/absolute.hpp>
235     ////////////////////////////////////////////////////////////////////////
236 
237     // absolute<Y> += Y
238     bu::quantity<bu::absolute<si::temperature> > Ta = 270.0 * bu::absolute<si::temperature>();
239     (Ta += bl::_1)(30.0 * si::kelvin);
240     BOOST_CHECK(( Ta == 300.0 * bu::absolute<si::temperature>()));
241 
242     // absolute<Y> -= Y
243     Ta = 270 * bu::absolute<si::temperature>();
244     (Ta -= bl::_1)(-30.0 * si::kelvin);
245     BOOST_CHECK(( Ta == 300.0 * bu::absolute<si::temperature>()));
246 
247     // absolute<Y> + Y
248     BOOST_CHECK(((270.0 * bu::absolute<si::temperature>() + bl::_1)(30.0 * si::kelvin) == 300.0 * bu::absolute<si::temperature>()));
249 
250     // Y + absolute<Y>
251     BOOST_CHECK(((bl::_1 + 270.0 * bu::absolute<si::temperature>())(30.0 * si::kelvin) == 300.0 * bu::absolute<si::temperature>()));
252 
253     // absolute<Y> - Y
254     BOOST_CHECK(((270.0 * bu::absolute<si::temperature>() - bl::_1)(30.0 * si::kelvin) == 240.0 * bu::absolute<si::temperature>()));
255 
256     // absolute<Y> - absolute<Y>
257     BOOST_CHECK(((bl::_1 - 270.0 * bu::absolute<si::temperature>())(300.0 * bu::absolute<si::temperature>()) == 30.0 * si::kelvin));
258 
259     // T * absolute<unit<D, S> >
260     BOOST_CHECK(((bl::_1 * bu::absolute<si::temperature>())(300.0) == 300.0 * bu::absolute<si::temperature>()));
261     BOOST_CHECK(((bl::_1 * bl::_2)(300.0, bu::absolute<si::temperature>()) == 300.0 * bu::absolute<si::temperature>()));
262 
263     // absolute<unit<D, S> > * T
264     BOOST_CHECK(((bu::absolute<si::temperature>() * bl::_1)(300.0) == 300.0 * bu::absolute<si::temperature>()));
265     BOOST_CHECK(((bl::_1 * bl::_2)(bu::absolute<si::temperature>(), 300.0) == 300.0 * bu::absolute<si::temperature>()));
266 
267 
268     return 0;
269 }
270