diff --git a/components/esp_matter/esp_matter_attribute_utils.h b/components/esp_matter/esp_matter_attribute_utils.h index 49d15dfb5..188e24246 100644 --- a/components/esp_matter/esp_matter_attribute_utils.h +++ b/components/esp_matter/esp_matter_attribute_utils.h @@ -153,12 +153,38 @@ typedef struct esp_matter_attr_bounds { template class nullable { + +/** NOTE: GetNullValue is taken from src/app/util/attribute-storage-null-handling.h */ +private: + template ::value, int> = 0> + static constexpr T GetNullValue() + { + return std::numeric_limits::quiet_NaN(); + } + + template ::value, int> = 0> + static constexpr T GetNullValue() + { + return std::is_signed::value ? std::numeric_limits::min() : std::numeric_limits::max(); + } + + template ::value, int> = 0> + static constexpr T GetNullValue() + { + static_assert(!std::is_signed>::value, "Enums must be unsigned"); + return static_cast(std::numeric_limits>::max()); + } + public: nullable(T value) { - assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); - val = value; + if (chip::app::NumericAttributeTraits::IsNullValue(value)) { + chip::app::NumericAttributeTraits::SetNull(val); + } else { + val = value; + } } + nullable() { chip::app::NumericAttributeTraits::SetNull(val); @@ -166,8 +192,12 @@ public: T value() { - assert(!is_null()); - return val; + if (is_null()) { + return GetNullValue(); + } else { + return val; + } + } T value_or(T ret) @@ -182,8 +212,11 @@ public: void operator=(T value) { - assert(!chip::app::NumericAttributeTraits::IsNullValue(value)); - this->val = value; + if (chip::app::NumericAttributeTraits::IsNullValue(value)) { + chip::app::NumericAttributeTraits::SetNull(this->val); + } else { + this->val = value; + } } void operator=(std::nullptr_t)