FastLED 3.9.15
Loading...
Searching...
No Matches
template_magic.h
Go to the documentation of this file.
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>
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>
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.
enable_if_t< is_base_of< Base, Derived >::value > is_derived
typename enable_if< Condition, T >::type enable_if_t
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16
static constexpr bool value
static no test(...)
static constexpr bool value
static yes test(Base *)
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value
static constexpr bool value