From 5897ecd92d678c98b7bbadeb9877fe58fe88d0f0 Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Thu, 14 Jul 2022 00:00:00 +0000 Subject: [PATCH 1/2] Excluded the series of function-like macros out of `extern "C"{` block in `Arduino.h`. --- cores/arduino/Arduino.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 91eeb16bc..0aaef6beb 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -89,6 +89,10 @@ void yield(void); #undef abs #endif +#if defined(__cplusplus) +}; // extern "C" +#endif + #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) #define abs(x) ((x)>0?(x):-(x)) @@ -126,6 +130,10 @@ typedef unsigned int word; typedef bool boolean; typedef uint8_t byte; +#if defined(__cplusplus) +extern "C"{ +#endif + void init(void); void initVariant(void); From 4ae6b262146fc6b79b6652c5e3c900ba1667c13f Mon Sep 17 00:00:00 2001 From: KOLANICH Date: Thu, 14 Jul 2022 00:00:00 +0000 Subject: [PATCH 2/2] 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 https://github.com/arduino/ArduinoCore-API/pull/140 and https://github.com/arduino/ArduinoCore-API/commit/30e439755e47339d19a835da9cd79cb1791c2e9f Co-Authored-By: Keating Reid Co-Authored-By: Martino Facchin --- cores/arduino/Arduino.h | 114 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 6 deletions(-) diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 0aaef6beb..fd2d48573 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -93,18 +93,118 @@ void yield(void); }; // extern "C" #endif -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#if defined(__cplusplus) +template constexpr auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) +{ + return (b < a) ? b : a; +} + +template constexpr auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) +{ + return (a < b) ? b : a; +} + +template constexpr auto abs(const T x) -> decltype(x>0?x:-x){ + return x>0?x:-x; +} + +template constexpr auto constrain(const T& amt, const U& low, const V& high) -> decltype(amt < low ? low : (amt > high ? high : amt)) { + return amt < low ? low : (amt > high ? high : amt); +} + +template constexpr T round(const T x){ + return x>=0?static_cast(x+0.5):static_cast(x-0.5); +} + +template constexpr auto radians(const T& deg) -> decltype(deg * DEG_TO_RAD){ + return deg * DEG_TO_RAD; +} + +template constexpr auto degrees(const T& rad) -> decltype(rad * RAD_TO_DEG){ + return rad * RAD_TO_DEG; +} + +template constexpr auto sq(const T& x) -> decltype(x*x){ + return x*x; +} +#else +#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 abs(x) ((x)>0?(x):-(x)) -#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) + +#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 round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) -#define radians(deg) ((deg)*DEG_TO_RAD) -#define degrees(rad) ((rad)*RAD_TO_DEG) -#define sq(x) ((x)*(x)) + +#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 + +#endif #define interrupts() sei() #define noInterrupts() cli() +#if defined(__cplusplus) +constexpr unsigned long clockCyclesPerMicrosecond(){ + return F_CPU / 1000000L; +} + +template constexpr T clockCyclesToMicroseconds(const T a){ + return a / clockCyclesPerMicrosecond(); +} + +template constexpr T microsecondsToClockCycles(const T a){ + return a * clockCyclesPerMicrosecond(); +} + +constexpr unsigned char lowByte(uint16_t w){ + return w & 0xff; +} + +constexpr unsigned char highByte(uint16_t w){ + return w >> 8; +} + +template +constexpr bool bitRead(T value, unsigned char bit){ + return (value >> bit) & 0x01; +} + +#else + #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) @@ -113,6 +213,8 @@ void yield(void); #define highByte(w) ((uint8_t) ((w) >> 8)) #define bitRead(value, bit) (((value) >> (bit)) & 0x01) +#endif + #define bitSet(value, bit) ((value) |= (1UL << (bit))) #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) #define bitToggle(value, bit) ((value) ^= (1UL << (bit)))