Skip to content

Commit 5fce911

Browse files
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
1 parent 93fa455 commit 5fce911

File tree

1 file changed

+90
-20
lines changed

1 file changed

+90
-20
lines changed

cpp/arduino/AvrMath.h

+90-20
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,96 @@
11
#pragma once
22
#include <math.h>
3+
#include "ArduinoDefines.h"
34

4-
#define constrain(x,l,h) ((x)<(l)?(l):((x)>(h)?(h):(x)))
5-
#define map(x,inMin,inMax,outMin,outMax) (((x)-(inMin))*((outMax)-(outMin))/((inMax)-(inMin))+outMin)
6-
7-
#define sq(x) ((x)*(x))
8-
9-
#define radians(deg) ((deg)*DEG_TO_RAD)
10-
#define degrees(rad) ((rad)*RAD_TO_DEG)
11-
12-
#ifdef abs
13-
#undef abs
5+
#ifdef __cplusplus
6+
template<class Amt, class Low, class High>
7+
auto constrain(const Amt& amt, const Low& low, const High& high) -> decltype(amt < low ? low : (amt > high ? high : amt ))
8+
{
9+
return (amt < low ? low : (amt > high ? high : amt ));
10+
}
11+
template<class X, class InMin, class InMax, class OutMin, class OutMax>
12+
auto map(const X& x, const InMin& inMin, const InMax& inMax, const OutMin& outMin, const OutMax& outMax)
13+
-> decltype((x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin)
14+
{
15+
return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
16+
}
17+
template<class T>
18+
auto radians(const T& deg) -> decltype(deg * DEG_TO_RAD)
19+
{
20+
return deg * DEG_TO_RAD;
21+
}
22+
template<class T>
23+
auto degrees(const T& rad) -> decltype(rad * RAD_TO_DEG)
24+
{
25+
return rad * RAD_TO_DEG;
26+
}
27+
template<class T>
28+
auto sq(const T& x) -> decltype(x * x)
29+
{
30+
return x * x;
31+
}
32+
template<class T>
33+
auto abs(const T& x) -> decltype(x > 0 ? x : -x)
34+
{
35+
return x > 0 ? x : -x;
36+
}
37+
template<class T, class L>
38+
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
39+
{
40+
return (b < a) ? b : a;
41+
}
42+
template<class T, class L>
43+
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
44+
{
45+
return (a < b) ? b : a;
46+
}
47+
#else
48+
#ifndef constrain
49+
#define constrain(amt,low,high) \
50+
({ __typeof__ (amt) _amt = (amt); \
51+
__typeof__ (low) _low = (low); \
52+
__typeof__ (high) _high = (high); \
53+
(amt < low ? low : (amt > high ? high : amt )); })
1454
#endif
15-
#define abs(x) ((x)>0?(x):-(x))
16-
17-
#ifdef max
18-
#undef max
55+
#ifndef map
56+
#define map(x,inMin,inMax,outMin,outMax) \
57+
({ __typeof__ (x) _x = (x); \
58+
__typeof__ (inMin) _inMin = (inMin); \
59+
__typeof__ (inMax) _inMax = (inMax); \
60+
__typeof__ (outMin) _outMin = (outMin); \
61+
__typeof__ (outMax) _outMax = (outMax); \
62+
(_x - _inMin) * (_outMax - _outMin) / (_inMax - _inMin) + _outMin; })
63+
#endif
64+
#ifndef radians
65+
#define radians(deg) \
66+
({ __typeof__ (deg) _deg = (deg); \
67+
_deg * DEG_TO_RAD; })
68+
#endif
69+
#ifndef degrees
70+
#define degrees(rad) \
71+
({ __typeof__ (rad) _rad = (rad); \
72+
_rad * RAD_TO_DEG; })
73+
#endif
74+
#ifndef sq
75+
#define sq(x) \
76+
({ __typeof__ (x) _x = (x); \
77+
_x * _x; })
78+
#endif
79+
#ifndef abs
80+
#define abs(x) \
81+
({ __typeof__ (x) _x = (x); \
82+
_x > 0 ? _x : -_x; })
83+
#endif
84+
#ifndef min
85+
#define min(a,b) \
86+
({ __typeof__ (a) _a = (a); \
87+
__typeof__ (b) _b = (b); \
88+
_a < _b ? _a : _b; })
89+
#endif
90+
#ifndef max
91+
#define max(a,b) \
92+
({ __typeof__ (a) _a = (a); \
93+
__typeof__ (b) _b = (b); \
94+
_a > _b ? _a : _b; })
1995
#endif
20-
#define max(a,b) ((a)>(b)?(a):(b))
21-
22-
#ifdef min
23-
#undef min
2496
#endif
25-
#define min(a,b) ((a)<(b)?(a):(b))
26-

0 commit comments

Comments
 (0)