FastLED 3.9.7
Loading...
Searching...
No Matches
template_magic.h
1#pragma once
2
3/*
4Provides eanble_if and is_derived for compilers before C++14.
5*/
6
7#include <stdint.h>
8
9#include "fl/namespace.h"
10
11namespace fl { // mandatory namespace to prevent name collision with std::enable_if.
12
13// Define enable_if for SFINAE
14template <bool Condition, typename T = void>
15struct enable_if {};
16
17// Specialization for true condition
18template <typename T>
19struct enable_if<true, T> {
20 using type = T;
21};
22
23// if enable_if<Condition, T> is true, then there will be a member type
24// called type. Otherwise it will not exist. This is (ab)used to enable
25// constructors and other functions based on template parameters. If there
26// is no member type, then the compiler will not fail to bind to the target
27// function or operation.
28template <bool Condition, typename T = void>
29using enable_if_t = typename enable_if<Condition, T>::type;
30
31// Define is_base_of to check inheritance relationship
32template <typename Base, typename Derived>
33struct is_base_of {
34private:
35 typedef uint8_t yes;
36 typedef uint16_t no;
37 static yes test(Base*); // Matches if Derived is convertible to Base*
38 static no test(...); // Fallback if not convertible
39 enum {
40 kSizeDerived = sizeof(test(static_cast<Derived*>(nullptr))),
41 };
42public:
43 static constexpr bool value = (kSizeDerived == sizeof(yes));
44};
45
46// Define is_base_of_v for compatibility with pre-C++14
47// Replaced variable template with a constant static member
48template <typename Base, typename Derived>
50 static constexpr bool value = is_base_of<Base, Derived>::value;
51};
52
53// Define is_same trait
54template <typename T, typename U>
55struct is_same {
56 static constexpr bool value = false;
57};
58
59// Specialization for when T and U are the same type
60template <typename T>
61struct is_same<T, T> {
62 static constexpr bool value = true;
63};
64
65// Define is_same_v for compatibility with variable templates
66template <typename T, typename U>
68 static constexpr bool value = is_same<T, U>::value;
69};
70
71// Define is_pod trait (basic implementation)
72template <typename T>
73struct is_pod {
74 static constexpr bool value = false; // Default to false for safety
75};
76
77// Specializations for fundamental types
78template<> struct is_pod<bool> { static constexpr bool value = true; };
79template<> struct is_pod<char> { static constexpr bool value = true; };
80template<> struct is_pod<signed char> { static constexpr bool value = true; };
81template<> struct is_pod<unsigned char> { static constexpr bool value = true; };
82template<> struct is_pod<short> { static constexpr bool value = true; };
83template<> struct is_pod<unsigned short> { static constexpr bool value = true; };
84template<> struct is_pod<int> { static constexpr bool value = true; };
85template<> struct is_pod<unsigned int> { static constexpr bool value = true; };
86template<> struct is_pod<long> { static constexpr bool value = true; };
87template<> struct is_pod<unsigned long> { static constexpr bool value = true; };
88template<> struct is_pod<long long> { static constexpr bool value = true; };
89template<> struct is_pod<unsigned long long> { static constexpr bool value = true; };
90template<> struct is_pod<float> { static constexpr bool value = true; };
91template<> struct is_pod<double> { static constexpr bool value = true; };
92template<> struct is_pod<long double> { static constexpr bool value = true; };
93
94// Helper struct for is_pod_v (similar to other _v helpers)
95template <typename T>
97 static constexpr bool value = is_pod<T>::value;
98};
99
100// This uses template magic to maybe generate a type for the given condition. If that type
101// doesn't exist then a type will fail to be generated, and the compiler will skip the
102// consideration of a target function. This is useful for enabling template constructors
103// that only become available if the class can be upcasted to the desired type.
104//
105// Example:
106// This is an optional upcasting constructor for a Ref<T>. If the type U is not derived from T
107// then the constructor will not be generated, and the compiler will skip it.
108//
109// template <typename U, typename = fl::is_derived<T, U>>
110// Ref(const Ref<U>& refptr) : referent_(refptr.get());
111template <typename Base, typename Derived>
112using is_derived = enable_if_t<is_base_of<Base, Derived>::value>;
113
114} // namespace fl
115
116
117
118
119
120// For comparison operators that return bool against pod data. The class obj will need
121// to supply the comparison operator for the pod type.
122// This example will show how to define a comparison operator for a class that can be
123// compared against a pod type.
124// Example:
125// FASTLED_DEFINE_POD_COMPARISON_OPERATOR(Myclass, >=) will allow MyClass to be compared
126// MyClass obj;
127// return obj >= 0;
128#define FASTLED_DEFINE_POD_COMPARISON_OPERATOR(CLASS, OP) \
129template <typename T, typename U> \
130typename fl::enable_if<fl::is_same<U, CLASS>::value && fl::is_pod<T>::value, bool>::type \
131operator OP (const T& pod, const CLASS& obj) { return pod OP obj; } \
132template <typename T> \
133typename fl::enable_if<fl::is_pod<T>::value, bool>::type \
134operator OP (const CLASS& obj, const T& pod) { return obj OP pod; }
Implements the FastLED namespace macros.
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16