Chris@16: // Boost.Units - A C++ library for zero-overhead dimensional analysis and Chris@16: // unit/quantity manipulation and conversion Chris@16: // Chris@16: // Copyright (C) 2003-2008 Matthias Christian Schabel Chris@16: // Copyright (C) 2007-2008 Steven Watanabe Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_UNITS_CMATH_HPP Chris@16: #define BOOST_UNITS_CMATH_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: /// \file Chris@16: /// \brief Overloads of functions in \ for quantities. Chris@16: /// \details Only functions for which a dimensionally-correct result type Chris@16: /// can be determined are overloaded. Chris@16: /// All functions work with dimensionless quantities. Chris@16: Chris@16: // BOOST_PREVENT_MACRO_SUBSTITUTION is needed on certain compilers that define Chris@16: // some functions as macros; it is used for all functions even though it Chris@16: // isn't necessary -- I didn't want to think :) Chris@16: // Chris@16: // the form using namespace detail; return(f(x)); is used Chris@16: // to enable ADL for UDTs. Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::isfinite; Chris@16: return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::isinf; Chris@16: return isinf BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::isnan; Chris@16: return isnan BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::isnormal; Chris@16: return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isless BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return isless BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: bool Chris@16: isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: abs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using std::abs; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(abs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: ceil BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using std::ceil; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(ceil BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: copysign BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using boost::math::copysign; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(copysign BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: fabs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using std::fabs; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fabs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: floor BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using std::floor; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(floor BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: fdim BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fdim BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: #if 0 Chris@16: Chris@16: template Chris@16: inline Chris@16: typename add_typeof_helper< Chris@16: typename multiply_typeof_helper, Chris@16: quantity >::type, Chris@16: quantity >::type Chris@16: fma BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2, Chris@16: const quantity& q3) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity type1; Chris@16: typedef quantity type2; Chris@16: typedef quantity type3; Chris@16: Chris@16: typedef typename multiply_typeof_helper::type prod_type; Chris@16: typedef typename add_typeof_helper::type quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fma BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value(),q3.value())); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: fmax BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fmax BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: fmin BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fmin BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: int Chris@16: fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::fpclassify; Chris@16: Chris@16: return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: typename root_typeof_helper< Chris@16: typename add_typeof_helper< Chris@16: typename power_typeof_helper, Chris@16: static_rational<2> >::type, Chris@16: typename power_typeof_helper, Chris@16: static_rational<2> >::type>::type, Chris@16: static_rational<2> >::type Chris@16: hypot BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1,const quantity& q2) Chris@16: { Chris@16: using boost::math::hypot; Chris@16: Chris@16: typedef quantity type1; Chris@16: Chris@16: typedef typename power_typeof_helper >::type pow_type; Chris@16: typedef typename add_typeof_helper::type add_type; Chris@16: typedef typename root_typeof_helper >::type quantity_type; Chris@16: Chris@16: return quantity_type::from_value(hypot BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: // does ISO C++ support long long? g++ claims not Chris@16: //template Chris@16: //inline Chris@16: //quantity Chris@16: //llrint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: //{ Chris@16: // using namespace detail; Chris@16: // Chris@16: // typedef quantity quantity_type; Chris@16: // Chris@16: // return quantity_type::from_value(llrint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: //} Chris@16: Chris@16: // does ISO C++ support long long? g++ claims not Chris@16: //template Chris@16: //inline Chris@16: //quantity Chris@16: //llround BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: //{ Chris@16: // using namespace detail; Chris@16: // Chris@16: // typedef quantity quantity_type; Chris@16: // Chris@16: // return quantity_type::from_value(llround BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: //} Chris@16: Chris@16: #if 0 Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using boost::math::nextafter; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: template Chris@16: inline Chris@16: quantity nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: // the only difference between nextafter and nexttowards is Chris@16: // in the argument types. Since we are requiring identical Chris@16: // argument types, there is no difference. Chris@16: using boost::math::nextafter; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); Chris@16: } Chris@16: Chris@16: #if 0 Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: rint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(rint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: round BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::round; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(round BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: int Chris@16: signbit BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using boost::math::signbit; Chris@16: Chris@16: return signbit BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity& q) Chris@16: { Chris@16: using namespace detail; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(trunc BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: fmod(const quantity& q1, const quantity& q2) Chris@16: { Chris@16: using std::fmod; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(fmod(q1.value(), q2.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: modf(const quantity& q1, quantity* q2) Chris@16: { Chris@16: using std::modf; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(modf(q1.value(), &quantity_cast(*q2))); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: frexp(const quantity& q,Int* ex) Chris@16: { Chris@16: using std::frexp; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(frexp(q.value(),ex)); Chris@16: } Chris@16: Chris@16: /// For non-dimensionless quantities, integral and rational powers Chris@16: /// and roots can be computed by @c pow and @c root respectively. Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: pow(const quantity& q1, Chris@16: const quantity& q2) Chris@16: { Chris@16: using std::pow; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(pow(q1.value(), q2.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: exp(const quantity& q) Chris@16: { Chris@16: using std::exp; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(exp(q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: ldexp(const quantity& q,const Int& ex) Chris@16: { Chris@16: using std::ldexp; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(ldexp(q.value(), ex)); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: log(const quantity& q) Chris@16: { Chris@16: using std::log; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(log(q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: quantity Chris@16: log10(const quantity& q) Chris@16: { Chris@16: using std::log10; Chris@16: Chris@16: typedef quantity quantity_type; Chris@16: Chris@16: return quantity_type::from_value(log10(q.value())); Chris@16: } Chris@16: Chris@16: template Chris@16: inline Chris@16: typename root_typeof_helper< Chris@16: quantity, Chris@16: static_rational<2> Chris@16: >::type Chris@16: sqrt(const quantity& q) Chris@16: { Chris@16: using std::sqrt; Chris@16: Chris@16: typedef typename root_typeof_helper< Chris@16: quantity, Chris@16: static_rational<2> Chris@16: >::type quantity_type; Chris@16: Chris@16: return quantity_type::from_value(sqrt(q.value())); Chris@16: } Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace units { Chris@16: Chris@16: // trig functions with si argument/return types Chris@16: Chris@16: /// cos of theta in radians Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: cos(const quantity& theta) Chris@16: { Chris@16: using std::cos; Chris@16: return cos(theta.value()); Chris@16: } Chris@16: Chris@16: /// sin of theta in radians Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: sin(const quantity& theta) Chris@16: { Chris@16: using std::sin; Chris@16: return sin(theta.value()); Chris@16: } Chris@16: Chris@16: /// tan of theta in radians Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: tan(const quantity& theta) Chris@16: { Chris@16: using std::tan; Chris@16: return tan(theta.value()); Chris@16: } Chris@16: Chris@16: /// cos of theta in other angular units Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: cos(const quantity,Y>& theta) Chris@16: { Chris@16: return cos(quantity(theta)); Chris@16: } Chris@16: Chris@16: /// sin of theta in other angular units Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: sin(const quantity,Y>& theta) Chris@16: { Chris@16: return sin(quantity(theta)); Chris@16: } Chris@16: Chris@16: /// tan of theta in other angular units Chris@16: template Chris@16: typename dimensionless_quantity::type Chris@16: tan(const quantity,Y>& theta) Chris@16: { Chris@16: return tan(quantity(theta)); Chris@16: } Chris@16: Chris@16: /// acos of dimensionless quantity returning angle in same system Chris@16: template Chris@16: quantity >,Y> Chris@16: acos(const quantity >,Y>& val) Chris@16: { Chris@16: using std::acos; Chris@16: return quantity >,Y>(acos(val.value())*si::radians); Chris@16: } Chris@16: Chris@16: /// acos of dimensionless quantity returning angle in radians Chris@16: template Chris@16: quantity Chris@16: acos(const quantity,Y>& val) Chris@16: { Chris@16: using std::acos; Chris@16: return quantity::from_value(acos(val.value())); Chris@16: } Chris@16: Chris@16: /// asin of dimensionless quantity returning angle in same system Chris@16: template Chris@16: quantity >,Y> Chris@16: asin(const quantity >,Y>& val) Chris@16: { Chris@16: using std::asin; Chris@16: return quantity >,Y>(asin(val.value())*si::radians); Chris@16: } Chris@16: Chris@16: /// asin of dimensionless quantity returning angle in radians Chris@16: template Chris@16: quantity Chris@16: asin(const quantity,Y>& val) Chris@16: { Chris@16: using std::asin; Chris@16: return quantity::from_value(asin(val.value())); Chris@16: } Chris@16: Chris@16: /// atan of dimensionless quantity returning angle in same system Chris@16: template Chris@16: quantity >,Y> Chris@16: atan(const quantity >, Y>& val) Chris@16: { Chris@16: using std::atan; Chris@16: return quantity >,Y>(atan(val.value())*si::radians); Chris@16: } Chris@16: Chris@16: /// atan of dimensionless quantity returning angle in radians Chris@16: template Chris@16: quantity Chris@16: atan(const quantity, Y>& val) Chris@16: { Chris@16: using std::atan; Chris@16: return quantity::from_value(atan(val.value())); Chris@16: } Chris@16: Chris@16: /// atan2 of @c value_type returning angle in radians Chris@16: template Chris@16: quantity >, Y> Chris@16: atan2(const quantity >, Y>& y, Chris@16: const quantity >, Y>& x) Chris@16: { Chris@16: using std::atan2; Chris@16: return quantity >, Y>(atan2(y.value(),x.value())*si::radians); Chris@16: } Chris@16: Chris@16: /// atan2 of @c value_type returning angle in radians Chris@16: template Chris@16: quantity Chris@16: atan2(const quantity >, Y>& y, Chris@16: const quantity >, Y>& x) Chris@16: { Chris@16: using std::atan2; Chris@16: return quantity::from_value(atan2(y.value(),x.value())); Chris@16: } Chris@16: Chris@16: } // namespace units Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #endif // BOOST_UNITS_CMATH_HPP