| // 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) 2007-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) |
| |
| #ifndef BOOST_UNITS_CMATH_HPP |
| #define BOOST_UNITS_CMATH_HPP |
| |
| #include <boost/config/no_tr1/cmath.hpp> |
| #include <cstdlib> |
| |
| #include <boost/math/special_functions/fpclassify.hpp> |
| #include <boost/math/special_functions/hypot.hpp> |
| #include <boost/math/special_functions/next.hpp> |
| #include <boost/math/special_functions/round.hpp> |
| #include <boost/math/special_functions/sign.hpp> |
| |
| #include <boost/units/dimensionless_quantity.hpp> |
| #include <boost/units/pow.hpp> |
| #include <boost/units/quantity.hpp> |
| #include <boost/units/detail/cmath_impl.hpp> |
| #include <boost/units/detail/dimensionless_unit.hpp> |
| |
| #include <boost/units/systems/si/plane_angle.hpp> |
| |
| /// \file |
| /// \brief Overloads of functions in \<cmath\> for quantities. |
| /// \details Only functions for which a dimensionally-correct result type |
| /// can be determined are overloaded. |
| /// All functions work with dimensionless quantities. |
| |
| // BOOST_PREVENT_MACRO_SUBSTITUTION is needed on certain compilers that define |
| // some <cmath> functions as macros; it is used for all functions even though it |
| // isn't necessary -- I didn't want to think :) |
| // |
| // the form using namespace detail; return(f(x)); is used |
| // to enable ADL for UDTs. |
| |
| namespace boost { |
| |
| namespace units { |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::isfinite; |
| return isfinite BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isinf BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::isinf; |
| return isinf BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isnan BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::isnan; |
| return isnan BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::isnormal; |
| return isnormal BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isless BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return isless BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| bool |
| isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| abs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using std::abs; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(abs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| ceil BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using std::ceil; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(ceil BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| copysign BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using boost::math::copysign; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(copysign BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| fabs BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using std::fabs; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(fabs BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| floor BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using std::floor; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(floor BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| fdim BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(fdim BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| #if 0 |
| |
| template<class Unit1,class Unit2,class Unit3,class Y> |
| inline |
| typename add_typeof_helper< |
| typename multiply_typeof_helper<quantity<Unit1,Y>, |
| quantity<Unit2,Y> >::type, |
| quantity<Unit3,Y> >::type |
| fma BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit1,Y>& q1, |
| const quantity<Unit2,Y>& q2, |
| const quantity<Unit3,Y>& q3) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit1,Y> type1; |
| typedef quantity<Unit2,Y> type2; |
| typedef quantity<Unit3,Y> type3; |
| |
| typedef typename multiply_typeof_helper<type1,type2>::type prod_type; |
| typedef typename add_typeof_helper<prod_type,type3>::type quantity_type; |
| |
| return quantity_type::from_value(fma BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value(),q3.value())); |
| } |
| |
| #endif |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| fmax BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(fmax BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| fmin BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(fmin BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| int |
| fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::fpclassify; |
| |
| return fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| typename root_typeof_helper< |
| typename add_typeof_helper< |
| typename power_typeof_helper<quantity<Unit,Y>, |
| static_rational<2> >::type, |
| typename power_typeof_helper<quantity<Unit,Y>, |
| static_rational<2> >::type>::type, |
| static_rational<2> >::type |
| hypot BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1,const quantity<Unit,Y>& q2) |
| { |
| using boost::math::hypot; |
| |
| typedef quantity<Unit,Y> type1; |
| |
| typedef typename power_typeof_helper<type1,static_rational<2> >::type pow_type; |
| typedef typename add_typeof_helper<pow_type,pow_type>::type add_type; |
| typedef typename root_typeof_helper<add_type,static_rational<2> >::type quantity_type; |
| |
| return quantity_type::from_value(hypot BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| // does ISO C++ support long long? g++ claims not |
| //template<class Unit,class Y> |
| //inline |
| //quantity<Unit,long long> |
| //llrint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| //{ |
| // using namespace detail; |
| // |
| // typedef quantity<Unit,long long> quantity_type; |
| // |
| // return quantity_type::from_value(llrint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| //} |
| |
| // does ISO C++ support long long? g++ claims not |
| //template<class Unit,class Y> |
| //inline |
| //quantity<Unit,long long> |
| //llround BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| //{ |
| // using namespace detail; |
| // |
| // typedef quantity<Unit,long long> quantity_type; |
| // |
| // return quantity_type::from_value(llround BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| //} |
| |
| #if 0 |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| #endif |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| using boost::math::nextafter; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q1, |
| const quantity<Unit,Y>& q2) |
| { |
| // the only difference between nextafter and nexttowards is |
| // in the argument types. Since we are requiring identical |
| // argument types, there is no difference. |
| using boost::math::nextafter; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(nextafter BOOST_PREVENT_MACRO_SUBSTITUTION (q1.value(),q2.value())); |
| } |
| |
| #if 0 |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| rint BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(rint BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| #endif |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| round BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::round; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(round BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| int |
| signbit BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using boost::math::signbit; |
| |
| return signbit BOOST_PREVENT_MACRO_SUBSTITUTION (q.value()); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit,Y> |
| trunc BOOST_PREVENT_MACRO_SUBSTITUTION (const quantity<Unit,Y>& q) |
| { |
| using namespace detail; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(trunc BOOST_PREVENT_MACRO_SUBSTITUTION (q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| quantity<Unit, Y> |
| fmod(const quantity<Unit,Y>& q1, const quantity<Unit,Y>& q2) |
| { |
| using std::fmod; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(fmod(q1.value(), q2.value())); |
| } |
| |
| template<class Unit, class Y> |
| inline |
| quantity<Unit, Y> |
| modf(const quantity<Unit, Y>& q1, quantity<Unit, Y>* q2) |
| { |
| using std::modf; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(modf(q1.value(), &quantity_cast<Y&>(*q2))); |
| } |
| |
| template<class Unit, class Y, class Int> |
| inline |
| quantity<Unit, Y> |
| frexp(const quantity<Unit, Y>& q,Int* ex) |
| { |
| using std::frexp; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(frexp(q.value(),ex)); |
| } |
| |
| /// For non-dimensionless quantities, integral and rational powers |
| /// and roots can be computed by @c pow<Ex> and @c root<Rt> respectively. |
| template<class S, class Y> |
| inline |
| quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> |
| pow(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q1, |
| const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q2) |
| { |
| using std::pow; |
| |
| typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S),Y> quantity_type; |
| |
| return quantity_type::from_value(pow(q1.value(), q2.value())); |
| } |
| |
| template<class S, class Y> |
| inline |
| quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> |
| exp(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q) |
| { |
| using std::exp; |
| |
| typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
| |
| return quantity_type::from_value(exp(q.value())); |
| } |
| |
| template<class Unit, class Y, class Int> |
| inline |
| quantity<Unit, Y> |
| ldexp(const quantity<Unit, Y>& q,const Int& ex) |
| { |
| using std::ldexp; |
| |
| typedef quantity<Unit,Y> quantity_type; |
| |
| return quantity_type::from_value(ldexp(q.value(), ex)); |
| } |
| |
| template<class S, class Y> |
| inline |
| quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> |
| log(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q) |
| { |
| using std::log; |
| |
| typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
| |
| return quantity_type::from_value(log(q.value())); |
| } |
| |
| template<class S, class Y> |
| inline |
| quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> |
| log10(const quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y>& q) |
| { |
| using std::log10; |
| |
| typedef quantity<BOOST_UNITS_DIMENSIONLESS_UNIT(S), Y> quantity_type; |
| |
| return quantity_type::from_value(log10(q.value())); |
| } |
| |
| template<class Unit,class Y> |
| inline |
| typename root_typeof_helper< |
| quantity<Unit,Y>, |
| static_rational<2> |
| >::type |
| sqrt(const quantity<Unit,Y>& q) |
| { |
| using std::sqrt; |
| |
| typedef typename root_typeof_helper< |
| quantity<Unit,Y>, |
| static_rational<2> |
| >::type quantity_type; |
| |
| return quantity_type::from_value(sqrt(q.value())); |
| } |
| |
| } // namespace units |
| |
| } // namespace boost |
| |
| namespace boost { |
| |
| namespace units { |
| |
| // trig functions with si argument/return types |
| |
| /// cos of theta in radians |
| template<class Y> |
| typename dimensionless_quantity<si::system,Y>::type |
| cos(const quantity<si::plane_angle,Y>& theta) |
| { |
| using std::cos; |
| return cos(theta.value()); |
| } |
| |
| /// sin of theta in radians |
| template<class Y> |
| typename dimensionless_quantity<si::system,Y>::type |
| sin(const quantity<si::plane_angle,Y>& theta) |
| { |
| using std::sin; |
| return sin(theta.value()); |
| } |
| |
| /// tan of theta in radians |
| template<class Y> |
| typename dimensionless_quantity<si::system,Y>::type |
| tan(const quantity<si::plane_angle,Y>& theta) |
| { |
| using std::tan; |
| return tan(theta.value()); |
| } |
| |
| /// cos of theta in other angular units |
| template<class System,class Y> |
| typename dimensionless_quantity<System,Y>::type |
| cos(const quantity<unit<plane_angle_dimension,System>,Y>& theta) |
| { |
| return cos(quantity<si::plane_angle,Y>(theta)); |
| } |
| |
| /// sin of theta in other angular units |
| template<class System,class Y> |
| typename dimensionless_quantity<System,Y>::type |
| sin(const quantity<unit<plane_angle_dimension,System>,Y>& theta) |
| { |
| return sin(quantity<si::plane_angle,Y>(theta)); |
| } |
| |
| /// tan of theta in other angular units |
| template<class System,class Y> |
| typename dimensionless_quantity<System,Y>::type |
| tan(const quantity<unit<plane_angle_dimension,System>,Y>& theta) |
| { |
| return tan(quantity<si::plane_angle,Y>(theta)); |
| } |
| |
| /// acos of dimensionless quantity returning angle in same system |
| template<class Y,class System> |
| quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y> |
| acos(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val) |
| { |
| using std::acos; |
| return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(acos(val.value())*si::radians); |
| } |
| |
| /// acos of dimensionless quantity returning angle in radians |
| template<class Y> |
| quantity<angle::radian_base_unit::unit_type,Y> |
| acos(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val) |
| { |
| using std::acos; |
| return quantity<angle::radian_base_unit::unit_type,Y>::from_value(acos(val.value())); |
| } |
| |
| /// asin of dimensionless quantity returning angle in same system |
| template<class Y,class System> |
| quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y> |
| asin(const quantity<unit<dimensionless_type, homogeneous_system<System> >,Y>& val) |
| { |
| using std::asin; |
| return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(asin(val.value())*si::radians); |
| } |
| |
| /// asin of dimensionless quantity returning angle in radians |
| template<class Y> |
| quantity<angle::radian_base_unit::unit_type,Y> |
| asin(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>,Y>& val) |
| { |
| using std::asin; |
| return quantity<angle::radian_base_unit::unit_type,Y>::from_value(asin(val.value())); |
| } |
| |
| /// atan of dimensionless quantity returning angle in same system |
| template<class Y,class System> |
| quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y> |
| atan(const quantity<unit<dimensionless_type, homogeneous_system<System> >, Y>& val) |
| { |
| using std::atan; |
| return quantity<unit<plane_angle_dimension, homogeneous_system<System> >,Y>(atan(val.value())*si::radians); |
| } |
| |
| /// atan of dimensionless quantity returning angle in radians |
| template<class Y> |
| quantity<angle::radian_base_unit::unit_type,Y> |
| atan(const quantity<unit<dimensionless_type, heterogeneous_dimensionless_system>, Y>& val) |
| { |
| using std::atan; |
| return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan(val.value())); |
| } |
| |
| /// atan2 of @c value_type returning angle in radians |
| template<class Y, class Dimension, class System> |
| quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y> |
| atan2(const quantity<unit<Dimension, homogeneous_system<System> >, Y>& y, |
| const quantity<unit<Dimension, homogeneous_system<System> >, Y>& x) |
| { |
| using std::atan2; |
| return quantity<unit<plane_angle_dimension, homogeneous_system<System> >, Y>(atan2(y.value(),x.value())*si::radians); |
| } |
| |
| /// atan2 of @c value_type returning angle in radians |
| template<class Y, class Dimension, class System> |
| quantity<angle::radian_base_unit::unit_type,Y> |
| atan2(const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& y, |
| const quantity<unit<Dimension, heterogeneous_system<System> >, Y>& x) |
| { |
| using std::atan2; |
| return quantity<angle::radian_base_unit::unit_type,Y>::from_value(atan2(y.value(),x.value())); |
| } |
| |
| } // namespace units |
| |
| } // namespace boost |
| |
| #endif // BOOST_UNITS_CMATH_HPP |