33
44#include " Arduino.h"
55
6- // sign function
7- #define _sign (a ) ( ( (a) < 0 ) ? -1 : ( (a) > 0 ) )
6+ template <typename T>
7+ constexpr inline int _sign (T val) {
8+ return __builtin_signbit (val);
9+ }
10+
11+ #ifndef __AVR__
12+ #include < type_traits>
13+
814#ifndef _round
9- #define _round (x ) ((x)>=0?(long)((x)+0.5f):(long)((x)-0.5f))
15+ // Use enable_if to select the roundf function for single precision floats.
16+ // This improves performance when -ffast-math is not set.
17+ template <typename T>
18+ constexpr inline typename std::enable_if<std::is_same<T, float >::value, long >::type _round (T x) {
19+ return __builtin_roundf (x);
20+ }
21+ template <typename T>
22+ constexpr inline typename std::enable_if<std::is_same<T, double >::value, long >::type _round (T x) {
23+ return __builtin_round (x);
24+ }
25+ #endif
26+
27+ // Use enable_if to select the fastest implementation according to the amt type.
28+ // Using __builtin_fXf is measurably faster than using the ternary approach.
29+ template <typename T, typename L, typename H>
30+ constexpr inline typename std::enable_if<std::is_integral<T>::value, T>::type _constrain (T amt, L low, H high) {
31+ return (amt < low) ? low : (amt > high) ? high : amt;
32+ }
33+ template <typename T, typename L, typename H>
34+ constexpr inline typename std::enable_if<std::is_same<T, float >::value, T>::type _constrain (T amt, L low, H high) {
35+ return __builtin_fmaxf (low, __builtin_fminf (high, amt));
36+ }
37+ template <typename T, typename L, typename H>
38+ constexpr inline typename std::enable_if<std::is_same<T, double >::value, T>::type _constrain (T amt, L low, H high) {
39+ return __builtin_fmax (low, __builtin_fmin (high, amt));
40+ }
41+ #else // __AVR__
42+ // AVR compiler lacks type_traits, so we are forced to use the slower non-type inferenced
43+ // version. That's okay, right? If you wanted to go fast you would not be on AVR.
44+ template <typename T>
45+ constexpr long _round (T x) {
46+ return __builtin_round (x);
47+ }
48+ template <typename T, typename L, typename H>
49+ constexpr T _constrain (T amt, L low, H high) {
50+ return (amt < low) ? low : (amt > high) ? high : amt;
51+ }
1052#endif
11- #define _constrain ( amt , low , high ) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
53+
1254#define _sqrt (a ) (_sqrtApprox(a))
1355#define _isset (a ) ( (a) != (NOT_SET ) )
1456#define _UNUSED (v ) (void ) (v)
@@ -121,4 +163,4 @@ float _electricalAngle(float shaft_angle, int pole_pairs);
121163 */
122164float _sqrtApprox (float value);
123165
124- #endif
166+ #endif
0 commit comments