diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 4dcd44a574..6d7ae564e8 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -224,8 +224,14 @@ template class FixedVector { } } - // Clear the vector (reset size to 0, keep capacity) - void clear() { size_ = 0; } + // Clear the vector (destroy all elements, reset size to 0, keep capacity) + void clear() { + // Manually destroy all elements + for (size_t i = 0; i < size_; i++) { + data_[i].~T(); + } + size_ = 0; + } // Shrink capacity to fit current size (frees all memory) void shrink_to_fit() { @@ -244,17 +250,34 @@ template class FixedVector { } } - /// Construct element in place and return reference + /// Add element by move without bounds checking /// Caller must ensure sufficient capacity was allocated via init() - T &emplace_back() { + /// Silently ignores pushes beyond capacity (no exception or assertion) + void push_back(T &&value) { if (size_ < capacity_) { - return data_[size_++]; + // Use placement new to move-construct the object in pre-allocated memory + new (&data_[size_]) T(std::move(value)); + size_++; } - // Should never happen with proper init() - return last element to avoid crash - return data_[capacity_ - 1]; } - /// Access last element + /// Emplace element without bounds checking - constructs in-place + /// Caller must ensure sufficient capacity was allocated via init() + /// Returns reference to the newly constructed element + /// Silently ignores emplaces beyond capacity (returns reference to last element) + T &emplace_back() { + if (size_ < capacity_) { + // Use placement new to default-construct the object in pre-allocated memory + new (&data_[size_]) T(); + size_++; + return data_[size_ - 1]; + } + // Beyond capacity - return reference to last element to avoid crash + return data_[size_ - 1]; + } + + /// Access last element (no bounds checking - matches std::vector behavior) + /// Caller must ensure vector is not empty (size() > 0) T &back() { return data_[size_ - 1]; } const T &back() const { return data_[size_ - 1]; }