3#include "platforms/is_platform.h"
7#define FL_STRINGIFY2(x) #x
8#define FL_STRINGIFY(x) FL_STRINGIFY2(x)
11#if defined(FL_IS_CLANG)
12 #define FL_DISABLE_WARNING_PUSH _Pragma("clang diagnostic push")
13 #define FL_DISABLE_WARNING_POP _Pragma("clang diagnostic pop")
15 #define FL_DISABLE_WARNING(warning) _Pragma(FL_STRINGIFY(clang diagnostic ignored "-W" #warning))
17#elif defined(FL_IS_GCC) && FL_GCC_VERSION >= 406
18 #define FL_DISABLE_WARNING_PUSH _Pragma("GCC diagnostic push")
19 #define FL_DISABLE_WARNING_POP _Pragma("GCC diagnostic pop")
21 #define FL_DISABLE_WARNING(warning) _Pragma(FL_STRINGIFY(GCC diagnostic ignored "-W" #warning))
23 #define FL_DISABLE_WARNING_PUSH
24 #define FL_DISABLE_WARNING_POP
25 #define FL_DISABLE_WARNING(warning)
30#if defined(FL_IS_CLANG)
31 #define FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS \
32 FL_DISABLE_WARNING(global-constructors)
33 #define FL_DISABLE_WARNING_SELF_ASSIGN \
34 FL_DISABLE_WARNING(self-assign)
35 #define FL_DISABLE_WARNING_SELF_ASSIGN_OVERLOADED \
36 FL_DISABLE_WARNING(self-assign-overloaded)
38 #define FL_DISABLE_FORMAT_TRUNCATION
39 #define FL_DISABLE_WARNING_NULL_DEREFERENCE FL_DISABLE_WARNING(null-dereference)
40 #define FL_DISABLE_WARNING_IMPLICIT_FALLTHROUGH
41 #define FL_DISABLE_WARNING_UNUSED_PARAMETER FL_DISABLE_WARNING(unused-parameter)
42 #define FL_DISABLE_WARNING_RETURN_TYPE
43 #define FL_DISABLE_WARNING_IMPLICIT_INT_CONVERSION FL_DISABLE_WARNING(implicit-int-conversion)
44 #define FL_DISABLE_WARNING_FLOAT_CONVERSION FL_DISABLE_WARNING(float-conversion)
45 #define FL_DISABLE_WARNING_SIGN_CONVERSION FL_DISABLE_WARNING(sign-conversion)
46 #define FL_DISABLE_WARNING_SHORTEN_64_TO_32 FL_DISABLE_WARNING(shorten-64-to-32)
48 #define FL_DISABLE_WARNING_VOLATILE FL_DISABLE_WARNING(deprecated-volatile)
49 #define FL_DISABLE_WARNING_DEPRECATED_REGISTER FL_DISABLE_WARNING(deprecated-register)
51 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED
53 #define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE
55 #define FL_DISABLE_WARNING_C14_EXTENSIONS FL_DISABLE_WARNING(c++14-extensions)
56 #define FL_DISABLE_WARNING_C17_EXTENSIONS FL_DISABLE_WARNING(c++17-extensions)
58 #define FL_DISABLE_WARNING_CLASS_MEMACCESS
60 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED
61#elif defined(FL_IS_GCC) && FL_GCC_VERSION >= 406
63 #define FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS
65 #define FL_DISABLE_WARNING_SELF_ASSIGN
67 #define FL_DISABLE_WARNING_SELF_ASSIGN_OVERLOADED
69 #define FL_DISABLE_FORMAT_TRUNCATION \
70 FL_DISABLE_WARNING(format-truncation)
71 #define FL_DISABLE_WARNING_NULL_DEREFERENCE
72 #define FL_DISABLE_WARNING_UNUSED_PARAMETER \
73 FL_DISABLE_WARNING(unused-parameter)
74 #define FL_DISABLE_WARNING_RETURN_TYPE \
75 FL_DISABLE_WARNING(return-type)
78 #if FL_GCC_VERSION >= 700
79 #define FL_DISABLE_WARNING_IMPLICIT_FALLTHROUGH FL_DISABLE_WARNING(implicit-fallthrough)
81 #define FL_DISABLE_WARNING_IMPLICIT_FALLTHROUGH
84 #define FL_DISABLE_WARNING_FLOAT_CONVERSION
85 #define FL_DISABLE_WARNING_SIGN_CONVERSION
86 #define FL_DISABLE_WARNING_IMPLICIT_INT_CONVERSION
88 #define FL_DISABLE_WARNING_SHORTEN_64_TO_32
90 #if defined(FL_IS_AVR) || (FL_GCC_VERSION < 1000)
91 #define FL_DISABLE_WARNING_VOLATILE
93 #define FL_DISABLE_WARNING_VOLATILE FL_DISABLE_WARNING(volatile)
96 #if FL_GCC_VERSION >= 500
97 #define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE FL_DISABLE_WARNING(subobject-linkage)
99 #define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE
102 #define FL_DISABLE_WARNING_C14_EXTENSIONS
103 #define FL_DISABLE_WARNING_C17_EXTENSIONS
105 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED FL_DISABLE_WARNING(maybe-uninitialized)
107 #if FL_GCC_VERSION >= 800
108 #define FL_DISABLE_WARNING_CLASS_MEMACCESS FL_DISABLE_WARNING(class-memaccess)
110 #define FL_DISABLE_WARNING_CLASS_MEMACCESS
113 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED FL_DISABLE_WARNING(maybe-uninitialized)
115 #if FL_GCC_VERSION >= 700
116 #define FL_DISABLE_WARNING_DEPRECATED_REGISTER FL_DISABLE_WARNING(register)
118 #define FL_DISABLE_WARNING_DEPRECATED_REGISTER
121 #define FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS
122 #define FL_DISABLE_WARNING_SELF_ASSIGN
123 #define FL_DISABLE_WARNING_SELF_ASSIGN_OVERLOADED
124 #define FL_DISABLE_FORMAT_TRUNCATION
125 #define FL_DISABLE_WARNING_NULL_DEREFERENCE
126 #define FL_DISABLE_WARNING_UNUSED_PARAMETER
127 #define FL_DISABLE_WARNING_RETURN_TYPE
128 #define FL_DISABLE_WARNING_IMPLICIT_INT_CONVERSION
129 #define FL_DISABLE_WARNING_FLOAT_CONVERSION
130 #define FL_DISABLE_WARNING_SIGN_CONVERSION
131 #define FL_DISABLE_WARNING_SHORTEN_64_TO_32
132 #define FL_DISABLE_WARNING_VOLATILE
133 #define FL_DISABLE_WARNING_DEPRECATED_REGISTER
135 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED
137 #define FL_DISABLE_WARNING_SUBOBJECT_LINKAGE
139 #define FL_DISABLE_WARNING_C14_EXTENSIONS
140 #define FL_DISABLE_WARNING_C17_EXTENSIONS
142 #define FL_DISABLE_WARNING_CLASS_MEMACCESS
143 #define FL_DISABLE_WARNING_MAYBE_UNINITIALIZED
154#define FL_ALLOW_PLATFORM_PRAGMA
157#define FL_DIAGNOSTIC_PUSH FL_DISABLE_WARNING_PUSH
158#define FL_DIAGNOSTIC_POP FL_DISABLE_WARNING_POP
159#define FL_DIAGNOSTIC_IGNORE_C14_EXTENSIONS FL_DISABLE_WARNING_C14_EXTENSIONS
162#if defined(FL_IS_CLANG)
163 #define FL_FAST_MATH_BEGIN \
164 _Pragma("clang diagnostic push") \
165 _Pragma("STDC FP_CONTRACT ON")
167 #define FL_FAST_MATH_END _Pragma("clang diagnostic pop")
169#elif defined(FL_IS_GCC)
170 #define FL_FAST_MATH_BEGIN \
171 _Pragma("GCC push_options") \
172 _Pragma("GCC optimize (\"fast-math\")") \
173 _Pragma("GCC optimize (\"tree-vectorize\")") \
174 _Pragma("GCC optimize (\"unroll-loops\")")
176 #define FL_FAST_MATH_END _Pragma("GCC pop_options")
178#elif defined(FL_IS_WIN_MSVC)
179 #define FL_FAST_MATH_BEGIN __pragma(float_control(precise, off))
180 #define FL_FAST_MATH_END __pragma(float_control(precise, on))
182 #define FL_FAST_MATH_BEGIN
183 #define FL_FAST_MATH_END
193#if defined(FL_IS_CLANG)
194 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN \
195 _Pragma("clang attribute push(__attribute__((hot)), apply_to = function)")
196 #define FL_OPTIMIZATION_LEVEL_O3_END \
197 _Pragma("clang attribute pop")
199#elif defined(FL_IS_GCC)
200 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN \
201 _Pragma("GCC push_options") \
202 _Pragma("GCC optimize (\"O3\")")
204 #define FL_OPTIMIZATION_LEVEL_O3_END _Pragma("GCC pop_options")
206 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN
207 #define FL_OPTIMIZATION_LEVEL_O3_END
211#if defined(FL_IS_CLANG)
212 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN \
213 _Pragma("clang diagnostic push")
215 #define FL_OPTIMIZATION_LEVEL_O0_END _Pragma("clang diagnostic pop")
217#elif defined(FL_IS_GCC)
218 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN \
219 _Pragma("GCC push_options") \
220 _Pragma("GCC optimize (\"O0\")")
222 #define FL_OPTIMIZATION_LEVEL_O0_END _Pragma("GCC pop_options")
224 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN
225 #define FL_OPTIMIZATION_LEVEL_O0_END
232#ifndef FL_TIMING_OPT_LEVEL
233#define FL_TIMING_OPT_LEVEL 2
236#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
239 #if FL_TIMING_OPT_LEVEL == 0
240 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O0\")")
241 #elif FL_TIMING_OPT_LEVEL == 1
242 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O1\")")
243 #elif FL_TIMING_OPT_LEVEL == 3
244 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O3\")")
247 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O2\")")
255 #define FL_BEGIN_OPTIMIZE_FOR_EXACT_TIMING \
256 _Pragma("GCC push_options") \
257 _FL_TIMING_OPT_PRAGMA \
258 _Pragma("GCC optimize(\"-fno-schedule-insns\")") \
259 _Pragma("GCC optimize(\"-fno-schedule-insns2\")") \
260 _Pragma("GCC optimize(\"-fno-reorder-blocks\")") \
261 _Pragma("GCC optimize(\"-fno-tree-vectorize\")") \
262 _Pragma("GCC optimize(\"-fno-tree-reassoc\")") \
263 _Pragma("GCC optimize(\"-fno-unroll-loops\")")
265 #define FL_END_OPTIMIZE_FOR_EXACT_TIMING \
266 _Pragma("GCC pop_options")
268 #define FL_BEGIN_OPTIMIZE_FOR_EXACT_TIMING
269 #define FL_END_OPTIMIZE_FOR_EXACT_TIMING
275#if defined(FL_IS_GCC)
276 #define FL_OPTIMIZE_FUNCTION __attribute__((optimize("O3")))
277 #define FL_OPTIMIZE_O2 __attribute__((optimize("O2")))
278#elif defined(FL_IS_CLANG)
279 #define FL_OPTIMIZE_FUNCTION __attribute__((hot))
280 #define FL_OPTIMIZE_O2 __attribute__((hot))
282 #define FL_OPTIMIZE_FUNCTION
283 #define FL_OPTIMIZE_O2
287#define FL_LINK_WEAK __attribute__((weak))
294#if defined(FL_IS_AVR)
297#elif defined(FL_IS_GCC)
299 #if FL_GCC_VERSION >= 800
300 #define FL_UNROLL(N) _Pragma(FL_STRINGIFY(GCC unroll N))
305#elif defined(FL_IS_CLANG)
307 #define FL_UNROLL(N) _Pragma(FL_STRINGIFY(unroll N))
314#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
315 #define FL_MAYBE_UNUSED __attribute__((unused))
317 #define FL_MAYBE_UNUSED
332#if defined(FL_IS_AVR)
333 #define FL_NO_INLINE_IF_AVR __attribute__((noinline))
335 #define FL_NO_INLINE_IF_AVR
348#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
349 #define FL_NO_INLINE __attribute__((noinline))
350#elif defined(FL_IS_WIN_MSVC)
351 #define FL_NO_INLINE __declspec(noinline)
358#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
359 #define FL_COLD __attribute__((cold))
384#if defined(FL_ARM_M0_RAMFUNC) && (defined(FL_IS_GCC) || defined(FL_IS_CLANG))
385 #define FL_RAMFUNC __attribute__((section(".ramfunc"), noinline, long_call))
392#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
393 #define FL_CONSTRUCTOR __attribute__((constructor))
394#elif defined(FL_IS_WIN_MSVC)
396 #define FL_CONSTRUCTOR
397 #pragma message("Warning: FL_CONSTRUCTOR not fully supported on MSVC")
399 #define FL_CONSTRUCTOR
405 #if defined(FL_IS_WASM)
408#include <emscripten.h>
411 #define FL_KEEP_ALIVE EMSCRIPTEN_KEEPALIVE
412 #elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
414 #define FL_KEEP_ALIVE __attribute__((used))
415 #elif defined(FL_IS_WIN_MSVC)
419 #define FL_KEEP_ALIVE __pragma(optimize("", off)) __pragma(optimize("", on))
422 #define FL_KEEP_ALIVE
448#if defined(FL_IS_WIN_MSVC)
449 #pragma section(".CRT$XCU", read)
451 #define FL_INIT(wrapper_name, func) \
452 namespace static_init { \
453 static void wrapper_name() { func(); } \
454 __declspec(allocate(".CRT$XCU")) \
455 static void (*wrapper_name##_ptr)(void) = wrapper_name; \
458#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
459 #define FL_INIT(wrapper_name, func) \
460 namespace static_init { \
461 FL_CONSTRUCTOR FL_KEEP_ALIVE \
462 void wrapper_name() { func(); } \
466 #error Unsupported compiler for FL_INIT
484#define FL_RUN_ONCE(code) \
486 static bool fl_run_once_flag = false; \
487 if (!fl_run_once_flag) { \
488 fl_run_once_flag = true; \
495 #define FL_EXTERN_C_BEGIN extern "C" {
496 #define FL_EXTERN_C_END }
497 #define FL_EXTERN_C extern "C"
499 #define FL_EXTERN_C_BEGIN
500 #define FL_EXTERN_C_END
528#define FL_INLINE_CONSTEXPR inline constexpr
534#if __cplusplus >= 201402L
535#define FL_CONSTEXPR14 constexpr
537#define FL_CONSTEXPR14 inline
553#if __cplusplus >= 201703L
555 #define FL_NO_DISCARD [[nodiscard]]
556#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
558 #define FL_NO_DISCARD __attribute__((warn_unused_result))
559#elif defined(FL_IS_WIN_MSVC)
561 #define FL_NO_DISCARD _Check_return_
564 #define FL_NO_DISCARD
581#if __cplusplus >= 201703L
583 #define FL_FALLTHROUGH [[fallthrough]]
584#elif defined(FL_IS_CLANG) || (defined(FL_IS_GCC) && FL_GCC_VERSION >= 700)
586 #define FL_FALLTHROUGH __attribute__((fallthrough))
589 #define FL_FALLTHROUGH
598#if __cplusplus >= 201103L
600 #define FL_NO_RETURN [[noreturn]]
601#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
603 #define FL_NO_RETURN __attribute__((noreturn))
604#elif defined(FL_IS_WIN_MSVC)
606 #define FL_NO_RETURN __declspec(noreturn)
620#if defined(FL_IS_CLANG)
622 #define FL_DEPRECATED(msg) __attribute__((deprecated(msg)))
624 #define FL_DEPRECATED_CLASS(msg)
625#elif defined(FL_IS_GCC)
627 #if FL_GCC_VERSION >= 405
628 #define FL_DEPRECATED(msg) __attribute__((deprecated(msg)))
629 #define FL_DEPRECATED_CLASS(msg) __attribute__((deprecated(msg)))
631 #define FL_DEPRECATED(msg) __attribute__((deprecated))
632 #define FL_DEPRECATED_CLASS(msg)
634#elif defined(FL_IS_WIN_MSVC)
636 #define FL_DEPRECATED(msg) __declspec(deprecated(msg))
637 #define FL_DEPRECATED_CLASS(msg) __declspec(deprecated(msg))
640 #define FL_DEPRECATED(msg)
641 #define FL_DEPRECATED_CLASS(msg)
645#define FASTLED_DEPRECATED(msg) FL_DEPRECATED(msg)
646#define FASTLED_DEPRECATED_CLASS(msg) FL_DEPRECATED_CLASS(msg)
658#if __cplusplus >= 202002L
660 #define FL_LIKELY(x) (x) [[likely]]
661 #define FL_UNLIKELY(x) (x) [[unlikely]]
662#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
664 #define FL_LIKELY(x) __builtin_expect(!!(x), 1)
665 #define FL_UNLIKELY(x) __builtin_expect(!!(x), 0)
668 #define FL_LIKELY(x) (x)
669 #define FL_UNLIKELY(x) (x)
684#if __cplusplus >= 202002L
686 #define FL_NO_UNIQUE_ADDRESS [[no_unique_address]]
687#elif defined(FL_IS_CLANG) || defined(FL_IS_GCC)
690 #define FL_NO_UNIQUE_ADDRESS
693 #define FL_NO_UNIQUE_ADDRESS
704#if defined(__cplusplus)
706 #if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
707 #define FL_RESTRICT_PARAM __restrict__
708 #elif defined(FL_IS_WIN_MSVC)
709 #define FL_RESTRICT_PARAM __restrict
711 #define FL_RESTRICT_PARAM
715 #define FL_RESTRICT_PARAM restrict
729#define FL_ASSUME_ALIGNED(ptr, N) (fl::assume_aligned<(N)>(ptr))
749#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
750 #define FL_PRETTY_FUNCTION __PRETTY_FUNCTION__
751#elif defined(FL_IS_WIN_MSVC)
752 #define FL_PRETTY_FUNCTION __FUNCSIG__
754 #define FL_PRETTY_FUNCTION __func__
759#define FL_MACRO_CONCAT_(a, b) a##b
760#define FL_MACRO_CONCAT(a, b) FL_MACRO_CONCAT_(a, b)
765#define FL_STRING_CONCAT(a, b) a b
773#define FL_UNIQUE_KEY FL_STRING_CONCAT(__FILE__ ":", FL_STRINGIFY(__LINE__))
779#define FL_UNIQUE_IDENTIFIER FL_MACRO_CONCAT(_fl_uid_, __LINE__)
781#if defined(__cplusplus)
783 #define FL_FUNCTION __func__
784#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
786 #define FL_FUNCTION __FUNCTION__
787#elif defined(FL_IS_WIN_MSVC)
789 #define FL_FUNCTION __FUNCTION__
792 #define FL_FUNCTION __func__
799#if defined(__SANITIZE_ADDRESS__)
800# define FL_HAS_SANITIZER_LSAN 1
801#elif defined(__has_feature)
802# if __has_feature(address_sanitizer)
803# define FL_HAS_SANITIZER_LSAN 1
807#ifndef FL_HAS_SANITIZER_LSAN
808# define FL_HAS_SANITIZER_LSAN 0
816#ifdef FASTLED_NO_FORCE_INLINE
817#define FASTLED_FORCE_INLINE inline
819#define FASTLED_FORCE_INLINE __attribute__((always_inline)) inline
824#ifdef FASTLED_NO_FORCE_INLINE
825#define FL_ALWAYS_INLINE static inline
827#define FL_ALWAYS_INLINE __attribute__((always_inline)) static inline
841#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
842__attribute__((always_inline))
843static inline void *_fl_builtin_memcpy(
void *dest,
const void *src,
845 return __builtin_memcpy(dest, src, n);
847#define FL_BUILTIN_MEMCPY(dest, src, n) _fl_builtin_memcpy(dest, src, n)
850#define FL_BUILTIN_MEMCPY(dest, src, n) __builtin_memcpy(dest, src, n)
859#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
860__attribute__((always_inline))
861static inline void *_fl_builtin_memset(
void *dest,
int val, __SIZE_TYPE__ n)
FL_NO_EXCEPT {
862 return __builtin_memset(dest, val, n);
864#define FL_BUILTIN_MEMSET(dest, val, n) _fl_builtin_memset(dest, val, n)
867#define FL_BUILTIN_MEMSET(dest, val, n) __builtin_memset(dest, val, n)
884#ifndef FASTLED_REGISTER
887#if (defined(_MSVC_LANG) ? _MSVC_LANG : __cplusplus) < 201703L
888 #define FASTLED_REGISTER register
891 #define FASTLED_REGISTER
900#ifndef FASTLED_UNUSED
901#define FASTLED_UNUSED(x) (void)(x)
905#define FL_UNUSED(x) (void)(x)
908#ifndef FL_UNUSED_FUNCTION
909#define FL_UNUSED_FUNCTION __attribute__((unused))
917#define VIRTUAL_IF_NOT_AVR
918#define OVERRIDE_IF_NOT_AVR
920#define VIRTUAL_IF_NOT_AVR virtual
921#define OVERRIDE_IF_NOT_AVR override
925#define AVR_DISALLOWED \
926 [[deprecated("This function or class is deprecated on AVR.")]]
928#define AVR_DISALLOWED
Alignment macros and utilities for FastLED.
#define FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
#define FL_DISABLE_WARNING_DEPRECATED_REGISTER