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: | ||||
|   TemplatableValue() : type_(NONE) {} | ||||
|  | ||||
|   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> | ||||
|   TemplatableValue(F value) : type_(VALUE), value_(std::move(value)) {} | ||||
|   template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0> TemplatableValue(F value) : type_(VALUE) { | ||||
|     new (&this->value_) T(std::move(value)); | ||||
|   } | ||||
|  | ||||
|   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> | ||||
|   TemplatableValue(F f) : type_(LAMBDA), f_(f) {} | ||||
|   template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0> TemplatableValue(F f) : type_(LAMBDA) { | ||||
|     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; } | ||||
|  | ||||
|   T value(X... x) { | ||||
|     if (this->type_ == LAMBDA) { | ||||
|       return this->f_(x...); | ||||
|       return (*this->f_)(x...); | ||||
|     } | ||||
|     // return value also when none | ||||
|     return this->value_; | ||||
|     return this->type_ == VALUE ? this->value_ : T{}; | ||||
|   } | ||||
|  | ||||
|   optional<T> optional_value(X... x) { | ||||
| @@ -58,14 +105,16 @@ template<typename T, typename... X> class TemplatableValue { | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   enum { | ||||
|   enum : uint8_t { | ||||
|     NONE, | ||||
|     VALUE, | ||||
|     LAMBDA, | ||||
|   } type_; | ||||
|  | ||||
|   T value_{}; | ||||
|   std::function<T(X...)> f_{}; | ||||
|   union { | ||||
|     T value_; | ||||
|     std::function<T(X...)> *f_; | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| /** Base class for all automation conditions. | ||||
|   | ||||
		Reference in New Issue
	
	Block a user