Add noexcept specifier to fixed point operations

This commit is contained in:
Myles Busig 2024-08-03 16:18:20 -06:00
parent 82d6d64829
commit 0e0884cce9
2 changed files with 19 additions and 19 deletions

View File

@ -17,12 +17,12 @@ namespace mtl {
* Valid values are in the range ~[-33'554'431.01, 33'554'432.98] * Valid values are in the range ~[-33'554'431.01, 33'554'432.98]
* *
* Has a maximum error of +/- 1/128 (~0.0078), integers are always * Has a maximum error of +/- 1/128 (~0.0078), integers are always
* exactly. * exactly represented.
* *
* \par ARM * \par ARM
* *
* All functions are compiled in ARM mode because some operators (notably * All functions are compiled in ARM-mode because some operators (notably
* multiplication and division) use ARM-only instructions. For optimal * multiplication and division) are much faster in ARM-mode. For optimal
* performance, fixed point numbers should only be used in ARM-mode * performance, fixed point numbers should only be used in ARM-mode
* code to enable as much inlining as possible. * code to enable as much inlining as possible.
*/ */
@ -44,10 +44,10 @@ private:
* DO NOT use to set the fixed number to an integer value, use * DO NOT use to set the fixed number to an integer value, use
* the public constructor instead. * the public constructor instead.
*/ */
constexpr fixed(int32_t _x, bool) : x(_x) {} constexpr fixed(int32_t _x, bool) noexcept : x(_x) {}
public: public:
constexpr fixed() : x(0) {} constexpr fixed() noexcept : x(0) {}
/** /**
* \brief Integer constructor * \brief Integer constructor
* *
@ -56,7 +56,7 @@ public:
* the class description for more detail. * the class description for more detail.
*/ */
template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true> template <typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
constexpr fixed(T _i) : x(_i * 64) {} constexpr fixed(T _i) noexcept : x(_i * 64) {}
/** /**
* \brief Floating point constructor * \brief Floating point constructor
* *
@ -69,7 +69,7 @@ public:
* float. * float.
*/ */
template <typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true> template <typename T, std::enable_if_t<std::is_floating_point_v<T>, bool> = true>
constexpr fixed(T _f) constexpr fixed(T _f) noexcept
// 0.5 offset accounts for truncating to integer, round instead // 0.5 offset accounts for truncating to integer, round instead
: x((_f * 64) + 0.5f) {} : x((_f * 64) + 0.5f) {}
@ -82,7 +82,7 @@ public:
* *
* Should not be used unless absolutely needed. * Should not be used unless absolutely needed.
*/ */
static constexpr fixed from_raw(int32_t x) { static constexpr fixed from_raw(int32_t x) noexcept {
return fixed(x, true); return fixed(x, true);
} }
@ -92,7 +92,7 @@ public:
* Gets the raw value of the fixed point number. i.e. The fixed point * Gets the raw value of the fixed point number. i.e. The fixed point
* number multiplied by 64. * number multiplied by 64.
*/ */
constexpr int32_t raw() const { constexpr int32_t raw() const noexcept {
return x; return x;
} }
@ -102,34 +102,34 @@ public:
* Addition with fixed point numbers is the same as with a 32-bit * Addition with fixed point numbers is the same as with a 32-bit
* integer, so should be extremely quick. * integer, so should be extremely quick.
*/ */
constexpr fixed operator+(fixed rhs) const { constexpr fixed operator+(fixed rhs) const noexcept {
return from_raw(x + rhs.x); return from_raw(x + rhs.x);
} }
constexpr fixed& operator+=(fixed rhs) { constexpr fixed& operator+=(fixed rhs) noexcept {
x += rhs.x; x += rhs.x;
return *this; return *this;
} }
/** /**
* \brief Fixed point subtraction * \brief Fixed point subtraction
*/ */
constexpr fixed operator-(fixed rhs) const { constexpr fixed operator-(fixed rhs) const noexcept {
return from_raw(x - rhs.x); return from_raw(x - rhs.x);
} }
constexpr fixed& operator-=(fixed rhs) { constexpr fixed& operator-=(fixed rhs) noexcept {
x -= rhs.x; x -= rhs.x;
return *this; return *this;
} }
constexpr fixed operator-() const { constexpr fixed operator-() const noexcept {
return from_raw(-x); return from_raw(-x);
} }
/** /**
* \brief Fixed point multiplication * \brief Fixed point multiplication
*/ */
constexpr fixed operator*(fixed rhs) const { constexpr fixed operator*(fixed rhs) const noexcept {
return from_raw(((int64_t)x * rhs.x) >> 6); return from_raw(((int64_t)x * rhs.x) >> 6);
} }
constexpr fixed& operator*=(fixed rhs) { constexpr fixed& operator*=(fixed rhs) noexcept {
*this = *this * rhs; *this = *this * rhs;
return *this; return *this;
} }
@ -149,8 +149,8 @@ public:
* *
* Placed in IWRAM * Placed in IWRAM
*/ */
GBA_IWRAM fixed operator/(fixed rhs) const; GBA_IWRAM fixed operator/(fixed rhs) const noexcept;
fixed& operator/=(fixed rhs) { fixed& operator/=(fixed rhs) noexcept {
*this = *this / rhs; *this = *this / rhs;
return *this; return *this;
} }

View File

@ -6,7 +6,7 @@ TARGET_ARM_MODE
namespace mtl { namespace mtl {
fixed fixed::operator/(fixed rhs) const { fixed fixed::operator/(fixed rhs) const noexcept {
int32_t raw_result; int32_t raw_result;
asm( asm(
// This division implementation has two methods it can use. // This division implementation has two methods it can use.