// Boost.Units - A C++ library for zero-overhead dimensional analysis and // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel // Copyright (C) 2008 Steven Watanabe // // Distributed under 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) //////////////////////////////////////////////////////////////////////// /// /// \file test_lambda.hpp /// /// \brief Unit test for checking the usage of Boost.Units' quantity, /// unit, and absolute types in functors created with the /// Boost.Lambda library. /// /// \author Torsten Maehne /// \date 2008-06-05 /// /// This unit test contains a check for each operator action, for /// which a specialization of Boost.Lambda's return type deduction /// system is made in lambda.hpp, i.e., for the operators defined for /// Boost.Units' quantity, unit, and absolute types. /// /// \todo All checks involving the multiplication/division of /// boost::units::unit and /// boost::units::absolute types are not /// compiling. The compiler complains about ambiguous overloads /// for operator* and operator/ (originating from Boost.Units /// and Boost.Lambda). Therefore they are currently commented /// out. Some checks also involve the usage of Boost.Function /// /// \todo The check fo unit - unit is /// not compiling. The compiler finds no matching definition of /// operator-. /// /// \todo Are the checks for the operations involving absolute unit /// types correct? /// /// \todo Add checks involving mathematical functions from /// boost/units/cmath.hpp once a solution for /// boost::lambda:bind's limitation concerning the binding of /// overloaded functions is found. /// //////////////////////////////////////////////////////////////////////// #include #include #include #include #include "test_header.hpp" namespace bl = boost::lambda; namespace bu = boost::units; namespace si = boost::units::si; int test_main(int argc, char *argv[]) { //////////////////////////////////////////////////////////////////////// // Test for Boost.Lambda working with overloaded operators defined // in //////////////////////////////////////////////////////////////////////// bu::quantity lvar = 0.0 * bu::meter; bu::quantity dlvar = 3.0; // quantity += quantity boost::function (bu::quantity)> f = (bl::var(lvar) += bl::_1); lvar = 1.0 * bu::meter; BOOST_CHECK((f(2.0 * bu::meter) == 3.0 * bu::meter)); BOOST_CHECK((f(6.0 * bu::meter) == 9.0 * bu::meter)); // quantity += quantity dlvar = 4.0; BOOST_CHECK(((bl::var(dlvar) += bl::_1)(3.0) == 7.0)); // quantity -= quantity lvar = 3.0 * bu::meter; BOOST_CHECK((f(-2.0 * bu::meter) == 1.0 * bu::meter)); BOOST_CHECK((f(6.0 * bu::meter) == 7.0 * bu::meter)); // quantity -= quantity dlvar = 4.0; BOOST_CHECK(((bl::var(dlvar) -= bl::_1)(3.0) == 1.0)); // quantity *= quantity dlvar = 2.0; BOOST_CHECK(((bl::var(dlvar) *= bl::_1)(3.0) == 6.0)); // quantity /= quantity dlvar = 6.0; BOOST_CHECK(((bl::var(dlvar) /= bl::_1)(3.0) == 2.0)); // quantity *= Y lvar = 3.0 * bu::meter; BOOST_CHECK(((bl::var(lvar) *= bl::_1)(2.0) == 6.0 * bu::meter)); // quantity /= Y lvar = 6.0 * bu::meter; BOOST_CHECK(((bl::var(lvar) /= bl::_1)(3.0) == 2.0 * bu::meter)); // unit * Y BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 2.0) == 2.0 * bu::meter)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bu::meter * bl::_1)(2.0) == 2.0 * bu::meter)); // unit / Y BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5) == 2.0 * bu::meter)); // // Error: ambiguous overload of operator/ // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bu::meter / bl::_1)(0.5 * bu::second) == 2.0 * bu::meter_per_second)); // Y * unit BOOST_CHECK(((bl::_1 * bl::_2)(2.0, bu::meter) == 2.0 * bu::meter)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 * bu::meter)(2.0 / bu::second) == 2.0 * bu::meter_per_second)); // Y / unit BOOST_CHECK(((bl::_1 / bl::_2)(3.5, bu::second) == 3.5 / bu::second)); // // Error: ambiguous overload of operator/ // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 / bu::second)(3.5 * bu::meter) == 3.5 * bu::meter_per_second)); // quantity * X BOOST_CHECK(((bl::_1 * bl::_2)(2.0, 3.0 * bu::meter) == 6.0 * bu::meter)); // X * quantity BOOST_CHECK(((bl::_1 * bl::_2)(4.0 * bu::joule, 2.0) == 8.0 * bu::joule)); // quantity / X BOOST_CHECK(((bl::_1 / bl::_2)(4.0 * bu::joule, 2.0) == 2.0 * bu::joule)); // X / quantity BOOST_CHECK(((3.0 / bl::_1)(2.0 * bu::second) == 1.5 / bu::second)); // unit * quantity BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 12.0 / bu::second) == 12.0 * bu::meter_per_second)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bu::meter * bl::_1)(12.0 / bu::second) == 12.0 * bu::meter_per_second)); // unit / quantity BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5 * bu::second) == 2.0 * bu::meter_per_second)); // // Error: ambiguous overload of operator/ // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bu::meter / bl::_1)(0.25 * bu::second) == 4.0 * bu::meter_per_second)); // quantity * unit BOOST_CHECK(((bl::_1 * bl::_2)(2.0 / bu::second, bu::meter) == 2.0 * bu::meter_per_second)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 * bu::meter)(12.0 / bu::second) == 12.0 / bu::meter_per_second)); // quantity / unit BOOST_CHECK(((bl::_1 / bl::_2)(3.5 * bu::meter, bu::second) == 3.5 * bu::meter_per_second)); // // Error: ambiguous overload of operator/ // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 / bu::second)(5.0 * bu::second) == 5.0)); // +quantity BOOST_CHECK(((+bl::_1)(5.0 * bu::second) == 5.0 * bu::second)); // -quantity BOOST_CHECK(((-bl::_1)(5.0 * bu::second) == -5.0 * bu::second)); // quantity + quantity BOOST_CHECK(((bl::_1 + bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == 6.0 * bu::meter)); // quantity - quantity BOOST_CHECK(((bl::_1 - bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == -2.0 * bu::meter)); // quantity * quantity BOOST_CHECK(((bl::_1 * bl::_2)(2.0 * bu::kilogram, 4.0 * bu::meter_per_second) == 8.0 * bu::kilogram * bu::meter_per_second)); // quantity / quantity BOOST_CHECK(((bl::_1 / bl::_2)(2.0 * bu::meter_per_second, 4.0 * bu::meter_per_second) == 0.5)); // quantity == quantity BOOST_CHECK(((bl::_1 == bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true)); BOOST_CHECK(((bl::_1 == bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false)); // quantity != quantity BOOST_CHECK(((bl::_1 != bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false)); BOOST_CHECK(((bl::_1 != bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true)); // quantity < quantity BOOST_CHECK(((bl::_1 < bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false)); BOOST_CHECK(((bl::_1 < bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true)); // quantity <= quantity BOOST_CHECK(((bl::_1 <= bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true)); BOOST_CHECK(((bl::_1 <= bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == true)); BOOST_CHECK(((bl::_1 <= bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == false)); // quantity > quantity BOOST_CHECK(((bl::_1 > bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == false)); BOOST_CHECK(((bl::_1 > bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false)); BOOST_CHECK(((bl::_1 > bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == true)); // quantity >= quantity BOOST_CHECK(((bl::_1 >= bl::_2)(2.0 * bu::meter, 2.0 * bu::meter) == true)); BOOST_CHECK(((bl::_1 >= bl::_2)(2.0 * bu::meter, 3.0 * bu::meter) == false)); BOOST_CHECK(((bl::_1 >= bl::_2)(4.0 * bu::meter, 3.0 * bu::meter) == true)); //////////////////////////////////////////////////////////////////////// // Test for Boost.Lambda working with overloaded operators defined // in //////////////////////////////////////////////////////////////////////// // +unit BOOST_CHECK(((+bl::_1)(bu::meter) == bu::meter)); // -unit BOOST_CHECK(((-bl::_1)(bu::meter) == bu::meter)); // unit + unit BOOST_CHECK(((bl::_1 + bu::meter)(bu::meter) == bu::meter)); BOOST_CHECK(((bu::meter + bl::_1)(bu::meter) == bu::meter)); BOOST_CHECK(((bl::_1 + bl::_2)(bu::meter, bu::meter) == bu::meter)); // unit - unit // // Error: no match for operator- // BOOST_CHECK(((bl::_1 - bl::_2)(bu::meter, bu::meter) == bu::meter)); // // Error: no match for operator- // BOOST_CHECK(((bl::_1 - bu::meter)(bu::meter) == bu::meter)); // // Error: no match for operator- // BOOST_CHECK(((bu::meter - bl::_1)(bu::meter) == bu::meter)); // unit * unit BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, bu::meter) == bu::meter * bu::meter)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 * bu::meter)(bu::meter) == bu::meter * bu::meter)); // unit / unit BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, bu::second) == bu::meter_per_second)); // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 / bu::second)(bu::meter) == bu::meter_per_second)); // unit == unit BOOST_CHECK(((bl::_1 == bu::meter)(bu::meter) == true)); BOOST_CHECK(((bl::_1 == bu::meter)(bu::second) == false)); // unit != unit BOOST_CHECK(((bl::_1 != bu::meter)(bu::meter) == false)); BOOST_CHECK(((bl::_1 != bu::meter)(bu::second) == true)); //////////////////////////////////////////////////////////////////////// // Test for Boost.Lambda working with overloaded operators defined // in //////////////////////////////////////////////////////////////////////// // absolute += Y bu::quantity > Ta = 270.0 * bu::absolute(); (Ta += bl::_1)(30.0 * si::kelvin); BOOST_CHECK(( Ta == 300.0 * bu::absolute())); // absolute -= Y Ta = 270 * bu::absolute(); (Ta -= bl::_1)(-30.0 * si::kelvin); BOOST_CHECK(( Ta == 300.0 * bu::absolute())); // absolute + Y BOOST_CHECK(((270.0 * bu::absolute() + bl::_1)(30.0 * si::kelvin) == 300.0 * bu::absolute())); // Y + absolute BOOST_CHECK(((bl::_1 + 270.0 * bu::absolute())(30.0 * si::kelvin) == 300.0 * bu::absolute())); // absolute - Y BOOST_CHECK(((270.0 * bu::absolute() - bl::_1)(30.0 * si::kelvin) == 240.0 * bu::absolute())); // absolute - absolute BOOST_CHECK(((bl::_1 - 270.0 * bu::absolute())(300.0 * bu::absolute()) == 30.0 * si::kelvin)); // // T * absolute > // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bl::_1 * bu::absolute())(300.0) == 300.0 * bu::absolute())); // // Error: no match for operator== // BOOST_CHECK(((bl::_1 * bl::_2)(300.0, bu::absolute()) == 300.0 * bu::absolute())); // // absolute > * T // // Error: ambiguous overload of operator* // // (defined in Boost.Lambda and Boost.Units). // BOOST_CHECK(((bu::absolute() * bl::_1)(300.0) == 300.0 * bu::absolute())); // // Error: no match for operator== // BOOST_CHECK(((bl::_1 * bl::_2)(bu::absolute(), 300.0) == 300.0 * bu::absolute())); return 0; }