• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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