fixes, safety

This commit is contained in:
J. Nick Koston
2026-03-22 11:01:36 -10:00
parent 7997743b15
commit c93c701e0a
2 changed files with 11 additions and 22 deletions
+6 -21
View File
@@ -2228,33 +2228,18 @@ template<std::totally_ordered T, comparable_with<T> U> T clamp_at_most(T value,
* This struct is designed to replace dynamic heap allocations (`new T(...)`) for
* global or static singletons within ESPHome, preventing memory fragmentation.
* The underlying object must be explicitly constructed using placement new
* before access.
* before access. No destructor is called — this is intentional since ESPHome
* singletons live for the entire device lifetime.
*/
template<class T> struct PlacementStorage {
/// @brief Raw byte storage, strictly aligned for type T.
alignas(T) unsigned char data[sizeof(T)];
/**
* @brief Safely retrieves a pointer to the constructed object.
* @return T* Pointer to the underlying object.
*/
constexpr T *get() { return reinterpret_cast<T *>(data); }
/// @brief Retrieves a pointer to the constructed object.
T *get() { return std::launder(reinterpret_cast<T *>(data)); }
/**
* @brief Safely retrieves a const pointer to the constructed object.
* @return const T* Const pointer to the underlying object.
*/
constexpr const T *get() const { return reinterpret_cast<const T *>(data); }
/// @brief Member access operator pointing to the underlying object.
constexpr T *operator->() { return get(); }
/// @brief Const member access operator pointing to the underlying object.
constexpr const T *operator->() const { return get(); }
/// @brief Dereference operator yielding a reference to the underlying object.
constexpr T &operator*() { return *get(); }
/// @brief Const dereference operator yielding a const reference to the underlying object.
constexpr const T &operator*() const { return *get(); }
/// @brief Retrieves a const pointer to the constructed object.
const T *get() const { return std::launder(reinterpret_cast<const T *>(data)); }
};
/// @name Internal functions
+5 -1
View File
@@ -594,7 +594,11 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
# for brace-enclosed initializer lists passed to variadic templates.
call_str = rhs_str[4:] # Strip "new " from "new Type<T>(args)"
the_type = id_.type if id_.type is not None else call_str.split("(")[0].strip()
the_type = (
id_.type
if id_.type is not None
else call_str.split("(", maxsplit=1)[0].strip()
)
storage_name = f"{id_.id}_storage_"
# Declare the static PlacementStorage