mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	Optimize TemplatableValue memory
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