//////////////////////////////////////////////////////////////////////// /// /// \file lambda_functor.cpp /// /// \brief Example demonstrating how functors with a sig template can /// simplify the usage of the cmath functions overloaded for /// Boost.Units' quantity type in functors created with the /// Boost.Lambda library and stored in Boost.Function objects. /// /// \author Torsten Maehne /// \date 2008-06-06 /// //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include // Include boost/units/lambda.hpp instead of boost/lambda/lambda.hpp // for a convenient usage of Boost.Units' quantity, unit, and absolute // types in lambda expressions. The header augments Boost.Lambda's // return type detuction system to recognize the new types so that not // for each arithmetic operation the return type needs to be // explicitely specified. #include #include #include #include #include #include /// \brief Functor for the sin function from cmath.hpp. struct sin_t { template class sig { private: typedef typename boost::tuples::element<1, Args>::type arg1_type; BOOST_TYPEOF_NESTED_TYPEDEF(nested, (boost::units::sin(boost::units::typeof_::make()))) public: typedef typename nested::type type; }; template typename sig >::type operator()(const T& arg) const { return boost::units::sin(arg); } }; /// \brief Templatized functor for the pow function from pow.hpp. template struct pow_t { template class sig { private: typedef typename boost::tuples::element<1, Args>::type arg1_type; BOOST_TYPEOF_NESTED_TYPEDEF(nested, (boost::units::pow(boost::units::typeof_::make()))) public: typedef typename nested::type type; }; template typename sig, Y> >::type operator()(const Y& arg) const { return boost::units::pow(arg); } }; int main(int argc, char **argv) { using namespace std; namespace bl = boost::lambda; namespace bu = boost::units; namespace si = boost::units::si; // Test if an instance of sin_t works like boost::units::sin() cout << "sin_t()(0.5 * M_PI * si::radian) = " << sin_t()(0.5 * M_PI * si::radian) << endl; // Test sig template BOOST_STATIC_ASSERT((boost::is_same > >::type, bu::quantity >::value == true)); // Create a functor object using Boost.Lambda's bind boost::function (bu::quantity)> sin_f = bl::bind(sin_t(), bl::_1); cout << "sin_f(0.5 * M_PI * si::radian) = " << sin_f(0.5 * M_PI * si::radian) << endl; // Create a functor describing a sinusoidal waveform boost::function (bu::quantity)> wave_f = 1.5 * si::volt * bl::bind(sin_t(), 2.0 * M_PI * si::radian * 50.0 * si::hertz * bl::_1); cout << "wave_f(5.0e-3 * si::second) = " << wave_f(5.0e-3 * si::second) << endl; // Create a functor by binding a lambda placeholder to a templated functor boost::function::type> (bu::quantity)> pow2_f = bl::bind(pow_t >(), bl::_1); cout << "pow2_f(2.0 * si::meter) = " << pow2_f(2.0 * si::meter) << endl; return 0; }