mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Optimize TemplatableValue memory (#9202)
This commit is contained in:
		| @@ -27,20 +27,67 @@ template<typename T, typename... X> class TemplatableValue { | |||||||
|  public: |  public: | ||||||
|   TemplatableValue() : type_(NONE) {} |   TemplatableValue() : type_(NONE) {} | ||||||
|  |  | ||||||
|   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> |   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> TemplatableValue(F value) : type_(VALUE) { | ||||||
|   TemplatableValue(F value) : type_(VALUE), value_(std::move(value)) {} |     new (&this->value_) T(std::move(value)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> |   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> TemplatableValue(F f) : type_(LAMBDA) { | ||||||
|   TemplatableValue(F f) : type_(LAMBDA), f_(f) {} |     this->f_ = new std::function<T(X...)>(std::move(f)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Copy constructor | ||||||
|  |   TemplatableValue(const TemplatableValue &other) : type_(other.type_) { | ||||||
|  |     if (type_ == VALUE) { | ||||||
|  |       new (&this->value_) T(other.value_); | ||||||
|  |     } else if (type_ == LAMBDA) { | ||||||
|  |       this->f_ = new std::function<T(X...)>(*other.f_); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Move constructor | ||||||
|  |   TemplatableValue(TemplatableValue &&other) noexcept : type_(other.type_) { | ||||||
|  |     if (type_ == VALUE) { | ||||||
|  |       new (&this->value_) T(std::move(other.value_)); | ||||||
|  |     } else if (type_ == LAMBDA) { | ||||||
|  |       this->f_ = other.f_; | ||||||
|  |       other.f_ = nullptr; | ||||||
|  |     } | ||||||
|  |     other.type_ = NONE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Assignment operators | ||||||
|  |   TemplatableValue &operator=(const TemplatableValue &other) { | ||||||
|  |     if (this != &other) { | ||||||
|  |       this->~TemplatableValue(); | ||||||
|  |       new (this) TemplatableValue(other); | ||||||
|  |     } | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   TemplatableValue &operator=(TemplatableValue &&other) noexcept { | ||||||
|  |     if (this != &other) { | ||||||
|  |       this->~TemplatableValue(); | ||||||
|  |       new (this) TemplatableValue(std::move(other)); | ||||||
|  |     } | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ~TemplatableValue() { | ||||||
|  |     if (type_ == VALUE) { | ||||||
|  |       this->value_.~T(); | ||||||
|  |     } else if (type_ == LAMBDA) { | ||||||
|  |       delete this->f_; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   bool has_value() { return this->type_ != NONE; } |   bool has_value() { return this->type_ != NONE; } | ||||||
|  |  | ||||||
|   T value(X... x) { |   T value(X... x) { | ||||||
|     if (this->type_ == LAMBDA) { |     if (this->type_ == LAMBDA) { | ||||||
|       return this->f_(x...); |       return (*this->f_)(x...); | ||||||
|     } |     } | ||||||
|     // return value also when none |     // return value also when none | ||||||
|     return this->value_; |     return this->type_ == VALUE ? this->value_ : T{}; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   optional<T> optional_value(X... x) { |   optional<T> optional_value(X... x) { | ||||||
| @@ -58,14 +105,16 @@ template<typename T, typename... X> class TemplatableValue { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   enum { |   enum : uint8_t { | ||||||
|     NONE, |     NONE, | ||||||
|     VALUE, |     VALUE, | ||||||
|     LAMBDA, |     LAMBDA, | ||||||
|   } type_; |   } type_; | ||||||
|  |  | ||||||
|   T value_{}; |   union { | ||||||
|   std::function<T(X...)> f_{}; |     T value_; | ||||||
|  |     std::function<T(X...)> *f_; | ||||||
|  |   }; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /** Base class for all automation conditions. | /** Base class for all automation conditions. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user