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
153#define FL_ALLOW_PLATFORM_PRAGMA
156#define FL_DIAGNOSTIC_PUSH FL_DISABLE_WARNING_PUSH
157#define FL_DIAGNOSTIC_POP FL_DISABLE_WARNING_POP
158#define FL_DIAGNOSTIC_IGNORE_C14_EXTENSIONS FL_DISABLE_WARNING_C14_EXTENSIONS
161#if defined(FL_IS_CLANG)
162 #define FL_FAST_MATH_BEGIN \
163 _Pragma("clang diagnostic push") \
164 _Pragma("STDC FP_CONTRACT ON")
166 #define FL_FAST_MATH_END _Pragma("clang diagnostic pop")
168#elif defined(FL_IS_GCC)
169 #define FL_FAST_MATH_BEGIN \
170 _Pragma("GCC push_options") \
171 _Pragma("GCC optimize (\"fast-math\")") \
172 _Pragma("GCC optimize (\"tree-vectorize\")") \
173 _Pragma("GCC optimize (\"unroll-loops\")")
175 #define FL_FAST_MATH_END _Pragma("GCC pop_options")
177#elif defined(FL_IS_WIN_MSVC)
178 #define FL_FAST_MATH_BEGIN __pragma(float_control(precise, off))
179 #define FL_FAST_MATH_END __pragma(float_control(precise, on))
181 #define FL_FAST_MATH_BEGIN
182 #define FL_FAST_MATH_END
192#if defined(FL_IS_CLANG)
193 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN \
194 _Pragma("clang attribute push(__attribute__((hot)), apply_to = function)")
195 #define FL_OPTIMIZATION_LEVEL_O3_END \
196 _Pragma("clang attribute pop")
198#elif defined(FL_IS_GCC)
199 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN \
200 _Pragma("GCC push_options") \
201 _Pragma("GCC optimize (\"O3\")")
203 #define FL_OPTIMIZATION_LEVEL_O3_END _Pragma("GCC pop_options")
205 #define FL_OPTIMIZATION_LEVEL_O3_BEGIN
206 #define FL_OPTIMIZATION_LEVEL_O3_END
210#if defined(FL_IS_CLANG)
211 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN \
212 _Pragma("clang diagnostic push")
214 #define FL_OPTIMIZATION_LEVEL_O0_END _Pragma("clang diagnostic pop")
216#elif defined(FL_IS_GCC)
217 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN \
218 _Pragma("GCC push_options") \
219 _Pragma("GCC optimize (\"O0\")")
221 #define FL_OPTIMIZATION_LEVEL_O0_END _Pragma("GCC pop_options")
223 #define FL_OPTIMIZATION_LEVEL_O0_BEGIN
224 #define FL_OPTIMIZATION_LEVEL_O0_END
231#ifndef FL_TIMING_OPT_LEVEL
232#define FL_TIMING_OPT_LEVEL 2
235#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
238 #if FL_TIMING_OPT_LEVEL == 0
239 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O0\")")
240 #elif FL_TIMING_OPT_LEVEL == 1
241 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O1\")")
242 #elif FL_TIMING_OPT_LEVEL == 3
243 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O3\")")
246 #define _FL_TIMING_OPT_PRAGMA _Pragma("GCC optimize(\"O2\")")
249 #define FL_BEGIN_OPTIMIZE_FOR_EXACT_TIMING \
250 _Pragma("GCC push_options") \
251 _FL_TIMING_OPT_PRAGMA \
252 _Pragma("GCC optimize(\"-fno-lto\")") \
253 _Pragma("GCC optimize(\"-fno-schedule-insns\")") \
254 _Pragma("GCC optimize(\"-fno-schedule-insns2\")") \
255 _Pragma("GCC optimize(\"-fno-reorder-blocks\")") \
256 _Pragma("GCC optimize(\"-fno-tree-vectorize\")") \
257 _Pragma("GCC optimize(\"-fno-tree-reassoc\")") \
258 _Pragma("GCC optimize(\"-fno-unroll-loops\")")
260 #define FL_END_OPTIMIZE_FOR_EXACT_TIMING \
261 _Pragma("GCC pop_options")
263 #define FL_BEGIN_OPTIMIZE_FOR_EXACT_TIMING
264 #define FL_END_OPTIMIZE_FOR_EXACT_TIMING
270#if defined(FL_IS_GCC)
271 #define FL_OPTIMIZE_FUNCTION __attribute__((optimize("O3")))
272 #define FL_OPTIMIZE_O2 __attribute__((optimize("O2")))
273#elif defined(FL_IS_CLANG)
274 #define FL_OPTIMIZE_FUNCTION __attribute__((hot))
275 #define FL_OPTIMIZE_O2 __attribute__((hot))
277 #define FL_OPTIMIZE_FUNCTION
278 #define FL_OPTIMIZE_O2
282#define FL_LINK_WEAK __attribute__((weak))
289#if defined(FL_IS_AVR)
292#elif defined(FL_IS_GCC)
294 #if FL_GCC_VERSION >= 800
295 #define FL_UNROLL(N) _Pragma(FL_STRINGIFY(GCC unroll N))
300#elif defined(FL_IS_CLANG)
302 #define FL_UNROLL(N) _Pragma(FL_STRINGIFY(unroll N))
309#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
310 #define FL_MAYBE_UNUSED __attribute__((unused))
312 #define FL_MAYBE_UNUSED
327#if defined(FL_IS_AVR)
328 #define FL_NO_INLINE_IF_AVR __attribute__((noinline))
330 #define FL_NO_INLINE_IF_AVR
342#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
343 #define FL_NO_INLINE __attribute__((noinline))
344#elif defined(FL_IS_WIN_MSVC)
345 #define FL_NO_INLINE __declspec(noinline)
352#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
353 #define FL_CONSTRUCTOR __attribute__((constructor))
354#elif defined(FL_IS_WIN_MSVC)
356 #define FL_CONSTRUCTOR
357 #pragma message("Warning: FL_CONSTRUCTOR not fully supported on MSVC")
359 #define FL_CONSTRUCTOR
365 #if defined(FL_IS_WASM)
368#include <emscripten.h>
371 #define FL_KEEP_ALIVE EMSCRIPTEN_KEEPALIVE
372 #elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
374 #define FL_KEEP_ALIVE __attribute__((used))
375 #elif defined(FL_IS_WIN_MSVC)
379 #define FL_KEEP_ALIVE __pragma(optimize("", off)) __pragma(optimize("", on))
382 #define FL_KEEP_ALIVE
408#if defined(FL_IS_WIN_MSVC)
409 #pragma section(".CRT$XCU", read)
411 #define FL_INIT(wrapper_name, func) \
412 namespace static_init { \
413 static void wrapper_name() { func(); } \
414 __declspec(allocate(".CRT$XCU")) \
415 static void (*wrapper_name##_ptr)(void) = wrapper_name; \
418#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
419 #define FL_INIT(wrapper_name, func) \
420 namespace static_init { \
421 FL_CONSTRUCTOR FL_KEEP_ALIVE \
422 void wrapper_name() { func(); } \
426 #error Unsupported compiler for FL_INIT
444#define FL_RUN_ONCE(code) \
446 static bool fl_run_once_flag = false; \
447 if (!fl_run_once_flag) { \
448 fl_run_once_flag = true; \
455 #define FL_EXTERN_C_BEGIN extern "C" {
456 #define FL_EXTERN_C_END }
457 #define FL_EXTERN_C extern "C"
459 #define FL_EXTERN_C_BEGIN
460 #define FL_EXTERN_C_END
488#define FL_INLINE_CONSTEXPR inline constexpr
494#if __cplusplus >= 201402L
495#define FL_CONSTEXPR14 constexpr
497#define FL_CONSTEXPR14 inline
513#if __cplusplus >= 201703L
515 #define FL_NODISCARD [[nodiscard]]
516#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
518 #define FL_NODISCARD __attribute__((warn_unused_result))
519#elif defined(FL_IS_WIN_MSVC)
521 #define FL_NODISCARD _Check_return_
541#if __cplusplus >= 201703L
543 #define FL_FALLTHROUGH [[fallthrough]]
544#elif defined(FL_IS_CLANG) || (defined(FL_IS_GCC) && FL_GCC_VERSION >= 700)
546 #define FL_FALLTHROUGH __attribute__((fallthrough))
549 #define FL_FALLTHROUGH
558#if __cplusplus >= 201103L
560 #define FL_NORETURN [[noreturn]]
561#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
563 #define FL_NORETURN __attribute__((noreturn))
564#elif defined(FL_IS_WIN_MSVC)
566 #define FL_NORETURN __declspec(noreturn)
580#if defined(FL_IS_CLANG)
582 #define FL_DEPRECATED(msg) __attribute__((deprecated(msg)))
584 #define FL_DEPRECATED_CLASS(msg)
585#elif defined(FL_IS_GCC)
587 #if FL_GCC_VERSION >= 405
588 #define FL_DEPRECATED(msg) __attribute__((deprecated(msg)))
589 #define FL_DEPRECATED_CLASS(msg) __attribute__((deprecated(msg)))
591 #define FL_DEPRECATED(msg) __attribute__((deprecated))
592 #define FL_DEPRECATED_CLASS(msg)
594#elif defined(FL_IS_WIN_MSVC)
596 #define FL_DEPRECATED(msg) __declspec(deprecated(msg))
597 #define FL_DEPRECATED_CLASS(msg) __declspec(deprecated(msg))
600 #define FL_DEPRECATED(msg)
601 #define FL_DEPRECATED_CLASS(msg)
605#define FASTLED_DEPRECATED(msg) FL_DEPRECATED(msg)
606#define FASTLED_DEPRECATED_CLASS(msg) FL_DEPRECATED_CLASS(msg)
618#if __cplusplus >= 202002L
620 #define FL_LIKELY(x) (x) [[likely]]
621 #define FL_UNLIKELY(x) (x) [[unlikely]]
622#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
624 #define FL_LIKELY(x) __builtin_expect(!!(x), 1)
625 #define FL_UNLIKELY(x) __builtin_expect(!!(x), 0)
628 #define FL_LIKELY(x) (x)
629 #define FL_UNLIKELY(x) (x)
644#if __cplusplus >= 202002L
646 #define FL_NO_UNIQUE_ADDRESS [[no_unique_address]]
647#elif defined(FL_IS_CLANG) || defined(FL_IS_GCC)
650 #define FL_NO_UNIQUE_ADDRESS
653 #define FL_NO_UNIQUE_ADDRESS
664#if defined(__cplusplus)
666 #if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
667 #define FL_RESTRICT_PARAM __restrict__
668 #elif defined(FL_IS_WIN_MSVC)
669 #define FL_RESTRICT_PARAM __restrict
671 #define FL_RESTRICT_PARAM
675 #define FL_RESTRICT_PARAM restrict
689#define FL_ASSUME_ALIGNED(ptr, N) (fl::assume_aligned<(N)>(ptr))
709#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
710 #define FL_PRETTY_FUNCTION __PRETTY_FUNCTION__
711#elif defined(FL_IS_WIN_MSVC)
712 #define FL_PRETTY_FUNCTION __FUNCSIG__
714 #define FL_PRETTY_FUNCTION __func__
719#define FL_MACRO_CONCAT_(a, b) a##b
720#define FL_MACRO_CONCAT(a, b) FL_MACRO_CONCAT_(a, b)
725#define FL_STRING_CONCAT(a, b) a b
733#define FL_UNIQUE_KEY FL_STRING_CONCAT(__FILE__ ":", FL_STRINGIFY(__LINE__))
739#define FL_UNIQUE_IDENTIFIER FL_MACRO_CONCAT(_fl_uid_, __LINE__)
741#if defined(__cplusplus)
743 #define FL_FUNCTION __func__
744#elif defined(FL_IS_GCC) || defined(FL_IS_CLANG)
746 #define FL_FUNCTION __FUNCTION__
747#elif defined(FL_IS_WIN_MSVC)
749 #define FL_FUNCTION __FUNCTION__
752 #define FL_FUNCTION __func__
759#if defined(__SANITIZE_ADDRESS__)
760# define FL_HAS_SANITIZER_LSAN 1
761#elif defined(__has_feature)
762# if __has_feature(address_sanitizer)
763# define FL_HAS_SANITIZER_LSAN 1
767#ifndef FL_HAS_SANITIZER_LSAN
768# define FL_HAS_SANITIZER_LSAN 0
776#ifdef FASTLED_NO_FORCE_INLINE
777#define FASTLED_FORCE_INLINE inline
779#define FASTLED_FORCE_INLINE __attribute__((always_inline)) inline
784#ifdef FASTLED_NO_FORCE_INLINE
785#define FL_ALWAYS_INLINE static inline
787#define FL_ALWAYS_INLINE __attribute__((always_inline)) static inline
801#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
802__attribute__((always_inline))
803static inline void *_fl_builtin_memcpy(
void *dest,
const void *src,
805 return __builtin_memcpy(dest, src, n);
807#define FL_BUILTIN_MEMCPY(dest, src, n) _fl_builtin_memcpy(dest, src, n)
810#define FL_BUILTIN_MEMCPY(dest, src, n) __builtin_memcpy(dest, src, n)
819#if defined(FL_IS_GCC) || defined(FL_IS_CLANG)
820__attribute__((always_inline))
821static inline void *_fl_builtin_memset(
void *dest,
int val, __SIZE_TYPE__ n)
FL_NOEXCEPT {
822 return __builtin_memset(dest, val, n);
824#define FL_BUILTIN_MEMSET(dest, val, n) _fl_builtin_memset(dest, val, n)
827#define FL_BUILTIN_MEMSET(dest, val, n) __builtin_memset(dest, val, n)
844#ifndef FASTLED_REGISTER
847#if (defined(_MSVC_LANG) ? _MSVC_LANG : __cplusplus) < 201703L
848 #define FASTLED_REGISTER register
851 #define FASTLED_REGISTER
860#ifndef FASTLED_UNUSED
861#define FASTLED_UNUSED(x) (void)(x)
865#define FL_UNUSED(x) (void)(x)
868#ifndef FL_UNUSED_FUNCTION
869#define FL_UNUSED_FUNCTION __attribute__((unused))
877#define VIRTUAL_IF_NOT_AVR
878#define OVERRIDE_IF_NOT_AVR
880#define VIRTUAL_IF_NOT_AVR virtual
881#define OVERRIDE_IF_NOT_AVR override
885#define AVR_DISALLOWED \
886 [[deprecated("This function or class is deprecated on AVR.")]]
888#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