Skip to content

Commit 4ae6b26

Browse files
committed
Converted the series of function-like macros in Arduino.h into constexpr functions in the case of C++. Required in order to avoid conflicts to C++ stdlib.
Incorporates some of the changes from arduino/ArduinoCore-API#140 and arduino/ArduinoCore-API@30e4397 Co-Authored-By: Keating Reid <[email protected]> Co-Authored-By: Martino Facchin <[email protected]>
1 parent 5897ecd commit 4ae6b26

File tree

1 file changed

+108
-6
lines changed

1 file changed

+108
-6
lines changed

Diff for: cores/arduino/Arduino.h

+108-6
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,118 @@ void yield(void);
9393
}; // extern "C"
9494
#endif
9595

96-
#define min(a,b) ((a)<(b)?(a):(b))
97-
#define max(a,b) ((a)>(b)?(a):(b))
96+
#if defined(__cplusplus)
97+
template<typename T, typename L> constexpr auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
98+
{
99+
return (b < a) ? b : a;
100+
}
101+
102+
template<typename T, typename L> constexpr auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
103+
{
104+
return (a < b) ? b : a;
105+
}
106+
107+
template <typename T> constexpr auto abs(const T x) -> decltype(x>0?x:-x){
108+
return x>0?x:-x;
109+
}
110+
111+
template<typename T, typename U, typename V> constexpr auto constrain(const T& amt, const U& low, const V& high) -> decltype(amt < low ? low : (amt > high ? high : amt)) {
112+
return amt < low ? low : (amt > high ? high : amt);
113+
}
114+
115+
template <typename T> constexpr T round(const T x){
116+
return x>=0?static_cast<long>(x+0.5):static_cast<long>(x-0.5);
117+
}
118+
119+
template<typename T> constexpr auto radians(const T& deg) -> decltype(deg * DEG_TO_RAD){
120+
return deg * DEG_TO_RAD;
121+
}
122+
123+
template<typename T> constexpr auto degrees(const T& rad) -> decltype(rad * RAD_TO_DEG){
124+
return rad * RAD_TO_DEG;
125+
}
126+
127+
template<typename T> constexpr auto sq(const T& x) -> decltype(x*x){
128+
return x*x;
129+
}
130+
#else
131+
#ifndef min
132+
#define min(a,b) \
133+
({ __typeof__ (a) _a = (a); \
134+
__typeof__ (b) _b = (b); \
135+
_a < _b ? _a : _b; })
136+
#endif
137+
138+
#ifndef max
139+
#define max(a,b) \
140+
({ __typeof__ (a) _a = (a); \
141+
__typeof__ (b) _b = (b); \
142+
_a > _b ? _a : _b; })
143+
#endif
144+
98145
#define abs(x) ((x)>0?(x):-(x))
99-
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
146+
147+
#ifndef constrain
148+
#define constrain(amt,low,high) \
149+
({ __typeof__ (amt) _amt = (amt); \
150+
__typeof__ (low) _low = (low); \
151+
__typeof__ (high) _high = (high); \
152+
_amt < _low ? _low : (_amt > _high ? _high :_amt); })
153+
#endif
154+
100155
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
101-
#define radians(deg) ((deg)*DEG_TO_RAD)
102-
#define degrees(rad) ((rad)*RAD_TO_DEG)
103-
#define sq(x) ((x)*(x))
156+
157+
#ifndef radians
158+
#define radians(deg) \
159+
({ __typeof__ (deg) _deg = deg; \
160+
_deg * DEG_TO_RAD; })
161+
#endif
162+
163+
#ifndef degrees
164+
#define degrees(rad) \
165+
({ __typeof__ (rad) _rad = rad; \
166+
_rad * RAD_TO_DEG; })
167+
#endif
168+
169+
#ifndef sq
170+
#define sq(x) \
171+
({ __typeof__ (x) _x = x; \
172+
_x * _x; })
173+
#endif
174+
175+
#endif
104176

105177
#define interrupts() sei()
106178
#define noInterrupts() cli()
107179

180+
#if defined(__cplusplus)
181+
constexpr unsigned long clockCyclesPerMicrosecond(){
182+
return F_CPU / 1000000L;
183+
}
184+
185+
template <typename T> constexpr T clockCyclesToMicroseconds(const T a){
186+
return a / clockCyclesPerMicrosecond();
187+
}
188+
189+
template <typename T> constexpr T microsecondsToClockCycles(const T a){
190+
return a * clockCyclesPerMicrosecond();
191+
}
192+
193+
constexpr unsigned char lowByte(uint16_t w){
194+
return w & 0xff;
195+
}
196+
197+
constexpr unsigned char highByte(uint16_t w){
198+
return w >> 8;
199+
}
200+
201+
template <typename T>
202+
constexpr bool bitRead(T value, unsigned char bit){
203+
return (value >> bit) & 0x01;
204+
}
205+
206+
#else
207+
108208
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
109209
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
110210
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
@@ -113,6 +213,8 @@ void yield(void);
113213
#define highByte(w) ((uint8_t) ((w) >> 8))
114214

115215
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
216+
#endif
217+
116218
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
117219
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
118220
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))

0 commit comments

Comments
 (0)