My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

macros.h 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #pragma once
  23. #if !defined(__has_include)
  24. #define __has_include(...) 1
  25. #endif
  26. #define ABCE 4
  27. #define XYZE 4
  28. #define ABC 3
  29. #define XYZ 3
  30. #define XY 2
  31. #define _AXIS(A) (A##_AXIS)
  32. #define _XMIN_ 100
  33. #define _YMIN_ 200
  34. #define _ZMIN_ 300
  35. #define _XMAX_ 101
  36. #define _YMAX_ 201
  37. #define _ZMAX_ 301
  38. #define _XDIAG_ 102
  39. #define _YDIAG_ 202
  40. #define _ZDIAG_ 302
  41. #define _E0DIAG_ 400
  42. #define _E1DIAG_ 401
  43. #define _E2DIAG_ 402
  44. #define _E3DIAG_ 403
  45. #define _E4DIAG_ 404
  46. #define _E5DIAG_ 405
  47. #define _E6DIAG_ 406
  48. #define _E7DIAG_ 407
  49. #define _FORCE_INLINE_ __attribute__((__always_inline__)) __inline__
  50. #define FORCE_INLINE __attribute__((always_inline)) inline
  51. #define NO_INLINE __attribute__((noinline))
  52. #define _UNUSED __attribute__((unused))
  53. #define _O0 __attribute__((optimize("O0")))
  54. #define _Os __attribute__((optimize("Os")))
  55. #define _O1 __attribute__((optimize("O1")))
  56. #define _O2 __attribute__((optimize("O2")))
  57. #define _O3 __attribute__((optimize("O3")))
  58. #define IS_CONSTEXPR(...) __builtin_constant_p(__VA_ARGS__) // Only valid solution with C++14. Should use std::is_constant_evaluated() in C++20 instead
  59. #ifndef UNUSED
  60. #define UNUSED(x) ((void)(x))
  61. #endif
  62. // Clock speed factors
  63. #if !defined(CYCLES_PER_MICROSECOND) && !defined(__STM32F1__)
  64. #define CYCLES_PER_MICROSECOND (F_CPU / 1000000UL) // 16 or 20 on AVR
  65. #endif
  66. // Nanoseconds per cycle
  67. #define NANOSECONDS_PER_CYCLE (1000000000.0 / F_CPU)
  68. // Macros to make a string from a macro
  69. #define STRINGIFY_(M) #M
  70. #define STRINGIFY(M) STRINGIFY_(M)
  71. #define A(CODE) " " CODE "\n\t"
  72. #define L(CODE) CODE ":\n\t"
  73. // Macros for bit masks
  74. #undef _BV
  75. #define _BV(n) (1<<(n))
  76. #define TEST(n,b) (!!((n)&_BV(b)))
  77. #define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0)
  78. #ifndef SBI
  79. #define SBI(A,B) (A |= _BV(B))
  80. #endif
  81. #ifndef CBI
  82. #define CBI(A,B) (A &= ~_BV(B))
  83. #endif
  84. #define TBI(N,B) (N ^= _BV(B))
  85. #define _BV32(b) (1UL << (b))
  86. #define TEST32(n,b) !!((n)&_BV32(b))
  87. #define SBI32(n,b) (n |= _BV32(b))
  88. #define CBI32(n,b) (n &= ~_BV32(b))
  89. #define TBI32(N,B) (N ^= _BV32(B))
  90. #define cu(x) ({__typeof__(x) _x = (x); (_x)*(_x)*(_x);})
  91. #define RADIANS(d) ((d)*float(M_PI)/180.0f)
  92. #define DEGREES(r) ((r)*180.0f/float(M_PI))
  93. #define HYPOT2(x,y) (sq(x)+sq(y))
  94. #define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
  95. #define CIRCLE_AREA(R) (float(M_PI) * sq(float(R)))
  96. #define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
  97. #define SIGN(a) ({__typeof__(a) _a = (a); (_a>0)-(_a<0);})
  98. #define IS_POWER_OF_2(x) ((x) && !((x) & ((x) - 1)))
  99. // Macros to constrain values
  100. #ifdef __cplusplus
  101. // C++11 solution that is standards compliant.
  102. template <class V, class N> static inline constexpr void NOLESS(V& v, const N n) {
  103. if (n > v) v = n;
  104. }
  105. template <class V, class N> static inline constexpr void NOMORE(V& v, const N n) {
  106. if (n < v) v = n;
  107. }
  108. template <class V, class N1, class N2> static inline constexpr void LIMIT(V& v, const N1 n1, const N2 n2) {
  109. if (n1 > v) v = n1;
  110. else if (n2 < v) v = n2;
  111. }
  112. #else
  113. #define NOLESS(v, n) \
  114. do{ \
  115. __typeof__(v) _n = (n); \
  116. if (_n > v) v = _n; \
  117. }while(0)
  118. #define NOMORE(v, n) \
  119. do{ \
  120. __typeof__(v) _n = (n); \
  121. if (_n < v) v = _n; \
  122. }while(0)
  123. #define LIMIT(v, n1, n2) \
  124. do{ \
  125. __typeof__(v) _n1 = (n1); \
  126. __typeof__(v) _n2 = (n2); \
  127. if (_n1 > v) v = _n1; \
  128. else if (_n2 < v) v = _n2; \
  129. }while(0)
  130. #endif
  131. // Macros to chain up to 14 conditions
  132. #define _DO_1(W,C,A) (_##W##_1(A))
  133. #define _DO_2(W,C,A,B) (_##W##_1(A) C _##W##_1(B))
  134. #define _DO_3(W,C,A,V...) (_##W##_1(A) C _DO_2(W,C,V))
  135. #define _DO_4(W,C,A,V...) (_##W##_1(A) C _DO_3(W,C,V))
  136. #define _DO_5(W,C,A,V...) (_##W##_1(A) C _DO_4(W,C,V))
  137. #define _DO_6(W,C,A,V...) (_##W##_1(A) C _DO_5(W,C,V))
  138. #define _DO_7(W,C,A,V...) (_##W##_1(A) C _DO_6(W,C,V))
  139. #define _DO_8(W,C,A,V...) (_##W##_1(A) C _DO_7(W,C,V))
  140. #define _DO_9(W,C,A,V...) (_##W##_1(A) C _DO_8(W,C,V))
  141. #define _DO_10(W,C,A,V...) (_##W##_1(A) C _DO_9(W,C,V))
  142. #define _DO_11(W,C,A,V...) (_##W##_1(A) C _DO_10(W,C,V))
  143. #define _DO_12(W,C,A,V...) (_##W##_1(A) C _DO_11(W,C,V))
  144. #define _DO_13(W,C,A,V...) (_##W##_1(A) C _DO_12(W,C,V))
  145. #define _DO_14(W,C,A,V...) (_##W##_1(A) C _DO_13(W,C,V))
  146. #define _DO_15(W,C,A,V...) (_##W##_1(A) C _DO_14(W,C,V))
  147. #define __DO_N(W,C,N,V...) _DO_##N(W,C,V)
  148. #define _DO_N(W,C,N,V...) __DO_N(W,C,N,V)
  149. #define DO(W,C,V...) (_DO_N(W,C,NUM_ARGS(V),V))
  150. // Macros to support option testing
  151. #define _CAT(a,V...) a##V
  152. #define CAT(a,V...) _CAT(a,V)
  153. #define _ISENA_ ~,1
  154. #define _ISENA_1 ~,1
  155. #define _ISENA_0x1 ~,1
  156. #define _ISENA_true ~,1
  157. #define _ISENA(V...) IS_PROBE(V)
  158. #define _ENA_1(O) _ISENA(CAT(_IS,CAT(ENA_, O)))
  159. #define _DIS_1(O) NOT(_ENA_1(O))
  160. #define ENABLED(V...) DO(ENA,&&,V)
  161. #define DISABLED(V...) DO(DIS,&&,V)
  162. #define COUNT_ENABLED(V...) DO(ENA,+,V)
  163. #define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION converted to '0' or '1'
  164. #define TERN0(O,A) _TERN(_ENA_1(O),0,A) // OPTION converted to A or '0'
  165. #define TERN1(O,A) _TERN(_ENA_1(O),1,A) // OPTION converted to A or '1'
  166. #define TERN_(O,A) _TERN(_ENA_1(O),,A) // OPTION converted to A or '<nul>'
  167. #define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1'
  168. #define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1'
  169. #define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B.
  170. #define IF_ENABLED TERN_
  171. #define IF_DISABLED(O,A) TERN(O,,A)
  172. #define ANY(V...) !DISABLED(V)
  173. #define NONE(V...) DISABLED(V)
  174. #define ALL(V...) ENABLED(V)
  175. #define BOTH(V1,V2) ALL(V1,V2)
  176. #define EITHER(V1,V2) ANY(V1,V2)
  177. #define MANY(V...) (COUNT_ENABLED(V) > 1)
  178. // Macros to support pins/buttons exist testing
  179. #define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
  180. #define _PINEX_1 PIN_EXISTS
  181. #define PINS_EXIST(V...) DO(PINEX,&&,V)
  182. #define ANY_PIN(V...) DO(PINEX,||,V)
  183. #define BUTTON_EXISTS(BN) (defined(BTN_##BN) && BTN_##BN >= 0)
  184. #define _BTNEX_1 BUTTON_EXISTS
  185. #define BUTTONS_EXIST(V...) DO(BTNEX,&&,V)
  186. #define ANY_BUTTON(V...) DO(BTNEX,||,V)
  187. #define WITHIN(N,L,H) ((N) >= (L) && (N) <= (H))
  188. #define ISEOL(C) ((C) == '\n' || (C) == '\r')
  189. #define NUMERIC(a) WITHIN(a, '0', '9')
  190. #define DECIMAL(a) (NUMERIC(a) || a == '.')
  191. #define HEXCHR(a) (NUMERIC(a) ? (a) - '0' : WITHIN(a, 'a', 'f') ? ((a) - 'a' + 10) : WITHIN(a, 'A', 'F') ? ((a) - 'A' + 10) : -1)
  192. #define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+')
  193. #define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+')
  194. #define COUNT(a) (sizeof(a)/sizeof(*a))
  195. #define ZERO(a) memset(a,0,sizeof(a))
  196. #define COPY(a,b) do{ \
  197. static_assert(sizeof(a[0]) == sizeof(b[0]), "COPY: '" STRINGIFY(a) "' and '" STRINGIFY(b) "' types (sizes) don't match!"); \
  198. memcpy(&a[0],&b[0],_MIN(sizeof(a),sizeof(b))); \
  199. }while(0)
  200. // Macros for initializing arrays
  201. #define LIST_16(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P
  202. #define LIST_15(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O
  203. #define LIST_14(A,B,C,D,E,F,G,H,I,J,K,L,M,N,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N
  204. #define LIST_13(A,B,C,D,E,F,G,H,I,J,K,L,M,...) A,B,C,D,E,F,G,H,I,J,K,L,M
  205. #define LIST_12(A,B,C,D,E,F,G,H,I,J,K,L,...) A,B,C,D,E,F,G,H,I,J,K,L
  206. #define LIST_11(A,B,C,D,E,F,G,H,I,J,K,...) A,B,C,D,E,F,G,H,I,J,K
  207. #define LIST_10(A,B,C,D,E,F,G,H,I,J,...) A,B,C,D,E,F,G,H,I,J
  208. #define LIST_9( A,B,C,D,E,F,G,H,I,...) A,B,C,D,E,F,G,H,I
  209. #define LIST_8( A,B,C,D,E,F,G,H,...) A,B,C,D,E,F,G,H
  210. #define LIST_7( A,B,C,D,E,F,G,...) A,B,C,D,E,F,G
  211. #define LIST_6( A,B,C,D,E,F,...) A,B,C,D,E,F
  212. #define LIST_5( A,B,C,D,E,...) A,B,C,D,E
  213. #define LIST_4( A,B,C,D,...) A,B,C,D
  214. #define LIST_3( A,B,C,...) A,B,C
  215. #define LIST_2( A,B,...) A,B
  216. #define LIST_1( A,...) A
  217. #define _LIST_N(N,V...) LIST_##N(V)
  218. #define LIST_N(N,V...) _LIST_N(N,V)
  219. #define ARRAY_N(N,V...) { _LIST_N(N,V) }
  220. #define _JOIN_1(O) (O)
  221. #define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V)))
  222. #define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=(S); VAR<=(N); VAR++)
  223. #define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=(S); VAR<(N); VAR++)
  224. #define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N)
  225. #define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N)
  226. #define NOOP (void(0))
  227. #define CEILING(x,y) (((x) + (y) - 1) / (y))
  228. #undef ABS
  229. #ifdef __cplusplus
  230. template <class T> static inline constexpr const T ABS(const T v) { return v >= 0 ? v : -v; }
  231. #else
  232. #define ABS(a) ({__typeof__(a) _a = (a); _a >= 0 ? _a : -_a;})
  233. #endif
  234. #define UNEAR_ZERO(x) ((x) < 0.000001f)
  235. #define NEAR_ZERO(x) WITHIN(x, -0.000001f, 0.000001f)
  236. #define NEAR(x,y) NEAR_ZERO((x)-(y))
  237. #define RECIPROCAL(x) (NEAR_ZERO(x) ? 0 : (1 / float(x)))
  238. #define FIXFLOAT(f) ({__typeof__(f) _f = (f); _f + (_f < 0 ? -0.0000005f : 0.0000005f);})
  239. //
  240. // Maths macros that can be overridden by HAL
  241. //
  242. #define ACOS(x) acosf(x)
  243. #define ATAN2(y, x) atan2f(y, x)
  244. #define POW(x, y) powf(x, y)
  245. #define SQRT(x) sqrtf(x)
  246. #define RSQRT(x) (1.0f / sqrtf(x))
  247. #define CEIL(x) ceilf(x)
  248. #define FLOOR(x) floorf(x)
  249. #define TRUNC(x) truncf(x)
  250. #define LROUND(x) lroundf(x)
  251. #define FMOD(x, y) fmodf(x, y)
  252. #define HYPOT(x,y) SQRT(HYPOT2(x,y))
  253. // Use NUM_ARGS(__VA_ARGS__) to get the number of variadic arguments
  254. #define _NUM_ARGS(_,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,OUT,...) OUT
  255. #define NUM_ARGS(V...) _NUM_ARGS(0,V,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
  256. #ifdef __cplusplus
  257. #ifndef _MINMAX_H_
  258. #define _MINMAX_H_
  259. extern "C++" {
  260. // C++11 solution that is standards compliant. Return type is deduced automatically
  261. template <class L, class R> static inline constexpr auto _MIN(const L lhs, const R rhs) -> decltype(lhs + rhs) {
  262. return lhs < rhs ? lhs : rhs;
  263. }
  264. template <class L, class R> static inline constexpr auto _MAX(const L lhs, const R rhs) -> decltype(lhs + rhs) {
  265. return lhs > rhs ? lhs : rhs;
  266. }
  267. template<class T, class ... Ts> static inline constexpr const T _MIN(T V, Ts... Vs) { return _MIN(V, _MIN(Vs...)); }
  268. template<class T, class ... Ts> static inline constexpr const T _MAX(T V, Ts... Vs) { return _MAX(V, _MAX(Vs...)); }
  269. }
  270. #endif
  271. // Allow manipulating enumeration value like flags without ugly cast everywhere
  272. #define ENUM_FLAGS(T) \
  273. FORCE_INLINE constexpr T operator&(T x, T y) { return static_cast<T>(static_cast<int>(x) & static_cast<int>(y)); } \
  274. FORCE_INLINE constexpr T operator|(T x, T y) { return static_cast<T>(static_cast<int>(x) | static_cast<int>(y)); } \
  275. FORCE_INLINE constexpr T operator^(T x, T y) { return static_cast<T>(static_cast<int>(x) ^ static_cast<int>(y)); } \
  276. FORCE_INLINE constexpr T operator~(T x) { return static_cast<T>(~static_cast<int>(x)); } \
  277. FORCE_INLINE T & operator&=(T &x, T y) { return x &= y; } \
  278. FORCE_INLINE T & operator|=(T &x, T y) { return x |= y; } \
  279. FORCE_INLINE T & operator^=(T &x, T y) { return x ^= y; }
  280. // C++11 solution that is standard compliant. <type_traits> is not available on all platform
  281. namespace Private {
  282. template<bool, typename _Tp = void> struct enable_if { };
  283. template<typename _Tp> struct enable_if<true, _Tp> { typedef _Tp type; };
  284. template<typename T, typename U> struct is_same { enum { value = false }; };
  285. template<typename T> struct is_same<T, T> { enum { value = true }; };
  286. template <typename T, typename ... Args> struct first_type_of { typedef T type; };
  287. template <typename T> struct first_type_of<T> { typedef T type; };
  288. }
  289. // C++11 solution using SFINAE to detect the existance of a member in a class at compile time.
  290. // It creates a HasMember<Type> structure containing 'value' set to true if the member exists
  291. #define HAS_MEMBER_IMPL(Member) \
  292. namespace Private { \
  293. template <typename Type, typename Yes=char, typename No=long> struct HasMember_ ## Member { \
  294. template <typename C> static Yes& test( decltype(&C::Member) ) ; \
  295. template <typename C> static No& test(...); \
  296. enum { value = sizeof(test<Type>(0)) == sizeof(Yes) }; }; \
  297. }
  298. // Call the method if it exists, but do nothing if it does not. The method is detected at compile time.
  299. // If the method exists, this is inlined and does not cost anything. Else, an "empty" wrapper is created, returning a default value
  300. #define CALL_IF_EXISTS_IMPL(Return, Method, ...) \
  301. HAS_MEMBER_IMPL(Method) \
  302. namespace Private { \
  303. template <typename T, typename ... Args> FORCE_INLINE typename enable_if<HasMember_ ## Method <T>::value, Return>::type Call_ ## Method(T * t, Args... a) { return static_cast<Return>(t->Method(a...)); } \
  304. _UNUSED static Return Call_ ## Method(...) { return __VA_ARGS__; } \
  305. }
  306. #define CALL_IF_EXISTS(Return, That, Method, ...) \
  307. static_cast<Return>(Private::Call_ ## Method(That, ##__VA_ARGS__))
  308. // Compile-time string manipulation
  309. namespace CompileTimeString {
  310. // Simple compile-time parser to find the position of the end of a string
  311. constexpr const char* findStringEnd(const char *str) {
  312. return *str ? findStringEnd(str + 1) : str;
  313. }
  314. // Check whether a string contains a specific character
  315. constexpr bool contains(const char *str, const char ch) {
  316. return *str == ch ? true : (*str ? contains(str + 1, ch) : false);
  317. }
  318. // Find the last position of the specific character (should be called with findStringEnd)
  319. constexpr const char* findLastPos(const char *str, const char ch) {
  320. return *str == ch ? (str + 1) : findLastPos(str - 1, ch);
  321. }
  322. // Compile-time evaluation of the last part of a file path
  323. // Typically used to shorten the path to file in compiled strings
  324. // CompileTimeString::baseName(__FILE__) returns "macros.h" and not /path/to/Marlin/src/core/macros.h
  325. constexpr const char* baseName(const char *str) {
  326. return contains(str, '/') ? findLastPos(findStringEnd(str), '/') : str;
  327. }
  328. // Find the first occurence of a character in a string (or return the last position in the string)
  329. constexpr const char* findFirst(const char *str, const char ch) {
  330. return *str == ch || *str == 0 ? (str + 1) : findFirst(str + 1, ch);
  331. }
  332. // Compute the string length at compile time
  333. constexpr unsigned stringLen(const char *str) {
  334. return *str == 0 ? 0 : 1 + stringLen(str + 1);
  335. }
  336. }
  337. #define ONLY_FILENAME CompileTimeString::baseName(__FILE__)
  338. /** Get the templated type name. This does not depends on RTTI, but on the preprocessor, so it should be quite safe to use even on old compilers.
  339. WARNING: DO NOT RENAME THIS FUNCTION (or change the text inside the function to match what the preprocessor will generate)
  340. The name is chosen very short since the binary will store "const char* gtn(T*) [with T = YourTypeHere]" so avoid long function name here */
  341. template <typename T>
  342. inline const char* gtn(T*) {
  343. // It works on GCC by instantiating __PRETTY_FUNCTION__ and parsing the result. So the syntax here is very limited to GCC output
  344. constexpr unsigned verboseChatLen = sizeof("const char* gtn(T*) [with T = ") - 1;
  345. static char templateType[sizeof(__PRETTY_FUNCTION__) - verboseChatLen] = {};
  346. __builtin_memcpy(templateType, __PRETTY_FUNCTION__ + verboseChatLen, sizeof(__PRETTY_FUNCTION__) - verboseChatLen - 2);
  347. return templateType;
  348. }
  349. #else
  350. #define MIN_2(a,b) ((a)<(b)?(a):(b))
  351. #define MIN_3(a,V...) MIN_2(a,MIN_2(V))
  352. #define MIN_4(a,V...) MIN_2(a,MIN_3(V))
  353. #define MIN_5(a,V...) MIN_2(a,MIN_4(V))
  354. #define MIN_6(a,V...) MIN_2(a,MIN_5(V))
  355. #define MIN_7(a,V...) MIN_2(a,MIN_6(V))
  356. #define MIN_8(a,V...) MIN_2(a,MIN_7(V))
  357. #define MIN_9(a,V...) MIN_2(a,MIN_8(V))
  358. #define MIN_10(a,V...) MIN_2(a,MIN_9(V))
  359. #define __MIN_N(N,V...) MIN_##N(V)
  360. #define _MIN_N(N,V...) __MIN_N(N,V)
  361. #define _MIN(V...) _MIN_N(NUM_ARGS(V), V)
  362. #define MAX_2(a,b) ((a)>(b)?(a):(b))
  363. #define MAX_3(a,V...) MAX_2(a,MAX_2(V))
  364. #define MAX_4(a,V...) MAX_2(a,MAX_3(V))
  365. #define MAX_5(a,V...) MAX_2(a,MAX_4(V))
  366. #define MAX_6(a,V...) MAX_2(a,MAX_5(V))
  367. #define MAX_7(a,V...) MAX_2(a,MAX_6(V))
  368. #define MAX_8(a,V...) MAX_2(a,MAX_7(V))
  369. #define MAX_9(a,V...) MAX_2(a,MAX_8(V))
  370. #define MAX_10(a,V...) MAX_2(a,MAX_9(V))
  371. #define __MAX_N(N,V...) MAX_##N(V)
  372. #define _MAX_N(N,V...) __MAX_N(N,V)
  373. #define _MAX(V...) _MAX_N(NUM_ARGS(V), V)
  374. #endif
  375. // Macros for adding
  376. #define INC_0 1
  377. #define INC_1 2
  378. #define INC_2 3
  379. #define INC_3 4
  380. #define INC_4 5
  381. #define INC_5 6
  382. #define INC_6 7
  383. #define INC_7 8
  384. #define INC_8 9
  385. #define INC_9 10
  386. #define INC_10 11
  387. #define INC_11 12
  388. #define INC_12 13
  389. #define INC_13 14
  390. #define INC_14 15
  391. #define INC_15 16
  392. #define INCREMENT_(n) INC_##n
  393. #define INCREMENT(n) INCREMENT_(n)
  394. #define ADD0(N) N
  395. #define ADD1(N) INCREMENT_(N)
  396. #define ADD2(N) ADD1(ADD1(N))
  397. #define ADD3(N) ADD1(ADD2(N))
  398. #define ADD4(N) ADD2(ADD2(N))
  399. #define ADD5(N) ADD2(ADD3(N))
  400. #define ADD6(N) ADD3(ADD3(N))
  401. #define ADD7(N) ADD3(ADD4(N))
  402. #define ADD8(N) ADD4(ADD4(N))
  403. #define ADD9(N) ADD4(ADD5(N))
  404. #define ADD10(N) ADD5(ADD5(N))
  405. // Macros for subtracting
  406. #define DEC_0 0
  407. #define DEC_1 0
  408. #define DEC_2 1
  409. #define DEC_3 2
  410. #define DEC_4 3
  411. #define DEC_5 4
  412. #define DEC_6 5
  413. #define DEC_7 6
  414. #define DEC_8 7
  415. #define DEC_9 8
  416. #define DEC_10 9
  417. #define DEC_11 10
  418. #define DEC_12 11
  419. #define DEC_13 12
  420. #define DEC_14 13
  421. #define DEC_15 14
  422. #define DECREMENT_(n) DEC_##n
  423. #define DECREMENT(n) DECREMENT_(n)
  424. #define SUB0(N) N
  425. #define SUB1(N) DECREMENT_(N)
  426. #define SUB2(N) SUB1(SUB1(N))
  427. #define SUB3(N) SUB1(SUB2(N))
  428. #define SUB4(N) SUB2(SUB2(N))
  429. #define SUB5(N) SUB2(SUB3(N))
  430. #define SUB6(N) SUB3(SUB3(N))
  431. #define SUB7(N) SUB3(SUB4(N))
  432. #define SUB8(N) SUB4(SUB4(N))
  433. #define SUB9(N) SUB4(SUB5(N))
  434. #define SUB10(N) SUB5(SUB5(N))
  435. //
  436. // Primitives supporting precompiler REPEAT
  437. //
  438. #define FIRST(a,...) a
  439. #define SECOND(a,b,...) b
  440. #define THIRD(a,b,c,...) c
  441. // Defer expansion
  442. #define EMPTY()
  443. #define DEFER(M) M EMPTY()
  444. #define DEFER2(M) M EMPTY EMPTY()()
  445. #define DEFER3(M) M EMPTY EMPTY EMPTY()()()
  446. #define DEFER4(M) M EMPTY EMPTY EMPTY EMPTY()()()()
  447. // Force define expansion
  448. #define EVAL(V...) EVAL16(V)
  449. #define EVAL1024(V...) EVAL512(EVAL512(V))
  450. #define EVAL512(V...) EVAL256(EVAL256(V))
  451. #define EVAL256(V...) EVAL128(EVAL128(V))
  452. #define EVAL128(V...) EVAL64(EVAL64(V))
  453. #define EVAL64(V...) EVAL32(EVAL32(V))
  454. #define EVAL32(V...) EVAL16(EVAL16(V))
  455. #define EVAL16(V...) EVAL8(EVAL8(V))
  456. #define EVAL8(V...) EVAL4(EVAL4(V))
  457. #define EVAL4(V...) EVAL2(EVAL2(V))
  458. #define EVAL2(V...) EVAL1(EVAL1(V))
  459. #define EVAL1(V...) V
  460. #define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
  461. #define PROBE() ~, 1 // Second item will be 1 if this is passed
  462. #define _NOT_0 PROBE()
  463. #define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
  464. #define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'.
  465. #define IF_ELSE(TF) _IF_ELSE(_BOOL(TF))
  466. #define _IF_ELSE(TF) _CAT(_IF_, TF)
  467. #define _IF_1(V...) V _IF_1_ELSE
  468. #define _IF_0(...) _IF_0_ELSE
  469. #define _IF_1_ELSE(...)
  470. #define _IF_0_ELSE(V...) V
  471. #define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
  472. #define _END_OF_ARGUMENTS_() 0
  473. // Simple Inline IF Macros, friendly to use in other macro definitions
  474. #define IF(O, A, B) ((O) ? (A) : (B))
  475. #define IF_0(O, A) IF(O, A, 0)
  476. #define IF_1(O, A) IF(O, A, 1)
  477. //
  478. // REPEAT core macros. Recurse N times with ascending I.
  479. //
  480. // Call OP(I) N times with ascending counter.
  481. #define _REPEAT(_RPT_I,_RPT_N,_RPT_OP) \
  482. _RPT_OP(_RPT_I) \
  483. IF_ELSE(SUB1(_RPT_N)) \
  484. ( DEFER2(__REPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \
  485. ( /* Do nothing */ )
  486. #define __REPEAT() _REPEAT
  487. // Call OP(I, ...) N times with ascending counter.
  488. #define _REPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \
  489. _RPT_OP(_RPT_I,V) \
  490. IF_ELSE(SUB1(_RPT_N)) \
  491. ( DEFER2(__REPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \
  492. ( /* Do nothing */ )
  493. #define __REPEAT2() _REPEAT2
  494. // Repeat a macro passing S...N-1.
  495. #define REPEAT_S(S,N,OP) EVAL(_REPEAT(S,SUB##S(N),OP))
  496. #define REPEAT(N,OP) REPEAT_S(0,N,OP)
  497. // Repeat a macro passing 0...N-1 plus additional arguments.
  498. #define REPEAT2_S(S,N,OP,V...) EVAL(_REPEAT2(S,SUB##S(N),OP,V))
  499. #define REPEAT2(N,OP,V...) REPEAT2_S(0,N,OP,V)
  500. // Use RREPEAT macros with REPEAT macros for nesting
  501. #define _RREPEAT(_RPT_I,_RPT_N,_RPT_OP) \
  502. _RPT_OP(_RPT_I) \
  503. IF_ELSE(SUB1(_RPT_N)) \
  504. ( DEFER2(__RREPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \
  505. ( /* Do nothing */ )
  506. #define __RREPEAT() _RREPEAT
  507. #define _RREPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \
  508. _RPT_OP(_RPT_I,V) \
  509. IF_ELSE(SUB1(_RPT_N)) \
  510. ( DEFER2(__RREPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \
  511. ( /* Do nothing */ )
  512. #define __RREPEAT2() _RREPEAT2
  513. #define RREPEAT_S(S,N,OP) EVAL1024(_RREPEAT(S,SUB##S(N),OP))
  514. #define RREPEAT(N,OP) RREPEAT_S(0,N,OP)
  515. #define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V))
  516. #define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V)
  517. // See https://github.com/swansontec/map-macro
  518. #define MAP_OUT
  519. #define MAP_END(...)
  520. #define MAP_GET_END() 0, MAP_END
  521. #define MAP_NEXT0(test, next, ...) next MAP_OUT
  522. #define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0)
  523. #define MAP_NEXT(test, next) MAP_NEXT1 (MAP_GET_END test, next)
  524. #define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
  525. #define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
  526. #define MAP(f, ...) EVAL512 (MAP1 (f, __VA_ARGS__, (), 0))