mirror of
https://github.com/esphome/esphome.git
synced 2026-07-11 01:15:33 +00:00
[core] Support convertible return types in TemplatableFn via trampoline
TemplatableFn now accepts stateless lambdas whose return type is
convertible to T (e.g., int -> uint8_t). Uses a casting trampoline
that reconstructs the stateless lambda via F{} (default-constructible
in C++20).
Also:
- Remove std::move on trivially copyable TemplatableFn (clang-tidy)
- Wrap http_request method via cg.templatable()
This commit is contained in:
@@ -41,10 +41,16 @@ template<typename T, typename... X> class TemplatableFn {
|
||||
public:
|
||||
TemplatableFn() = default;
|
||||
|
||||
// Exact return type match — direct function pointer storage
|
||||
template<typename F> TemplatableFn(F f) requires std::convertible_to<F, T (*)(X...)> : f_(f) {}
|
||||
|
||||
// Convertible return type (e.g., int -> uint8_t) — casting trampoline.
|
||||
// Stateless lambdas are default-constructible in C++20, so F{} recreates the lambda inside
|
||||
// the trampoline without capturing. This compiles to the same code as a direct call + cast.
|
||||
template<typename F>
|
||||
TemplatableFn(F) requires std::invocable<F, X...> &&(!std::convertible_to<F, T (*)(X...)>) = delete;
|
||||
TemplatableFn(F) requires(!std::convertible_to<F, T (*)(X...)>) &&
|
||||
std::invocable<F, X...> &&std::convertible_to<std::invoke_result_t<F, X...>, T> &&std::is_empty_v<F>
|
||||
&&std::default_initializable<F> : f_([](X... x) -> T { return static_cast<T>(F{}(x...)); }) {}
|
||||
|
||||
bool has_value() const { return this->f_ != nullptr; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user