summaryrefslogtreecommitdiff
path: root/boost/units/cmath.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/units/cmath.hpp')
-rw-r--r--boost/units/cmath.hpp676
1 files changed, 676 insertions, 0 deletions
diff --git a/boost/units/cmath.hpp b/boost/units/cmath.hpp
new file mode 100644
index 0000000..238b31c
--- /dev/null
+++ b/boost/units/cmath.hpp
@@ -0,0 +1,676 @@
+// 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