Skip to content

Commit

Permalink
[wpimath] Make gcem call std functions if not constant-evaluated (#5983)
Browse files Browse the repository at this point in the history
The one exception is macOS, which doesn't support std::beta().
  • Loading branch information
calcmogul authored Dec 1, 2023
1 parent 3081611 commit 74b85b7
Show file tree
Hide file tree
Showing 39 changed files with 1,256 additions and 15 deletions.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion upstream_utils/update_gcem.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def main():

# Apply patches to upstream Git repo
os.chdir(upstream_root)
for f in []:
for f in ["0001-Call-std-functions-if-not-constant-evaluated.patch"]:
git_am(os.path.join(wpilib_root, "upstream_utils/gcem_patches", f))

# Delete old install
Expand Down
20 changes: 6 additions & 14 deletions wpimath/src/main/native/include/frc/geometry/Rotation2d.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,31 @@

#pragma once

#include <type_traits>
#include <gcem.hpp>

#include "frc/geometry/Rotation2d.h"
#include "gcem.hpp"
#include "units/angle.h"

namespace frc {

constexpr Rotation2d::Rotation2d(units::radian_t value)
: m_value(value),
m_cos(std::is_constant_evaluated() ? gcem::cos(value.to<double>())
: std::cos(value.to<double>())),
m_sin(std::is_constant_evaluated() ? gcem::sin(value.to<double>())
: std::sin(value.to<double>())) {}
m_cos(gcem::cos(value.to<double>())),
m_sin(gcem::sin(value.to<double>())) {}

constexpr Rotation2d::Rotation2d(units::degree_t value)
: Rotation2d(units::radian_t{value}) {}

constexpr Rotation2d::Rotation2d(double x, double y) {
double magnitude =
std::is_constant_evaluated() ? gcem::hypot(x, y) : std::hypot(x, y);
double magnitude = gcem::hypot(x, y);
if (magnitude > 1e-6) {
m_sin = y / magnitude;
m_cos = x / magnitude;
} else {
m_sin = 0.0;
m_cos = 1.0;
}
m_value =
units::radian_t{std::is_constant_evaluated() ? gcem::atan2(m_sin, m_cos)
: std::atan2(m_sin, m_cos)};
m_value = units::radian_t{gcem::atan2(m_sin, m_cos)};
}

constexpr Rotation2d Rotation2d::operator-() const {
Expand All @@ -58,9 +52,7 @@ constexpr Rotation2d Rotation2d::operator/(double scalar) const {
}

constexpr bool Rotation2d::operator==(const Rotation2d& other) const {
return (std::is_constant_evaluated()
? gcem::hypot(Cos() - other.Cos(), Sin() - other.Sin())
: std::hypot(Cos() - other.Cos(), Sin() - other.Sin())) < 1E-9;
return gcem::hypot(Cos() - other.Cos(), Sin() - other.Sin()) < 1E-9;
}

constexpr Rotation2d Rotation2d::RotateBy(const Rotation2d& other) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#ifndef _gcem_abs_HPP
#define _gcem_abs_HPP

#include <cmath>
#include <type_traits>

/**
* Compile-time absolute value function
*
Expand All @@ -34,12 +37,16 @@ T
abs(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return( // deal with signed-zeros
x == T(0) ? \
T(0) :
// else
x < T(0) ? \
- x : x );
} else {
return std::abs(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_acos_HPP
#define _gcem_acos_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -78,7 +81,11 @@ return_t<T>
acos(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::acos_check( static_cast<return_t<T>>(x) );
} else {
return std::acos(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_acosh_HPP
#define _gcem_acosh_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -62,7 +65,11 @@ return_t<T>
acosh(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::acosh_compute( static_cast<return_t<T>>(x) );
} else {
return std::acosh(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_asin_HPP
#define _gcem_asin_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -76,7 +79,11 @@ return_t<T>
asin(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::asin_check( static_cast<return_t<T>>(x) );
} else {
return std::asin(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_asinh_HPP
#define _gcem_asinh_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -59,7 +62,11 @@ return_t<T>
asinh(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::asinh_compute( static_cast<return_t<T>>(x) );
} else {
return std::asinh(x);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
#ifndef _gcem_atan_HPP
#define _gcem_atan_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -149,7 +152,11 @@ return_t<T>
atan(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::atan_check( static_cast<return_t<T>>(x) );
} else {
return std::atan(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_atan2_HPP
#define _gcem_atan2_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -82,7 +85,11 @@ common_return_t<T1,T2>
atan2(const T1 y, const T2 x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::atan2_type_check(x,y);
} else {
return std::atan2(y, x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_atanh_HPP
#define _gcem_atanh_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -73,7 +76,11 @@ return_t<T>
atanh(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::atanh_check( static_cast<return_t<T>>(x) );
} else {
return std::atanh(x);
}
}

#endif
11 changes: 11 additions & 0 deletions wpimath/src/main/native/thirdparty/gcem/include/gcem_incl/beta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#ifndef _gcem_beta_HPP
#define _gcem_beta_HPP

#include <cmath>
#include <type_traits>

/**
* Compile-time beta function
*
Expand All @@ -36,7 +39,15 @@ common_return_t<T1,T2>
beta(const T1 a, const T2 b)
noexcept
{
if (std::is_constant_evaluated()) {
return exp( lbeta(a,b) );
} else {
#ifdef __cpp_lib_math_special_functions
return std::beta(a, b);
#else
return exp( lbeta(a,b) );
#endif
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#ifndef _gcem_ceil_HPP
#define _gcem_ceil_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -124,7 +127,11 @@ return_t<T>
ceil(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::ceil_check( static_cast<return_t<T>>(x) );
} else {
return std::ceil(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#ifndef _gcem_copysign_HPP
#define _gcem_copysign_HPP

#include <cmath>
#include <type_traits>

/**
* Compile-time copy sign function
*
Expand All @@ -35,7 +38,11 @@ T1
copysign(const T1 x, const T2 y)
noexcept
{
if (std::is_constant_evaluated()) {
return( signbit(x) != signbit(y) ? -x : x );
} else {
return std::copysign(x, y);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_cos_HPP
#define _gcem_cos_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -77,7 +80,11 @@ return_t<T>
cos(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::cos_check( static_cast<return_t<T>>(x) );
} else {
return std::cos(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_cosh_HPP
#define _gcem_cosh_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -59,7 +62,11 @@ return_t<T>
cosh(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::cosh_compute( static_cast<return_t<T>>(x) );
} else {
return std::cosh(x);
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#ifndef _gcem_erf_HPP
#define _gcem_erf_HPP

#include <cmath>
#include <type_traits>

namespace internal
{

Expand Down Expand Up @@ -137,7 +140,11 @@ return_t<T>
erf(const T x)
noexcept
{
if (std::is_constant_evaluated()) {
return internal::erf_check( static_cast<return_t<T>>(x) );
} else {
return std::erf(x);
}
}

#endif
Loading

0 comments on commit 74b85b7

Please sign in to comment.