// 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) // $Id: lambda.hpp 27 2008-06-16 14:50:58Z maehne $ #ifndef BOOST_UNITS_LAMBDA_HPP #define BOOST_UNITS_LAMBDA_HPP //////////////////////////////////////////////////////////////////////// /// /// \file lambda.hpp /// /// \brief Definitions to ease the usage of Boost.Units' quantity, /// unit, and absolute types in functors created with the /// Boost.Lambda library. /// /// \author Torsten Maehne /// \date 2008-06-16 /// /// Boost.Lambda's return type deduction system is extented to make /// use of Boost.Units' typeof_helper trait classes for Boost.Units' /// quantity, absolute, and unit template classes. /// //////////////////////////////////////////////////////////////////////// #include #include #include #include namespace boost { namespace lambda { /// Partial specialization of return type trait for action /// unit * Y. template struct plain_return_type_2, boost::units::unit, Y > { typedef typename boost::units::multiply_typeof_helper< boost::units::unit, Y >::type type; }; } // namespace lambda namespace units { template struct multiply_typeof_helper, boost::lambda::lambda_functor > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple >::type, boost::lambda::lambda_functor > > > type; }; /// Disambiguating overload for action /// unit * lambda_functor /// based on \. template inline const typename multiply_typeof_helper, boost::lambda::lambda_functor >::type operator*(const boost::units::unit& a, const boost::lambda::lambda_functor& b) { return typename multiply_typeof_helper, boost::lambda::lambda_functor >::type::inherited (tuple >::type, boost::lambda::lambda_functor > (a, b)); } } // namespace units namespace lambda { /// Partial specialization of return type trait for action /// unit / Y. template struct plain_return_type_2, boost::units::unit, Y > { typedef typename boost::units::divide_typeof_helper< boost::units::unit, Y >::type type; }; } // namespace lambda namespace units { template struct divide_typeof_helper, boost::lambda::lambda_functor > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple >::type, boost::lambda::lambda_functor > > > type; }; /// Disambiguating overload for action /// unit / lambda_functor /// based on \. template inline const typename divide_typeof_helper, boost::lambda::lambda_functor >::type operator/(const boost::units::unit& a, const boost::lambda::lambda_functor& b) { return typename divide_typeof_helper, boost::lambda::lambda_functor >::type::inherited (tuple >::type, boost::lambda::lambda_functor > (a, b)); } } // namespace units namespace lambda { /// Partial specialization of return type trait for action /// Y * unit. template struct plain_return_type_2, Y, boost::units::unit > { typedef typename boost::units::multiply_typeof_helper< Y, boost::units::unit >::type type; }; } // namespace lambda namespace units { template struct multiply_typeof_helper, boost::units::unit > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple, typename boost::lambda::const_copy_argument >::type> > > type; }; /// Disambiguating overload for action /// lambda_functor * unit /// based on \. template inline const typename multiply_typeof_helper, boost::units::unit >::type operator*(const boost::lambda::lambda_functor& a, const boost::units::unit& b) { return typename multiply_typeof_helper, boost::units::unit >::type::inherited (tuple, typename boost::lambda::const_copy_argument >::type> (a, b)); } } // namespace units namespace lambda { /// Partial specialization of return type trait for action /// Y / unit. template struct plain_return_type_2, Y, boost::units::unit > { typedef typename boost::units::divide_typeof_helper< Y, boost::units::unit >::type type; }; } // namespace lambda namespace units { template struct divide_typeof_helper, boost::units::unit > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple, typename boost::lambda::const_copy_argument >::type> > > type; }; /// Disambiguating overload for action /// lambda_functor / unit /// based on \. template inline const typename divide_typeof_helper, boost::units::unit >::type operator/(const boost::lambda::lambda_functor& a, const boost::units::unit& b) { return typename divide_typeof_helper, boost::units::unit >::type::inherited (tuple, typename boost::lambda::const_copy_argument >::type> (a, b)); } } // namespace units namespace lambda { /// Partial specialization of return type trait for action /// quantity * X. template struct plain_return_type_2, boost::units::quantity, X> { typedef typename boost::units::multiply_typeof_helper< boost::units::quantity, X>::type type; }; /// Partial specialization of return type trait for action /// X * quantity. template struct plain_return_type_2, X, boost::units::quantity > { typedef typename boost::units::multiply_typeof_helper< X, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity / X. template struct plain_return_type_2, boost::units::quantity, X> { typedef typename boost::units::divide_typeof_helper< boost::units::quantity, X>::type type; }; /// Partial specialization of return type trait for action /// X / quantity. template struct plain_return_type_2, X, boost::units::quantity > { typedef typename boost::units::divide_typeof_helper< X, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// unit * quantity. template struct plain_return_type_2, boost::units::unit, boost::units::quantity > { typedef typename boost::units::multiply_typeof_helper< boost::units::unit, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// unit / quantity. template struct plain_return_type_2, boost::units::unit, boost::units::quantity > { typedef typename boost::units::divide_typeof_helper< boost::units::unit, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity * unit. template struct plain_return_type_2, boost::units::quantity, boost::units::unit > { typedef typename boost::units::multiply_typeof_helper< boost::units::quantity, boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// quantity / unit. template struct plain_return_type_2, boost::units::quantity, boost::units::unit > { typedef typename boost::units::divide_typeof_helper< boost::units::quantity, boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// +quantity. template struct plain_return_type_1, boost::units::quantity > { typedef typename boost::units::unary_plus_typeof_helper< boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// -quantity. template struct plain_return_type_1, boost::units::quantity > { typedef typename boost::units::unary_minus_typeof_helper< boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity + quantity. template struct plain_return_type_2, boost::units::quantity, boost::units::quantity > { typedef typename boost::units::add_typeof_helper< boost::units::quantity, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity + Y. template struct plain_return_type_2, boost::units::quantity, Y> { typedef typename boost::units::add_typeof_helper< boost::units::quantity, Y>::type type; }; /// Partial specialization of return type trait for action /// X + quantity. template struct plain_return_type_2, X, boost::units::quantity > { typedef typename boost::units::add_typeof_helper< X, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity - quantity. template struct plain_return_type_2, boost::units::quantity, boost::units::quantity > { typedef typename boost::units::subtract_typeof_helper< boost::units::quantity, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity - Y. template struct plain_return_type_2, boost::units::quantity, Y> { typedef typename boost::units::subtract_typeof_helper< boost::units::quantity, Y>::type type; }; /// Partial specialization of return type trait for action /// X - quantity. template struct plain_return_type_2, X, boost::units::quantity > { typedef typename boost::units::subtract_typeof_helper< X, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity * quantity. template struct plain_return_type_2, boost::units::quantity, boost::units::quantity > { typedef typename boost::units::multiply_typeof_helper< boost::units::quantity, boost::units::quantity >::type type; }; /// Partial specialization of return type trait for action /// quantity / quantity. template struct plain_return_type_2, boost::units::quantity, boost::units::quantity > { typedef typename boost::units::divide_typeof_helper< boost::units::quantity, boost::units::quantity >::type type; }; //////////////////////////////////////////////////////////////////////// // Partial specialization of Boost.Lambda's trait classes for all // operators overloaded in //////////////////////////////////////////////////////////////////////// /// Partial specialization of return type trait for action /// +unit. template struct plain_return_type_1, boost::units::unit > { typedef typename boost::units::unary_plus_typeof_helper< boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// -unit. template struct plain_return_type_1, boost::units::unit > { typedef typename boost::units::unary_minus_typeof_helper< boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// unit + unit. template struct plain_return_type_2, boost::units::unit, boost::units::unit > { typedef typename boost::units::add_typeof_helper< boost::units::unit, boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// unit - unit. template struct plain_return_type_2, boost::units::unit, boost::units::unit > { typedef typename boost::units::subtract_typeof_helper< boost::units::unit, boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// unit * unit. template struct plain_return_type_2, boost::units::unit, boost::units::unit > { typedef typename boost::units::multiply_typeof_helper< boost::units::unit, boost::units::unit >::type type; }; /// Partial specialization of return type trait for action /// unit / unit. template struct plain_return_type_2, boost::units::unit, boost::units::unit > { typedef typename boost::units::divide_typeof_helper< boost::units::unit, boost::units::unit >::type type; }; //////////////////////////////////////////////////////////////////////// // Partial specialization of Boost.Lambda's trait classes for all // operators overloaded in //////////////////////////////////////////////////////////////////////// /// Partial specialization of return type trait for action /// absolute + Y. template struct plain_return_type_2, boost::units::absolute, Y> { typedef typename boost::units::absolute type; }; /// Partial specialization of return type trait for action /// Y + absolute. template struct plain_return_type_2, Y, boost::units::absolute > { typedef typename boost::units::absolute type; }; /// Partial specialization of return type trait for action /// absolute - Y. template struct plain_return_type_2, boost::units::absolute, Y> { typedef typename boost::units::absolute type; }; /// Partial specialization of return type trait for action /// absolute - absolute. template struct plain_return_type_2, boost::units::absolute, boost::units::absolute > { typedef Y type; }; /// Partial specialization of return type trait for action /// T * absolute >. template struct plain_return_type_2, T, boost::units::absolute > > { typedef typename boost::units::quantity< boost::units::absolute >, T> type; }; } // namespace lambda namespace units { template struct multiply_typeof_helper, boost::units::absolute > > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple, typename boost::lambda::const_copy_argument > >::type> > > type; }; /// Disambiguating overload for action /// lambda_functor * absolute > /// based on \. template inline const typename multiply_typeof_helper, boost::units::absolute > >::type operator*(const boost::lambda::lambda_functor& a, const boost::units::absolute >& b) { return typename multiply_typeof_helper, boost::units::absolute > >::type::inherited (tuple, typename boost::lambda::const_copy_argument > >::type> (a, b)); } } // namespace units namespace lambda { /// Partial specialization of return type trait for action /// absolute > * T. template struct plain_return_type_2, boost::units::absolute >, T> { typedef typename boost::units::quantity< boost::units::absolute >, T> type; }; } // namespace lambda namespace units { template struct multiply_typeof_helper >, boost::lambda::lambda_functor > { typedef boost::lambda::lambda_functor< boost::lambda::lambda_functor_base< boost::lambda::arithmetic_action, tuple > >::type, boost::lambda::lambda_functor > > > type; }; /// Disambiguating overload for action /// absolute > * lambda_functor /// based on \. template inline const typename multiply_typeof_helper >, boost::lambda::lambda_functor >::type operator*(const boost::units::absolute >& a, const boost::lambda::lambda_functor& b) { return typename multiply_typeof_helper >, boost::lambda::lambda_functor >::type::inherited (tuple > >::type, boost::lambda::lambda_functor > (a, b)); } } // namespace units } // namespace boost #endif // BOOST_UNITS_LAMBDA_HPP