diff --git a/wpimath/src/main/native/include/units/base.h b/wpimath/src/main/native/include/units/base.h index bbb8a2bc4f0..e7333a91ee4 100644 --- a/wpimath/src/main/native/include/units/base.h +++ b/wpimath/src/main/native/include/units/base.h @@ -81,6 +81,8 @@ #include #endif +#include + //------------------------------ // STRING FORMATTER //------------------------------ @@ -2803,10 +2805,10 @@ namespace units * @returns new unit_t, raised to the given exponent */ template::value, int>> - inline auto pow(const UnitType& value) noexcept -> unit_t::unit_type>::type, typename units::traits::unit_t_traits::underlying_type, linear_scale> + inline constexpr auto pow(const UnitType& value) noexcept -> unit_t::unit_type>::type, typename units::traits::unit_t_traits::underlying_type, linear_scale> { return unit_t::unit_type>::type, typename units::traits::unit_t_traits::underlying_type, linear_scale> - (std::pow(value(), power)); + (gcem::pow(value(), power)); } /** diff --git a/wpimath/src/main/native/include/units/math.h b/wpimath/src/main/native/include/units/math.h index 995335bbb59..727aee62fb5 100644 --- a/wpimath/src/main/native/include/units/math.h +++ b/wpimath/src/main/native/include/units/math.h @@ -28,6 +28,8 @@ #include +#include + #include "units/angle.h" #include "units/base.h" #include "units/dimensionless.h" @@ -58,12 +60,12 @@ namespace units::math { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t cos(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t cos(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::cos(angle.template convert()())); + gcem::cos(angle.template convert()())); } #endif @@ -78,12 +80,12 @@ dimensionless::scalar_t cos(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t sin(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t sin(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::sin(angle.template convert()())); + gcem::sin(angle.template convert()())); } #endif /** @@ -97,12 +99,12 @@ dimensionless::scalar_t sin(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t tan(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t tan(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::tan(angle.template convert()())); + gcem::tan(angle.template convert()())); } #endif @@ -116,11 +118,11 @@ dimensionless::scalar_t tan(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t acos(const ScalarUnit x) noexcept { +constexpr angle::radian_t acos(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::acos(x())); + return angle::radian_t(gcem::acos(x())); } #endif @@ -134,11 +136,11 @@ angle::radian_t acos(const ScalarUnit x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t asin(const ScalarUnit x) noexcept { +constexpr angle::radian_t asin(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::asin(x())); + return angle::radian_t(gcem::asin(x())); } #endif @@ -156,11 +158,11 @@ angle::radian_t asin(const ScalarUnit x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t atan(const ScalarUnit x) noexcept { +constexpr angle::radian_t atan(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::atan(x())); + return angle::radian_t(gcem::atan(x())); } #endif @@ -176,15 +178,15 @@ angle::radian_t atan(const ScalarUnit x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t atan2(const Y y, const X x) noexcept { +constexpr angle::radian_t atan2(const Y y, const X x) noexcept { static_assert(traits::is_dimensionless_unit::value, "The quantity y/x must yield a dimensionless ratio."); // X and Y could be different length units, so normalize them return angle::radian_t( - std::atan2(y.template convert< - typename units::traits::unit_t_traits::unit_type>()(), - x())); + gcem::atan2(y.template convert< + typename units::traits::unit_t_traits::unit_type>()(), + x())); } #endif @@ -203,12 +205,12 @@ angle::radian_t atan2(const Y y, const X x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t cosh(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t cosh(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::cosh(angle.template convert()())); + gcem::cosh(angle.template convert()())); } #endif @@ -223,12 +225,12 @@ dimensionless::scalar_t cosh(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t sinh(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t sinh(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::sinh(angle.template convert()())); + gcem::sinh(angle.template convert()())); } #endif @@ -243,12 +245,12 @@ dimensionless::scalar_t sinh(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -dimensionless::scalar_t tanh(const AngleUnit angle) noexcept { +constexpr dimensionless::scalar_t tanh(const AngleUnit angle) noexcept { static_assert( traits::is_angle_unit::value, "Type `AngleUnit` must be a unit of angle derived from `unit_t`."); return dimensionless::scalar_t( - std::tanh(angle.template convert()())); + gcem::tanh(angle.template convert()())); } #endif @@ -264,11 +266,11 @@ dimensionless::scalar_t tanh(const AngleUnit angle) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t acosh(const ScalarUnit x) noexcept { +constexpr angle::radian_t acosh(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::acosh(x())); + return angle::radian_t(gcem::acosh(x())); } #endif @@ -281,11 +283,11 @@ angle::radian_t acosh(const ScalarUnit x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t asinh(const ScalarUnit x) noexcept { +constexpr angle::radian_t asinh(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::asinh(x())); + return angle::radian_t(gcem::asinh(x())); } #endif @@ -300,11 +302,11 @@ angle::radian_t asinh(const ScalarUnit x) noexcept { */ #if !defined(DISABLE_PREDEFINED_UNITS) || defined(ENABLE_PREDEFINED_ANGLE_UNITS) template -angle::radian_t atanh(const ScalarUnit x) noexcept { +constexpr angle::radian_t atanh(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return angle::radian_t(std::atanh(x())); + return angle::radian_t(gcem::atanh(x())); } #endif @@ -329,11 +331,11 @@ angle::radian_t atanh(const ScalarUnit x) noexcept { * error occurs. */ template -dimensionless::scalar_t exp(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t exp(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::exp(x())); + return dimensionless::scalar_t(gcem::exp(x())); } /** @@ -346,11 +348,11 @@ dimensionless::scalar_t exp(const ScalarUnit x) noexcept { * @returns Natural logarithm of x. */ template -dimensionless::scalar_t log(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t log(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::log(x())); + return dimensionless::scalar_t(gcem::log(x())); } /** @@ -362,11 +364,11 @@ dimensionless::scalar_t log(const ScalarUnit x) noexcept { * @returns Common logarithm of x. */ template -dimensionless::scalar_t log10(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t log10(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::log10(x())); + return dimensionless::scalar_t(gcem::log10(x())); } /** @@ -417,11 +419,11 @@ dimensionless::scalar_t exp2(const ScalarUnit x) noexcept { * @returns e raised to the power of x, minus one. */ template -dimensionless::scalar_t expm1(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t expm1(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::expm1(x())); + return dimensionless::scalar_t(gcem::expm1(x())); } /** @@ -434,11 +436,11 @@ dimensionless::scalar_t expm1(const ScalarUnit x) noexcept { * @returns The natural logarithm of (1+x). */ template -dimensionless::scalar_t log1p(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t log1p(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::log1p(x())); + return dimensionless::scalar_t(gcem::log1p(x())); } /** @@ -450,11 +452,11 @@ dimensionless::scalar_t log1p(const ScalarUnit x) noexcept { * @returns The binary logarithm of x: log2x. */ template -dimensionless::scalar_t log2(const ScalarUnit x) noexcept { +constexpr dimensionless::scalar_t log2(const ScalarUnit x) noexcept { static_assert( traits::is_dimensionless_unit::value, "Type `ScalarUnit` must be a dimensionless unit derived from `unit_t`."); - return dimensionless::scalar_t(std::log2(x())); + return dimensionless::scalar_t(gcem::log2(x())); } //---------------------------------- @@ -480,14 +482,14 @@ dimensionless::scalar_t log2(const ScalarUnit x) noexcept { template < class UnitType, std::enable_if_t::value, int> = 0> -inline auto sqrt(const UnitType& value) noexcept -> unit_t< +inline constexpr auto sqrt(const UnitType& value) noexcept -> unit_t< square_root::unit_type>, typename units::traits::unit_t_traits::underlying_type, linear_scale> { return unit_t< square_root::unit_type>, typename units::traits::unit_t_traits::underlying_type, - linear_scale>(std::sqrt(value())); + linear_scale>(gcem::sqrt(value())); } /** @@ -502,10 +504,10 @@ template ::value, int> = 0> -inline UnitTypeLhs hypot(const UnitTypeLhs& x, const UnitTypeRhs& y) { +inline constexpr UnitTypeLhs hypot(const UnitTypeLhs& x, const UnitTypeRhs& y) { static_assert(traits::is_convertible_unit_t::value, "Parameters of hypot() function are not compatible units."); - return UnitTypeLhs(std::hypot( + return UnitTypeLhs(gcem::hypot( x(), y.template convert< typename units::traits::unit_t_traits::unit_type>()())); @@ -525,8 +527,8 @@ inline UnitTypeLhs hypot(const UnitTypeLhs& x, const UnitTypeRhs& y) { */ template ::value>> -UnitType ceil(const UnitType x) noexcept { - return UnitType(std::ceil(x())); +constexpr UnitType ceil(const UnitType x) noexcept { + return UnitType(gcem::ceil(x())); } /** @@ -539,8 +541,8 @@ UnitType ceil(const UnitType x) noexcept { */ template ::value>> -UnitType floor(const UnitType x) noexcept { - return UnitType(std::floor(x())); +constexpr UnitType floor(const UnitType x) noexcept { + return UnitType(gcem::floor(x())); } /** @@ -555,10 +557,11 @@ UnitType floor(const UnitType x) noexcept { template ::value && traits::is_unit_t::value>> -UnitTypeLhs fmod(const UnitTypeLhs numer, const UnitTypeRhs denom) noexcept { +constexpr UnitTypeLhs fmod(const UnitTypeLhs numer, + const UnitTypeRhs denom) noexcept { static_assert(traits::is_convertible_unit_t::value, "Parameters of fmod() function are not compatible units."); - return UnitTypeLhs(std::fmod( + return UnitTypeLhs(gcem::fmod( numer(), denom.template convert< typename units::traits::unit_t_traits::unit_type>()())); @@ -574,8 +577,8 @@ UnitTypeLhs fmod(const UnitTypeLhs numer, const UnitTypeRhs denom) noexcept { */ template ::value>> -UnitType trunc(const UnitType x) noexcept { - return UnitType(std::trunc(x())); +constexpr UnitType trunc(const UnitType x) noexcept { + return UnitType(gcem::trunc(x())); } /** @@ -588,8 +591,8 @@ UnitType trunc(const UnitType x) noexcept { */ template ::value>> -UnitType round(const UnitType x) noexcept { - return UnitType(std::round(x())); +constexpr UnitType round(const UnitType x) noexcept { + return UnitType(gcem::round(x())); } //---------------------------------- @@ -608,17 +611,18 @@ UnitType round(const UnitType x) noexcept { template ::value && traits::is_unit_t::value>> -UnitTypeLhs copysign(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { - return UnitTypeLhs(std::copysign( +constexpr UnitTypeLhs copysign(const UnitTypeLhs x, + const UnitTypeRhs y) noexcept { + return UnitTypeLhs(gcem::copysign( x(), y())); // no need for conversion to get the correct sign. } /// Overload to copy the sign from a raw double template ::value>> -UnitTypeLhs copysign(const UnitTypeLhs x, - const UNIT_LIB_DEFAULT_TYPE y) noexcept { - return UnitTypeLhs(std::copysign(x(), y)); +constexpr UnitTypeLhs copysign(const UnitTypeLhs x, + const UNIT_LIB_DEFAULT_TYPE y) noexcept { + return UnitTypeLhs(gcem::copysign(x(), y)); } //---------------------------------- @@ -660,10 +664,10 @@ UnitTypeLhs fdim(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { template ::value && traits::is_unit_t::value>> -UnitTypeLhs fmax(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { +constexpr UnitTypeLhs fmax(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { static_assert(traits::is_convertible_unit_t::value, "Parameters of fmax() function are not compatible units."); - return UnitTypeLhs(std::fmax( + return UnitTypeLhs(gcem::max( x(), y.template convert< typename units::traits::unit_t_traits::unit_type>()())); @@ -683,10 +687,10 @@ UnitTypeLhs fmax(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { template ::value && traits::is_unit_t::value>> -UnitTypeLhs fmin(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { +constexpr UnitTypeLhs fmin(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { static_assert(traits::is_convertible_unit_t::value, "Parameters of fmin() function are not compatible units."); - return UnitTypeLhs(std::fmin( + return UnitTypeLhs(gcem::min( x(), y.template convert< typename units::traits::unit_t_traits::unit_type>()())); @@ -705,8 +709,8 @@ UnitTypeLhs fmin(const UnitTypeLhs x, const UnitTypeRhs y) noexcept { */ template ::value>> -UnitType fabs(const UnitType x) noexcept { - return UnitType(std::fabs(x())); +constexpr UnitType fabs(const UnitType x) noexcept { + return UnitType(gcem::abs(x())); } /** @@ -718,8 +722,8 @@ UnitType fabs(const UnitType x) noexcept { */ template ::value>> -UnitType abs(const UnitType x) noexcept { - return UnitType(std::fabs(x())); +constexpr UnitType abs(const UnitType x) noexcept { + return UnitType(gcem::abs(x())); } /**