[core] Use is_trivially_copyable_v for TemplatableStorage selection

TemplatableStorage now selects TemplatableFn (4 bytes) for trivially
copyable types and TemplatableValue (8 bytes) for non-trivial types.

This automatically handles std::string (PROGMEM support) and
std::vector<uint8_t> (raw value assignment from C++) without
special-casing.

Reverts esp32_ble_server back to TEMPLATABLE_VALUE macro since
std::vector<uint8_t> now correctly gets TemplatableValue.
This commit is contained in:
J. Nick Koston
2026-04-07 19:51:52 -10:00
parent e22ded3803
commit ee83f525c4
2 changed files with 8 additions and 11 deletions
@@ -69,8 +69,7 @@ class BLECharacteristicSetValueActionManager {
template<typename... Ts> class BLECharacteristicSetValueAction : public Action<Ts...> {
public:
BLECharacteristicSetValueAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
// TemplatableValue (not TemplatableFn) — also set from C++ with raw values (initializer_list, ByteBuffer)
template<typename V> void set_buffer(V buffer) { this->buffer_ = buffer; }
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
void set_buffer(std::initializer_list<uint8_t> buffer) { this->buffer_ = std::vector<uint8_t>(buffer); }
void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
void play(const Ts &...x) override {
@@ -91,7 +90,6 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
protected:
BLECharacteristic *parent_;
TemplatableValue<std::vector<uint8_t>, Ts...> buffer_{};
};
#endif // USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
@@ -117,15 +115,13 @@ template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts.
template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...> {
public:
BLEDescriptorSetValueAction(BLEDescriptor *descriptor) : parent_(descriptor) {}
// TemplatableValue (not TemplatableFn) — also set from C++ with raw values (initializer_list, ByteBuffer)
template<typename V> void set_buffer(V buffer) { this->buffer_ = buffer; }
TEMPLATABLE_VALUE(std::vector<uint8_t>, buffer)
void set_buffer(std::initializer_list<uint8_t> buffer) { this->buffer_ = std::vector<uint8_t>(buffer); }
void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
void play(const Ts &...x) override { this->parent_->set_value(this->buffer_.value(x...)); }
protected:
BLEDescriptor *parent_;
TemplatableValue<std::vector<uint8_t>, Ts...> buffer_{};
};
#endif // USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
+6 -5
View File
@@ -80,11 +80,12 @@ template<typename T, typename... X> class TemplatableFn {
// Forward declaration for TemplatableValue (string specialization needs it)
template<typename T, typename... X> class TemplatableValue;
/// TemplatableStorage uses TemplatableValue (8 bytes) for the TEMPLATABLE_VALUE macro.
/// Many components pass raw constants to macro-generated setters from codegen, so the
/// macro must accept both raw values and function pointers. Components that want the
/// 4-byte savings can use TemplatableFn directly instead of the macro.
template<typename T, typename... X> using TemplatableStorage = TemplatableValue<T, X...>;
/// Selects TemplatableFn (4 bytes) for trivially copyable types, TemplatableValue (8 bytes) otherwise.
/// Non-trivial types (std::string, std::vector<uint8_t>, etc.) need TemplatableValue for raw value
/// storage, PROGMEM/FlashStringHelper support (strings), and proper copy/move/destruction.
template<typename T, typename... X>
using TemplatableStorage =
std::conditional_t<std::is_trivially_copyable_v<T>, TemplatableFn<T, X...>, TemplatableValue<T, X...>>;
#define TEMPLATABLE_VALUE_(type, name) \
protected: \