forked from Arduino-CI/arduino_ci
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Prevent name clashes with math macros
This replaces the macros in AvrMath.h with template functions when included from C++. This prevents name clashes with e.g. the `std::min` function or similar methods or namespace-local functions. For C, this still uses a macro (lacking templates), but an improved version that prevents double evaluation of arguments. This code is based on the ArduinoCore-API repository, which is in the process of become the single source of all non-architecture-specific Arduino API code: https://github.com/arduino/ArduinoCore-API/blob/master/api/Common.h There, only `min` and `max` have been replaced by template functions, but others will probably follow as well: arduino/ArduinoCore-API#85
- Loading branch information
1 parent
93fa455
commit 5fce911
Showing
1 changed file
with
90 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,96 @@ | ||
#pragma once | ||
#include <math.h> | ||
#include "ArduinoDefines.h" | ||
|
||
#define constrain(x,l,h) ((x)<(l)?(l):((x)>(h)?(h):(x))) | ||
#define map(x,inMin,inMax,outMin,outMax) (((x)-(inMin))*((outMax)-(outMin))/((inMax)-(inMin))+outMin) | ||
|
||
#define sq(x) ((x)*(x)) | ||
|
||
#define radians(deg) ((deg)*DEG_TO_RAD) | ||
#define degrees(rad) ((rad)*RAD_TO_DEG) | ||
|
||
#ifdef abs | ||
#undef abs | ||
#ifdef __cplusplus | ||
template<class Amt, class Low, class High> | ||
auto constrain(const Amt& amt, const Low& low, const High& high) -> decltype(amt < low ? low : (amt > high ? high : amt )) | ||
{ | ||
return (amt < low ? low : (amt > high ? high : amt )); | ||
} | ||
template<class X, class InMin, class InMax, class OutMin, class OutMax> | ||
auto map(const X& x, const InMin& inMin, const InMax& inMax, const OutMin& outMin, const OutMax& outMax) | ||
-> decltype((x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin) | ||
{ | ||
return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; | ||
} | ||
template<class T> | ||
auto radians(const T& deg) -> decltype(deg * DEG_TO_RAD) | ||
{ | ||
return deg * DEG_TO_RAD; | ||
} | ||
template<class T> | ||
auto degrees(const T& rad) -> decltype(rad * RAD_TO_DEG) | ||
{ | ||
return rad * RAD_TO_DEG; | ||
} | ||
template<class T> | ||
auto sq(const T& x) -> decltype(x * x) | ||
{ | ||
return x * x; | ||
} | ||
template<class T> | ||
auto abs(const T& x) -> decltype(x > 0 ? x : -x) | ||
{ | ||
return x > 0 ? x : -x; | ||
} | ||
template<class T, class L> | ||
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) | ||
{ | ||
return (b < a) ? b : a; | ||
} | ||
template<class T, class L> | ||
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) | ||
{ | ||
return (a < b) ? b : a; | ||
} | ||
#else | ||
#ifndef constrain | ||
#define constrain(amt,low,high) \ | ||
({ __typeof__ (amt) _amt = (amt); \ | ||
__typeof__ (low) _low = (low); \ | ||
__typeof__ (high) _high = (high); \ | ||
(amt < low ? low : (amt > high ? high : amt )); }) | ||
#endif | ||
#define abs(x) ((x)>0?(x):-(x)) | ||
|
||
#ifdef max | ||
#undef max | ||
#ifndef map | ||
#define map(x,inMin,inMax,outMin,outMax) \ | ||
({ __typeof__ (x) _x = (x); \ | ||
__typeof__ (inMin) _inMin = (inMin); \ | ||
__typeof__ (inMax) _inMax = (inMax); \ | ||
__typeof__ (outMin) _outMin = (outMin); \ | ||
__typeof__ (outMax) _outMax = (outMax); \ | ||
(_x - _inMin) * (_outMax - _outMin) / (_inMax - _inMin) + _outMin; }) | ||
#endif | ||
#ifndef radians | ||
#define radians(deg) \ | ||
({ __typeof__ (deg) _deg = (deg); \ | ||
_deg * DEG_TO_RAD; }) | ||
#endif | ||
#ifndef degrees | ||
#define degrees(rad) \ | ||
({ __typeof__ (rad) _rad = (rad); \ | ||
_rad * RAD_TO_DEG; }) | ||
#endif | ||
#ifndef sq | ||
#define sq(x) \ | ||
({ __typeof__ (x) _x = (x); \ | ||
_x * _x; }) | ||
#endif | ||
#ifndef abs | ||
#define abs(x) \ | ||
({ __typeof__ (x) _x = (x); \ | ||
_x > 0 ? _x : -_x; }) | ||
#endif | ||
#ifndef min | ||
#define min(a,b) \ | ||
({ __typeof__ (a) _a = (a); \ | ||
__typeof__ (b) _b = (b); \ | ||
_a < _b ? _a : _b; }) | ||
#endif | ||
#ifndef max | ||
#define max(a,b) \ | ||
({ __typeof__ (a) _a = (a); \ | ||
__typeof__ (b) _b = (b); \ | ||
_a > _b ? _a : _b; }) | ||
#endif | ||
#define max(a,b) ((a)>(b)?(a):(b)) | ||
|
||
#ifdef min | ||
#undef min | ||
#endif | ||
#define min(a,b) ((a)<(b)?(a):(b)) | ||
|