1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include "lib/fit/function.h" 17 #include "pw_function/config.h" 18 19 namespace pw { 20 21 /// `pw::Function` is a wrapper for an arbitrary callable object. It can be used 22 /// by callback-based APIs to allow callers to provide any type of callable. 23 /// 24 /// Example: 25 /// @code{.cpp} 26 /// 27 /// template <typename T> 28 /// bool All(const pw::Vector<T>& items, 29 /// pw::Function<bool(const T& item)> predicate) { 30 /// for (const T& item : items) { 31 /// if (!predicate(item)) { 32 /// return false; 33 /// } 34 /// } 35 /// return true; 36 /// } 37 /// 38 /// bool ElementsArePositive(const pw::Vector<int>& items) { 39 /// return All(items, [](const int& i) { return i > 0; }); 40 /// } 41 /// 42 /// bool IsEven(const int& i) { return i % 2 == 0; } 43 /// 44 /// bool ElementsAreEven(const pw::Vector<int>& items) { 45 /// return All(items, IsEven); 46 /// } 47 /// 48 /// @endcode 49 template <typename Callable, 50 size_t inline_target_size = 51 function_internal::config::kInlineCallableSize> 52 using Function = fit::function_impl< 53 inline_target_size, 54 /*require_inline=*/!function_internal::config::kEnableDynamicAllocation, 55 Callable>; 56 57 /// Version of `pw::Function` that exclusively uses inline storage. 58 /// 59 /// IMPORTANT: If `pw::Function` is configured to allow dynamic allocations then 60 /// any attempt to convert `pw::InlineFunction` to `pw::Function` will ALWAYS 61 /// allocate. 62 /// 63 // TODO(b/252852651): Remove warning above when conversion from 64 // `fit::inline_function` to `fit::function` doesn't allocate anymore. 65 template <typename Callable, 66 size_t inline_target_size = 67 function_internal::config::kInlineCallableSize> 68 using InlineFunction = fit::inline_function<Callable, inline_target_size>; 69 70 using Closure = Function<void()>; 71 72 /// `pw::Callback` is identical to @cpp_type{pw::Function} except: 73 /// 74 /// 1. On the first call to invoke a `pw::Callback`, the target function held 75 /// by the `pw::Callback` cannot be called again. 76 /// 2. When a `pw::Callback` is invoked for the first time, the target function 77 /// is released and destructed, along with any resources owned by that 78 /// function (typically the objects captured by a lambda). 79 /// 80 /// A `pw::Callback` in the "already called" state has the same state as a 81 /// `pw::Callback` that has been assigned to `nullptr`. 82 template <typename Callable, 83 size_t inline_target_size = 84 function_internal::config::kInlineCallableSize> 85 using Callback = fit::callback_impl< 86 inline_target_size, 87 /*require_inline=*/!function_internal::config::kEnableDynamicAllocation, 88 Callable>; 89 90 /// Version of `pw::Callback` that exclusively uses inline storage. 91 template <typename Callable, 92 size_t inline_target_size = 93 function_internal::config::kInlineCallableSize> 94 using InlineCallback = fit::inline_callback<Callable, inline_target_size>; 95 96 } // namespace pw 97