FastLED 3.9.15
Loading...
Searching...
No Matches
bit_cast.h
Go to the documentation of this file.
1#pragma once
2
3// What is bit cast?
4// Bit cast is a safe version of reinterpret_cast that is robust against strict aliasing rules
5// that are used in aggressive compiler optimizations.
6//
7// Uses memcpy internally which is the only standard-compliant way to type-pun safely.
8// Compilers recognize this pattern and optimize it to a single register move.
9
10#include "fl/stl/type_traits.h"
11#include "fl/stl/cstring.h"
12#include "fl/stl/int.h"
13#include "fl/stl/noexcept.h"
15
16namespace fl {
17
18//-------------------------------------------------------------------------------
19// bit_cast - Safe type-punning utility (C++20 std::bit_cast equivalent)
20//-------------------------------------------------------------------------------
21
22// Helper trait for bitcast - check if a type can be bitcast (relax POD requirement)
23// Trivially copyable types are safe for bit_cast (matches C++20 std::bit_cast requirements)
24template <typename T>
31
32// Specializations for const types
33template <typename T>
34struct is_bitcast_compatible<const T> {
35 static constexpr bool value = is_bitcast_compatible<T>::value;
36};
37
38// Specializations for pointer types
39template <typename T>
41 static constexpr bool value = true;
42};
43
44// C++20-style bit_cast for safe type reinterpretation
45// Uses memcpy which is the standard-compliant way to type-pun safely.
46// Compilers recognize this pattern and optimize it to a single register move.
47template <typename To, typename From>
48To bit_cast(const From& from) FL_NOEXCEPT {
49 FL_STATIC_ASSERT(sizeof(To) == sizeof(From), "bit_cast: types must have the same size");
50 FL_STATIC_ASSERT(is_bitcast_compatible<To>::value, "bit_cast: destination type must be bitcast compatible");
51 FL_STATIC_ASSERT(is_bitcast_compatible<From>::value, "bit_cast: source type must be bitcast compatible");
52
53 To to;
54 fl::memcpy(&to, &from, sizeof(To));
55 return to;
56}
57
58// Overload for pointer types - converts storage pointer to typed pointer safely
59template <typename To>
60To* bit_cast_ptr(void* storage) FL_NOEXCEPT {
61 return bit_cast<To*>(storage);
62}
63
64template <typename To>
65const To* bit_cast_ptr(const void* storage) FL_NOEXCEPT {
66 return bit_cast<const To*>(storage);
67}
68
69// Additional utility for uptr conversions (common pattern in the codebase)
70template <typename T>
71uptr ptr_to_int(T* ptr) FL_NOEXCEPT {
72 return bit_cast<uptr>(ptr);
73}
74
75template <typename T>
77 return bit_cast<T*>(value);
78}
79
80//-------------------------------------------------------------------------------
81// fl::reinterpret_cast - Wrapper that delegates to bit_cast for safety
82//-------------------------------------------------------------------------------
83// This provides a drop-in replacement for reinterpret_cast that uses bit_cast
84// internally. Use this when you need reinterpret_cast semantics but want the
85// safety guarantees of bit_cast against strict aliasing violations.
86
87template <typename To, typename From>
88To reinterpret_cast_(const From& from) FL_NOEXCEPT { // ok reinterpret cast - defining the wrapper
89 return bit_cast<To>(from);
90}
91
92} // namespace fl
void * memcpy(void *dest, const void *src, size_t n) FL_NOEXCEPT
constexpr int type_rank< T >::value
T * int_to_ptr(uptr value) FL_NOEXCEPT
Definition bit_cast.h:76
uptr ptr_to_int(T *ptr) FL_NOEXCEPT
Definition bit_cast.h:71
To reinterpret_cast_(const From &from) FL_NOEXCEPT
Definition bit_cast.h:88
To bit_cast(const From &from) FL_NOEXCEPT
Definition bit_cast.h:48
To * bit_cast_ptr(void *storage) FL_NOEXCEPT
Definition bit_cast.h:60
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_STATIC_ASSERT(...)
#define FL_NOEXCEPT
Portable compile-time assertion wrapper.
static constexpr bool value
Definition bit_cast.h:41
static constexpr bool value
Definition bit_cast.h:35
static constexpr bool value
Definition bit_cast.h:26