// Copyright 2021 The Pigweed Authors // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. #pragma once #include "lib/fit/function.h" #include "pw_function/config.h" namespace pw { /// `pw::Function` is a wrapper for an arbitrary callable object. It can be used /// by callback-based APIs to allow callers to provide any type of callable. /// /// Example: /// @code{.cpp} /// /// template /// bool All(const pw::Vector& items, /// pw::Function predicate) { /// for (const T& item : items) { /// if (!predicate(item)) { /// return false; /// } /// } /// return true; /// } /// /// bool ElementsArePositive(const pw::Vector& items) { /// return All(items, [](const int& i) { return i > 0; }); /// } /// /// bool IsEven(const int& i) { return i % 2 == 0; } /// /// bool ElementsAreEven(const pw::Vector& items) { /// return All(items, IsEven); /// } /// /// @endcode template using Function = fit::function_impl< inline_target_size, /*require_inline=*/!function_internal::config::kEnableDynamicAllocation, Callable>; /// Version of `pw::Function` that exclusively uses inline storage. /// /// IMPORTANT: If `pw::Function` is configured to allow dynamic allocations then /// any attempt to convert `pw::InlineFunction` to `pw::Function` will ALWAYS /// allocate. /// // TODO(b/252852651): Remove warning above when conversion from // `fit::inline_function` to `fit::function` doesn't allocate anymore. template using InlineFunction = fit::inline_function; using Closure = Function; /// `pw::Callback` is identical to @cpp_type{pw::Function} except: /// /// 1. On the first call to invoke a `pw::Callback`, the target function held /// by the `pw::Callback` cannot be called again. /// 2. When a `pw::Callback` is invoked for the first time, the target function /// is released and destructed, along with any resources owned by that /// function (typically the objects captured by a lambda). /// /// A `pw::Callback` in the "already called" state has the same state as a /// `pw::Callback` that has been assigned to `nullptr`. template using Callback = fit::callback_impl< inline_target_size, /*require_inline=*/!function_internal::config::kEnableDynamicAllocation, Callable>; /// Version of `pw::Callback` that exclusively uses inline storage. template using InlineCallback = fit::inline_callback; } // namespace pw