Boost logo

Boost-Commit :

From: steven_at_[hidden]
Date: 2008-06-18 00:14:13


Author: steven_watanabe
Date: 2008-06-18 00:14:12 EDT (Wed, 18 Jun 2008)
New Revision: 46468
URL: http://svn.boost.org/trac/boost/changeset/46468

Log:
Added Lambda interoperability header from Torsten Maehne
Added:
   trunk/boost/units/lambda.hpp (contents, props changed)
   trunk/libs/units/test/test_lambda.cpp (contents, props changed)
Text files modified:
   trunk/libs/units/doc/units.qbk | 9 +++++++++
   trunk/libs/units/test/Jamfile.v2 | 1 +
   2 files changed, 10 insertions(+), 0 deletions(-)

Added: trunk/boost/units/lambda.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/units/lambda.hpp 2008-06-18 00:14:12 EDT (Wed, 18 Jun 2008)
@@ -0,0 +1,548 @@
+// 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 <boost/lambda/lambda.hpp>
+#include <boost/units/units_fwd.hpp>
+#include <boost/units/operators.hpp>
+
+namespace boost {
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim, System> * Y.
+ template<typename System, typename Dim, typename Y>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::unit<Dim, System>,
+ Y > {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::unit<Dim, System>, Y >::type type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> > {
+ typename boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
+ tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type, boost::lambda::lambda_functor<Arg> >
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// unit<Dim, System> * lambda_functor<Arg>
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type
+ operator*(const boost::units::unit<Dim, System>& a,
+ const boost::lambda::lambda_functor<Arg>& b) {
+ return typename multiply_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type::inherited
+ (tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type,
+ boost::lambda::lambda_functor<Arg> >
+ (a, b));
+ }
+
+} // namespace units
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim, System> / Y.
+ template<typename System, typename Dim, typename Y>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::unit<Dim, System>,
+ Y > {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::unit<Dim, System>, Y >::type type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> > {
+ typedef boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::divide_action>,
+ tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type, boost::lambda::lambda_functor<Arg> >
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// unit<Dim, System> / lambda_functor<Arg>
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type
+ operator/(const boost::units::unit<Dim, System>& a,
+ const boost::lambda::lambda_functor<Arg>& b) {
+ return typename divide_typeof_helper<boost::units::unit<Dim, System>, boost::lambda::lambda_functor<Arg> >::type::inherited
+ (tuple<typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type,
+ boost::lambda::lambda_functor<Arg> >
+ (a, b));
+ }
+
+} // namespace units
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// Y * unit<Dim, System>.
+ template<typename System, typename Dim, typename Y>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ Y,
+ boost::units::unit<Dim, System> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ Y, boost::units::unit<Dim, System> >::type type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> > {
+ typedef boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
+ tuple<boost::lambda::lambda_functor<Arg>, typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// lambda_functor<Arg> * unit<Dim, System>
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type
+ operator*(const boost::lambda::lambda_functor<Arg>& a,
+ const boost::units::unit<Dim, System>& b) {
+ return typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type::inherited
+ (tuple<boost::lambda::lambda_functor<Arg>,
+ typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
+ (a, b));
+ }
+
+} // namespace units
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// Y / unit<Dim, System>.
+ template<typename System, typename Dim, typename Y>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ Y,
+ boost::units::unit<Dim, System> > {
+ typedef typename boost::units::divide_typeof_helper<
+ Y, boost::units::unit<Dim, System> >::type type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> > {
+ typedef boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::divide_action>,
+ tuple<boost::lambda::lambda_functor<Arg>, typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// lambda_functor<Arg> / unit<Dim, System>
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type
+ operator/(const boost::lambda::lambda_functor<Arg>& a,
+ const boost::units::unit<Dim, System>& b) {
+ return typename divide_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::unit<Dim, System> >::type::inherited
+ (tuple<boost::lambda::lambda_functor<Arg>,
+ typename boost::lambda::const_copy_argument<const boost::units::unit<Dim, System> >::type>
+ (a, b));
+ }
+
+} // namespace units
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit, X> * X.
+ template<typename Unit, typename X>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::quantity<Unit, X>,
+ X> {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::quantity<Unit, X>, X>::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// X * quantity<Unit, X>.
+ template<typename Unit, typename X>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ X,
+ boost::units::quantity<Unit, X> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ X, boost::units::quantity<Unit, X> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit, X> / X.
+ template<typename Unit, typename X>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::quantity<Unit, X>,
+ X> {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::quantity<Unit, X>, X>::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// X / quantity<Unit, X>.
+ template<typename Unit, typename X>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ X,
+ boost::units::quantity<Unit, X> > {
+ typedef typename boost::units::divide_typeof_helper<
+ X, boost::units::quantity<Unit, X> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> * quantity<Unit2, Y>.
+ template<typename System1, typename Dim1, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> / quantity<Unit2, Y>.
+ template<typename System1, typename Dim1, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, Y> * unit<Dim2, System2>.
+ template<typename Unit1, typename Y, typename System2, typename Dim2>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::quantity<Unit1, Y>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::quantity<Unit1, Y>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, Y> / unit<Dim2, System2>.
+ template<typename Unit1, typename Y, typename System2, typename Dim2>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::quantity<Unit1, Y>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::quantity<Unit1, Y>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// +quantity<Unit, Y>.
+ template<typename Unit, typename Y>
+ struct plain_return_type_1<unary_arithmetic_action<plus_action>,
+ boost::units::quantity<Unit, Y> > {
+ typedef typename boost::units::unary_plus_typeof_helper<
+ boost::units::quantity<Unit, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// -quantity<Unit, Y>.
+ template<typename Unit, typename Y>
+ struct plain_return_type_1<unary_arithmetic_action<minus_action>,
+ boost::units::quantity<Unit, Y> > {
+ typedef typename boost::units::unary_minus_typeof_helper<
+ boost::units::quantity<Unit, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, X> + quantity<Unit2, Y>.
+ template<typename Unit1, typename X, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<plus_action>,
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::add_typeof_helper<
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, X> - quantity<Unit2, Y>.
+ template<typename Unit1, typename X, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<minus_action>,
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::subtract_typeof_helper<
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, X> * quantity<Unit2, Y>.
+ template<typename Unit1, typename X, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// quantity<Unit1, X> / quantity<Unit2, Y>.
+ template<typename Unit1, typename X, typename Unit2, typename Y>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> > {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::quantity<Unit1, X>,
+ boost::units::quantity<Unit2, Y> >::type type;
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////
+ // Partial specialization of Boost.Lambda's trait classes for all
+ // operators overloaded in <boost/units/unit.hpp>
+ ////////////////////////////////////////////////////////////////////////
+
+ /// Partial specialization of return type trait for action
+ /// +unit<Dim, System>.
+ template<typename Dim, typename System>
+ struct plain_return_type_1<unary_arithmetic_action<plus_action>,
+ boost::units::unit<Dim, System> > {
+ typedef typename boost::units::unary_plus_typeof_helper<
+ boost::units::unit<Dim, System> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// -unit<Dim, System>.
+ template<typename Dim, typename System>
+ struct plain_return_type_1<unary_arithmetic_action<minus_action>,
+ boost::units::unit<Dim, System> > {
+ typedef typename boost::units::unary_minus_typeof_helper<
+ boost::units::unit<Dim, System> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> + unit<Dim2, System2>.
+ template<typename Dim1, typename Dim2, typename System1, typename System2>
+ struct plain_return_type_2<arithmetic_action<plus_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::add_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> - unit<Dim2, System2>.
+ template<typename Dim1, typename Dim2, typename System1, typename System2>
+ struct plain_return_type_2<arithmetic_action<minus_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::subtract_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> * unit<Dim2, System2>.
+ template<typename Dim1, typename Dim2, typename System1, typename System2>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::multiply_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// unit<Dim1, System1> / unit<Dim2, System2>.
+ template<typename Dim1, typename Dim2, typename System1, typename System2>
+ struct plain_return_type_2<arithmetic_action<divide_action>,
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> > {
+ typedef typename boost::units::divide_typeof_helper<
+ boost::units::unit<Dim1, System1>,
+ boost::units::unit<Dim2, System2> >::type type;
+ };
+
+
+ ////////////////////////////////////////////////////////////////////////
+ // Partial specialization of Boost.Lambda's trait classes for all
+ // operators overloaded in <boost/units/absolute.hpp>
+ ////////////////////////////////////////////////////////////////////////
+
+
+ /// Partial specialization of return type trait for action
+ /// absolute<Y> + Y.
+ template<typename Y>
+ struct plain_return_type_2<arithmetic_action<plus_action>,
+ boost::units::absolute<Y>,
+ Y> {
+ typedef typename boost::units::absolute<Y> type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// Y + absolute<Y>.
+ template<typename Y>
+ struct plain_return_type_2<arithmetic_action<plus_action>,
+ Y,
+ boost::units::absolute<Y> > {
+ typedef typename boost::units::absolute<Y> type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// absolute<Y> - Y.
+ template<typename Y>
+ struct plain_return_type_2<arithmetic_action<minus_action>,
+ boost::units::absolute<Y>,
+ Y> {
+ typedef typename boost::units::absolute<Y> type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// absolute<Y> - absolute<Y>.
+ template<typename Y>
+ struct plain_return_type_2<arithmetic_action<minus_action>,
+ boost::units::absolute<Y>,
+ boost::units::absolute<Y> > {
+ typedef Y type;
+ };
+
+ /// Partial specialization of return type trait for action
+ /// T * absolute<unit<D, S> >.
+ template<typename D, typename S, typename T>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ T,
+ boost::units::absolute<boost::units::unit<D, S> > > {
+ typedef typename boost::units::quantity<
+ boost::units::absolute<boost::units::unit<D, S> >, T> type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > > {
+ typedef boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
+ tuple<boost::lambda::lambda_functor<Arg>,
+ typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type>
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// lambda_functor<Arg> * absolute<unit<Dim, System> >
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > >::type
+ operator*(const boost::lambda::lambda_functor<Arg>& a,
+ const boost::units::absolute<boost::units::unit<Dim, System> >& b) {
+ return typename multiply_typeof_helper<boost::lambda::lambda_functor<Arg>, boost::units::absolute<boost::units::unit<Dim, System> > >::type::inherited
+ (tuple<boost::lambda::lambda_functor<Arg>,
+ typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type>
+ (a, b));
+ }
+
+} // namespace units
+
+namespace lambda {
+
+ /// Partial specialization of return type trait for action
+ /// absolute<unit<D, S> > * T.
+ template<typename D, typename S, typename T>
+ struct plain_return_type_2<arithmetic_action<multiply_action>,
+ boost::units::absolute<boost::units::unit<D, S> >,
+ T> {
+ typedef typename boost::units::quantity<
+ boost::units::absolute<boost::units::unit<D, S> >, T> type;
+ };
+
+} // namespace lambda
+
+namespace units {
+
+ template<typename System, typename Dim, typename Arg>
+ struct multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> > {
+ typedef boost::lambda::lambda_functor<
+ boost::lambda::lambda_functor_base<
+ boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
+ tuple<typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type,
+ boost::lambda::lambda_functor<Arg> >
+ >
+ > type;
+ };
+
+ /// Disambiguating overload for action
+ /// absolute<unit<Dim, System> > * lambda_functor<Arg>
+ /// based on \<boost/lambda/detail/operators.hpp\>.
+ template<typename System, typename Dim, typename Arg>
+ inline const typename multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> >::type
+ operator*(const boost::units::absolute<boost::units::unit<Dim, System> >& a,
+ const boost::lambda::lambda_functor<Arg>& b) {
+ return typename multiply_typeof_helper<boost::units::absolute<boost::units::unit<Dim, System> >, boost::lambda::lambda_functor<Arg> >::type::inherited
+ (tuple<typename boost::lambda::const_copy_argument<const boost::units::absolute<boost::units::unit<Dim, System> > >::type,
+ boost::lambda::lambda_functor<Arg> >
+ (a, b));
+ }
+
+} // namespace units
+
+} // namespace boost
+
+#endif // BOOST_UNITS_LAMBDA_HPP

Modified: trunk/libs/units/doc/units.qbk
==============================================================================
--- trunk/libs/units/doc/units.qbk (original)
+++ trunk/libs/units/doc/units.qbk 2008-06-18 00:14:12 EDT (Wed, 18 Jun 2008)
@@ -1050,6 +1050,14 @@
 
 [endsect]
 
+[section Library Interoperability]
+
+The header [headerref boost/lambda/lambda.hpp] provides overloads
+and specializations needed to make Boost.Units usable with the
+Boost.Lambda library.
+
+[endsect]
+
 [section:Reference Reference]
 
 [xinclude units_reference.xml]
@@ -1203,6 +1211,7 @@
 * Janek Kozicki,
 * Andy Little,
 * Kevin Lynch,
+* Torsten Maehne
 * Noah Roberts,
 * Andrey Semashev,
 * David Walthall,

Modified: trunk/libs/units/test/Jamfile.v2
==============================================================================
--- trunk/libs/units/test/Jamfile.v2 (original)
+++ trunk/libs/units/test/Jamfile.v2 2008-06-18 00:14:12 EDT (Wed, 18 Jun 2008)
@@ -44,6 +44,7 @@
     [ run test_limits.cpp : : : : ]
     [ run test_custom_unit.cpp : : : : ]
     [ run test_scaled_conversion.cpp : : : : ]
+ [ run test_lambda.cpp : : : : ]
     [ run test_scaled_unit.cpp test_framework : : : : ]
 # [ run check_conversion_defs.cpp $(checklibs) : : : <dependency>$(check-conversion-dependencies) : ]
     [ compile-fail fail_implicit_conversion.cpp : : ]

Added: trunk/libs/units/test/test_lambda.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/units/test/test_lambda.cpp 2008-06-18 00:14:12 EDT (Wed, 18 Jun 2008)
@@ -0,0 +1,257 @@
+// 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: test_lambda.cpp 27 2008-06-16 14:50:58Z maehne $
+
+////////////////////////////////////////////////////////////////////////
+///
+/// \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-16
+///
+/// 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.
+///
+////////////////////////////////////////////////////////////////////////
+
+#include <boost/function.hpp>
+#include <boost/units/lambda.hpp>
+#include <boost/units/absolute.hpp>
+#include <boost/units/systems/si/temperature.hpp>
+#include "test_header.hpp"
+
+
+namespace bl = boost::lambda;
+namespace bu = boost::units;
+namespace si = boost::units::si;
+
+
+int test_main(int, char *[])
+{
+
+ ////////////////////////////////////////////////////////////////////////
+ // Test for Boost.Lambda working with overloaded operators defined
+ // in <boost/units/quantity.hpp>
+ ////////////////////////////////////////////////////////////////////////
+
+ bu::quantity<bu::length> lvar = 0.0 * bu::meter;
+
+ bu::quantity<bu::dimensionless> dlvar = 3.0;
+
+ // quantity<Unit, Y> += quantity<Unit2, YY>
+ boost::function<bu::quantity<bu::length> (bu::quantity<bu::length>)>
+ 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<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> += quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y>
+ dlvar = 4.0;
+ BOOST_CHECK(((bl::var(dlvar) += bl::_1)(3.0) == 7.0));
+
+ // quantity<Unit, Y> -= quantity<Unit2, YY>
+ 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<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y> -= quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(System), Y>
+ dlvar = 4.0;
+ BOOST_CHECK(((bl::var(dlvar) -= bl::_1)(3.0) == 1.0));
+
+ // quantity<Unit, Y> *= quantity<Unit2, YY>
+ dlvar = 2.0;
+ BOOST_CHECK(((bl::var(dlvar) *= bl::_1)(3.0) == 6.0));
+
+ // quantity<Unit, Y> /= quantity<Unit2, YY>
+ dlvar = 6.0;
+ BOOST_CHECK(((bl::var(dlvar) /= bl::_1)(3.0) == 2.0));
+
+ // quantity<Unit, Y> *= Y
+ lvar = 3.0 * bu::meter;
+ BOOST_CHECK(((bl::var(lvar) *= bl::_1)(2.0) == 6.0 * bu::meter));
+
+ // quantity<Unit, Y> /= Y
+ lvar = 6.0 * bu::meter;
+ BOOST_CHECK(((bl::var(lvar) /= bl::_1)(3.0) == 2.0 * bu::meter));
+
+ // unit<Dim, System> * Y
+ BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 2.0) == 2.0 * bu::meter));
+ BOOST_CHECK(((bu::meter * bl::_1)(2.0) == 2.0 * bu::meter));
+
+ // unit<Dim, System> / Y
+ BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5) == 2.0 * bu::meter));
+ BOOST_CHECK(((bu::meter / bl::_1)(0.5 * bu::second) == 2.0 * bu::meter_per_second));
+
+ // Y * unit<Dim, System>
+ BOOST_CHECK(((bl::_1 * bl::_2)(2.0, bu::meter) == 2.0 * bu::meter));
+ BOOST_CHECK(((bl::_1 * bu::meter)(2.0 / bu::second) == 2.0 * bu::meter_per_second));
+
+ // Y / unit<Dim, System>
+ BOOST_CHECK(((bl::_1 / bl::_2)(3.5, bu::second) == 3.5 / bu::second));
+ BOOST_CHECK(((bl::_1 / bu::second)(3.5 * bu::meter) == 3.5 * bu::meter_per_second));
+
+ // quantity<Unit, X> * X
+ BOOST_CHECK(((bl::_1 * bl::_2)(2.0, 3.0 * bu::meter) == 6.0 * bu::meter));
+
+ // X * quantity<Unit, X>
+ BOOST_CHECK(((bl::_1 * bl::_2)(4.0 * bu::joule, 2.0) == 8.0 * bu::joule));
+
+ // quantity<Unit, X> / X
+ BOOST_CHECK(((bl::_1 / bl::_2)(4.0 * bu::joule, 2.0) == 2.0 * bu::joule));
+
+ // X / quantity<Unit, X>
+ BOOST_CHECK(((3.0 / bl::_1)(2.0 * bu::second) == 1.5 / bu::second));
+
+ // unit<Dim1, System1> * quantity<Unit2, Y>
+ BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, 12.0 / bu::second) == 12.0 * bu::meter_per_second));
+ BOOST_CHECK(((bu::meter * bl::_1)(12.0 / bu::second) == 12.0 * bu::meter_per_second));
+
+ // unit<Dim1, System1> / quantity<Unit2, Y>
+ BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, 0.5 * bu::second) == 2.0 * bu::meter_per_second));
+ BOOST_CHECK(((bu::meter / bl::_1)(0.25 * bu::second) == 4.0 * bu::meter_per_second));
+
+ // quantity<Unit1, Y> * unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 * bl::_2)(2.0 / bu::second, bu::meter) == 2.0 * bu::meter_per_second));
+ BOOST_CHECK(((bl::_1 * bu::meter)(12.0 / bu::second) == 12.0 * bu::meter_per_second));
+
+ // quantity<Unit1, Y> / unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 / bl::_2)(3.5 * bu::meter, bu::second) == 3.5 * bu::meter_per_second));
+ BOOST_CHECK(((bl::_1 / bu::second)(5.0 * bu::second) == 5.0));
+
+ // +quantity<Unit, Y>
+ BOOST_CHECK(((+bl::_1)(5.0 * bu::second) == 5.0 * bu::second));
+
+ // -quantity<Unit, Y>
+ BOOST_CHECK(((-bl::_1)(5.0 * bu::second) == -5.0 * bu::second));
+
+ // quantity<Unit1, X> + quantity<Unit2, Y>
+ BOOST_CHECK(((bl::_1 + bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == 6.0 * bu::meter));
+
+ // quantity<Unit1, X> - quantity<Unit2, Y>
+ BOOST_CHECK(((bl::_1 - bl::_2)(2.0 * bu::meter, 4.0 * bu::meter) == -2.0 * bu::meter));
+
+ // quantity<Unit1, X> * quantity<Unit2, Y>
+ 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<Unit1, X> / quantity<Unit2, Y>
+ BOOST_CHECK(((bl::_1 / bl::_2)(2.0 * bu::meter_per_second, 4.0 * bu::meter_per_second) == 0.5));
+
+ // quantity<Unit, X> == quantity<Unit, Y>
+ 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<Unit, X> != quantity<Unit, Y>
+ 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<Unit, X> < quantity<Unit, Y>
+ 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<Unit, X> <= quantity<Unit, Y>
+ 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<Unit, X> > quantity<Unit, Y>
+ 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<Unit, X> >= quantity<Unit, Y>
+ 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 <boost/units/unit.hpp>
+ ////////////////////////////////////////////////////////////////////////
+
+ // +unit<Dim, System>
+ BOOST_CHECK(((+bl::_1)(bu::meter) == bu::meter));
+
+ // -unit<Dim, System>
+ BOOST_CHECK(((-bl::_1)(bu::meter) == bu::meter));
+
+ // unit<Dim1, System1> + unit<Dim2, System2>
+ 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<Dim1, System1> - unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 - bl::_2)(bu::meter, bu::meter) == bu::meter));
+ BOOST_CHECK(((bl::_1 - bu::meter)(bu::meter) == bu::meter));
+ BOOST_CHECK(((bu::meter - bl::_1)(bu::meter) == bu::meter));
+
+ // unit<Dim1, System1> * unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 * bl::_2)(bu::meter, bu::meter) == bu::meter * bu::meter));
+ BOOST_CHECK(((bl::_1 * bu::meter)(bu::meter) == bu::meter * bu::meter));
+
+ // unit<Dim1, System1> / unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 / bl::_2)(bu::meter, bu::second) == bu::meter_per_second));
+ BOOST_CHECK(((bl::_1 / bu::second)(bu::meter) == bu::meter_per_second));
+
+ // unit<Dim1, System1> == unit<Dim2, System2>
+ BOOST_CHECK(((bl::_1 == bu::meter)(bu::meter) == true));
+ BOOST_CHECK(((bl::_1 == bu::meter)(bu::second) == false));
+
+ // unit<Dim1, System1> != unit<Dim2, System2>
+ 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 <boost/units/absolute.hpp>
+ ////////////////////////////////////////////////////////////////////////
+
+ // absolute<Y> += Y
+ bu::quantity<bu::absolute<si::temperature> > Ta = 270.0 * bu::absolute<si::temperature>();
+ (Ta += bl::_1)(30.0 * si::kelvin);
+ BOOST_CHECK(( Ta == 300.0 * bu::absolute<si::temperature>()));
+
+ // absolute<Y> -= Y
+ Ta = 270 * bu::absolute<si::temperature>();
+ (Ta -= bl::_1)(-30.0 * si::kelvin);
+ BOOST_CHECK(( Ta == 300.0 * bu::absolute<si::temperature>()));
+
+ // absolute<Y> + Y
+ BOOST_CHECK(((270.0 * bu::absolute<si::temperature>() + bl::_1)(30.0 * si::kelvin) == 300.0 * bu::absolute<si::temperature>()));
+
+ // Y + absolute<Y>
+ BOOST_CHECK(((bl::_1 + 270.0 * bu::absolute<si::temperature>())(30.0 * si::kelvin) == 300.0 * bu::absolute<si::temperature>()));
+
+ // absolute<Y> - Y
+ BOOST_CHECK(((270.0 * bu::absolute<si::temperature>() - bl::_1)(30.0 * si::kelvin) == 240.0 * bu::absolute<si::temperature>()));
+
+ // absolute<Y> - absolute<Y>
+ BOOST_CHECK(((bl::_1 - 270.0 * bu::absolute<si::temperature>())(300.0 * bu::absolute<si::temperature>()) == 30.0 * si::kelvin));
+
+ // T * absolute<unit<D, S> >
+ BOOST_CHECK(((bl::_1 * bu::absolute<si::temperature>())(300.0) == 300.0 * bu::absolute<si::temperature>()));
+ BOOST_CHECK(((bl::_1 * bl::_2)(300.0, bu::absolute<si::temperature>()) == 300.0 * bu::absolute<si::temperature>()));
+
+ // absolute<unit<D, S> > * T
+ BOOST_CHECK(((bu::absolute<si::temperature>() * bl::_1)(300.0) == 300.0 * bu::absolute<si::temperature>()));
+ BOOST_CHECK(((bl::_1 * bl::_2)(bu::absolute<si::temperature>(), 300.0) == 300.0 * bu::absolute<si::temperature>()));
+
+
+ return 0;
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk