diff --git a/include/ftl/details/function.h b/include/ftl/details/function.h
new file mode 100644
index 0000000..35c5a8b
--- /dev/null
+++ b/include/ftl/details/function.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 <array>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <type_traits>
+
+namespace android::ftl::details {
+
+// The maximum allowed value for the template argument `N` in
+// `ftl::Function<F, N>`.
+constexpr size_t kFunctionMaximumN = 14;
+
+// Converts a member function pointer type `Ret(Class::*)(Args...)` to an equivalent non-member
+// function type `Ret(Args...)`.
+
+template <typename>
+struct remove_member_function_pointer;
+
+template <typename Class, typename Ret, typename... Args>
+struct remove_member_function_pointer<Ret (Class::*)(Args...)> {
+  using type = Ret(Args...);
+};
+
+template <typename Class, typename Ret, typename... Args>
+struct remove_member_function_pointer<Ret (Class::*)(Args...) const> {
+  using type = Ret(Args...);
+};
+
+template <auto MemberFunction>
+using remove_member_function_pointer_t =
+    typename remove_member_function_pointer<decltype(MemberFunction)>::type;
+
+// Helper functions for binding to the supported targets.
+
+template <typename Ret, typename... Args>
+auto bind_opaque_no_op() -> Ret (*)(void*, Args...) {
+  return [](void*, Args...) -> Ret {
+    if constexpr (!std::is_void_v<Ret>) {
+      return Ret{};
+    }
+  };
+}
+
+template <typename F, typename Ret, typename... Args>
+auto bind_opaque_function_object(const F&) -> Ret (*)(void*, Args...) {
+  return [](void* opaque, Args... args) -> Ret {
+    return std::invoke(*static_cast<F*>(opaque), std::forward<Args>(args)...);
+  };
+}
+
+template <auto MemberFunction, typename Class, typename Ret, typename... Args>
+auto bind_member_function(Class* instance, Ret (*)(Args...) = nullptr) {
+  return [instance](Args... args) -> Ret {
+    return std::invoke(MemberFunction, instance, std::forward<Args>(args)...);
+  };
+}
+
+template <auto FreeFunction, typename Ret, typename... Args>
+auto bind_free_function(Ret (*)(Args...) = nullptr) {
+  return [](Args... args) -> Ret { return std::invoke(FreeFunction, std::forward<Args>(args)...); };
+}
+
+// Traits class for the opaque storage used by Function.
+
+template <std::size_t N>
+struct function_opaque_storage {
+  // The actual type used for the opaque storage. An `N` of zero specifies the minimum useful size,
+  // which allows a lambda with zero or one capture args.
+  using type = std::array<std::intptr_t, N + 1>;
+
+  template <typename S>
+  static constexpr bool require_trivially_copyable = std::is_trivially_copyable_v<S>;
+
+  template <typename S>
+  static constexpr bool require_trivially_destructible = std::is_trivially_destructible_v<S>;
+
+  template <typename S>
+  static constexpr bool require_will_fit_in_opaque_storage = sizeof(S) <= sizeof(type);
+
+  template <typename S>
+  static constexpr bool require_alignment_compatible =
+      std::alignment_of_v<S> <= std::alignment_of_v<type>;
+
+  // Copies `src` into the opaque storage, and returns that storage.
+  template <typename S>
+  static type opaque_copy(const S& src) {
+    // TODO: Replace with C++20 concepts/constraints which can give more details.
+    static_assert(require_trivially_copyable<S>,
+                  "ftl::Function can only store lambdas that capture trivially copyable data.");
+    static_assert(
+        require_trivially_destructible<S>,
+        "ftl::Function can only store lambdas that capture trivially destructible data.");
+    static_assert(require_will_fit_in_opaque_storage<S>,
+                  "ftl::Function has limited storage for lambda captured state. Maybe you need to "
+                  "increase N?");
+    static_assert(require_alignment_compatible<S>);
+
+    type opaque;
+    std::memcpy(opaque.data(), &src, sizeof(S));
+    return opaque;
+  }
+};
+
+// Traits class to help determine the template parameters to use for a ftl::Function, given a
+// function object.
+
+template <typename F, typename = decltype(&F::operator())>
+struct function_traits {
+  // The function type `F` with which to instantiate the `Function<F, N>` template.
+  using type = remove_member_function_pointer_t<&F::operator()>;
+
+  // The (minimum) size `N` with which to instantiate the `Function<F, N>` template.
+  static constexpr std::size_t size =
+      (std::max(sizeof(std::intptr_t), sizeof(F)) - 1) / sizeof(std::intptr_t);
+};
+
+}  // namespace android::ftl::details
diff --git a/include/ftl/function.h b/include/ftl/function.h
new file mode 100644
index 0000000..3538ca4
--- /dev/null
+++ b/include/ftl/function.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 <cstddef>
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+#include <ftl/details/function.h>
+
+namespace android::ftl {
+
+// ftl::Function<F, N> is a container for function object, and can mostly be used in place of
+// std::function<F>.
+//
+// Unlike std::function<F>, a ftl::Function<F, N>:
+//
+//  * Uses a static amount of memory (controlled by N), and never any dynamic allocation.
+//  * Satisfies the std::is_trivially_copyable<> trait.
+//  * Satisfies the std::is_trivially_destructible<> trait.
+//
+// However those same limits are also required from the contained function object in turn.
+//
+// The size of a ftl::Function<F, N> is guaranteed to be:
+//
+//     sizeof(std::intptr_t) * (N + 2)
+//
+// A ftl::Function<F, N> can always be implicitly converted to a larger size ftl::Function<F, M>.
+// Trying to convert the other way leads to a compilation error.
+//
+// A default-constructed ftl::Function is in an empty state. The operator bool() overload returns
+// false in this state. It is undefined behavior to attempt to invoke the function in this state.
+//
+// The ftl::Function<F, N> can also be constructed or assigned from ftl::no_op. This sets up the
+// ftl::Function to be non-empty, with a function that when called does nothing except
+// default-constructs a return value.
+//
+// The ftl::make_function() helpers construct a ftl::Function<F, N>, including deducing the
+// values of F and N from the arguments it is given.
+//
+// The static ftl::Function<F, N>::make() helpers construct a ftl::Function<F, N> without that
+// deduction, and also allow for implicit argument conversion if the target being called needs them.
+//
+// The construction helpers allow any of the following types of functions to be stored:
+//
+//  * Any SMALL function object (as defined by the C++ Standard), such as a lambda with a small
+//    capture, or other "functor". The requirements are:
+//
+//      1) The function object must be trivial to destroy (in fact, the destructor will never
+//         actually be called once copied to the internal storage).
+//      2) The function object must be trivial to copy (the raw bytes will be copied as the
+//         ftl::Function<F, N> is copied/moved).
+//      3) The size of the function object cannot be larger than sizeof(std::intptr_t) * (N + 1),
+//         and it cannot require stricter alignment than alignof(std::intptr_t).
+//
+//    With the default of N=0, a lambda can only capture a single pointer-sized argument. This is
+//    enough to capture `this`, which is why N=0 is the default.
+//
+//  * A member function, with the address passed as the template value argument to the construction
+//    helper function, along with the instance pointer needed to invoke it passed as an ordinary
+//    argument.
+//
+//        ftl::make_function<&Class::member_function>(this);
+//
+//    Note that the indicated member function will be invoked non-virtually. If you need it to be
+//    invoked virtually, you should invoke it yourself with a small lambda like so:
+//
+//        ftl::function([this] { virtual_member_function(); });
+//
+//  * An ordinary function ("free function"), with the address of the function passed as a template
+//    value argument.
+//
+//        ftl::make_function<&std::atoi>();
+//
+//   As with the member function helper, as the function is known at compile time, it will be called
+//   directly.
+//
+// Example usage:
+//
+//   class MyClass {
+//    public:
+//     void on_event() const {}
+//     int on_string(int*, std::string_view) { return 1; }
+//
+//     auto get_function() {
+//       return ftl::function([this] { on_event(); });
+//     }
+//   } cls;
+//
+//   // A function container with no arguments, and returning no value.
+//   ftl::Function<void()> f;
+//
+//   // Construct a ftl::Function containing a small lambda.
+//   f = cls.get_function();
+//
+//   // Construct a ftl::Function that calls `cls.on_event()`.
+//   f = ftl::function<&MyClass::on_event>(&cls);
+//
+//   // Create a do-nothing function.
+//   f = ftl::no_op;
+//
+//   // Invoke the contained function.
+//   f();
+//
+//   // Also invokes it.
+//   std::invoke(f);
+//
+//   // Create a typedef to give a more meaningful name and bound the size.
+//   using MyFunction = ftl::Function<int(std::string_view), 2>;
+//   int* ptr = nullptr;
+//   auto f1 = MyFunction::make_function(
+//       [cls = &cls, ptr](std::string_view sv) {
+//           return cls->on_string(ptr, sv);
+//       });
+//   int r = f1("abc"sv);
+//
+//   // Returns a default-constructed int (0).
+//   f1 = ftl::no_op;
+//   r = f1("abc"sv);
+//   assert(r == 0);
+
+template <typename F, std::size_t N = 0>
+class Function;
+
+// Used to construct a Function that does nothing.
+struct NoOpTag {};
+
+constexpr NoOpTag no_op;
+
+// Detects that a type is a `ftl::Function<F, N>` regardless of what `F` and `N` are.
+template <typename>
+struct is_function : public std::false_type {};
+
+template <typename F, std::size_t N>
+struct is_function<Function<F, N>> : public std::true_type {};
+
+template <typename T>
+constexpr bool is_function_v = is_function<T>::value;
+
+template <typename Ret, typename... Args, std::size_t N>
+class Function<Ret(Args...), N> final {
+  // Enforce a valid size, with an arbitrary maximum allowed size for the container of
+  // sizeof(std::intptr_t) * 16, though that maximum can be relaxed.
+  static_assert(N <= details::kFunctionMaximumN);
+
+  using OpaqueStorageTraits = details::function_opaque_storage<N>;
+
+ public:
+  // Defining result_type allows ftl::Function to be substituted for std::function.
+  using result_type = Ret;
+
+  // Constructs an empty ftl::Function.
+  Function() = default;
+
+  // Constructing or assigning from nullptr_t also creates an empty ftl::Function.
+  Function(std::nullptr_t) {}
+  Function& operator=(std::nullptr_t) { return *this = Function(nullptr); }
+
+  // Constructing from NoOpTag sets up a a special no-op function which is valid to call, and which
+  // returns a default constructed return value.
+  Function(NoOpTag) : function_(details::bind_opaque_no_op<Ret, Args...>()) {}
+  Function& operator=(NoOpTag) { return *this = Function(no_op); }
+
+  // Constructing/assigning from a function object stores a copy of that function object, however:
+  //  * It must be trivially copyable, as the implementation makes a copy with memcpy().
+  //  * It must be trivially destructible, as the implementation doesn't destroy the copy!
+  //  * It must fit in the limited internal storage, which enforces size/alignment restrictions.
+
+  template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
+  Function(const F& f)
+      : opaque_(OpaqueStorageTraits::opaque_copy(f)),
+        function_(details::bind_opaque_function_object<F, Ret, Args...>(f)) {}
+
+  template <typename F, typename = std::enable_if_t<std::is_invocable_r_v<Ret, F, Args...>>>
+  Function& operator=(const F& f) noexcept {
+    return *this = Function{OpaqueStorageTraits::opaque_copy(f),
+                            details::bind_opaque_function_object<F, Ret, Args...>(f)};
+  }
+
+  // Constructing/assigning from a smaller ftl::Function is allowed, but not anything else.
+
+  template <std::size_t M>
+  Function(const Function<Ret(Args...), M>& other)
+      : opaque_{OpaqueStorageTraits::opaque_copy(other.opaque_)}, function_(other.function_) {}
+
+  template <std::size_t M>
+  auto& operator=(const Function<Ret(Args...), M>& other) {
+    return *this = Function{OpaqueStorageTraits::opaque_copy(other.opaque_), other.function_};
+  }
+
+  // Returns true if a function is set.
+  explicit operator bool() const { return function_ != nullptr; }
+
+  // Checks if the other function has the same contents as this one.
+  bool operator==(const Function& other) const {
+    return other.opaque_ == opaque_ && other.function_ == function_;
+  }
+  bool operator!=(const Function& other) const { return !operator==(other); }
+
+  // Alternative way of testing for a function being set.
+  bool operator==(std::nullptr_t) const { return function_ == nullptr; }
+  bool operator!=(std::nullptr_t) const { return function_ != nullptr; }
+
+  // Invokes the function.
+  Ret operator()(Args... args) const {
+    return std::invoke(function_, opaque_.data(), std::forward<Args>(args)...);
+  }
+
+  // Creation helper for function objects, such as lambdas.
+  template <typename F>
+  static auto make(const F& f) -> decltype(Function{f}) {
+    return Function{f};
+  }
+
+  // Creation helper for a class pointer and a compile-time chosen member function to call.
+  template <auto MemberFunction, typename Class>
+  static auto make(Class* instance) -> decltype(Function{
+      details::bind_member_function<MemberFunction>(instance,
+                                                    static_cast<Ret (*)(Args...)>(nullptr))}) {
+    return Function{details::bind_member_function<MemberFunction>(
+        instance, static_cast<Ret (*)(Args...)>(nullptr))};
+  }
+
+  // Creation helper for a compile-time chosen free function to call.
+  template <auto FreeFunction>
+  static auto make() -> decltype(Function{
+      details::bind_free_function<FreeFunction>(static_cast<Ret (*)(Args...)>(nullptr))}) {
+    return Function{
+        details::bind_free_function<FreeFunction>(static_cast<Ret (*)(Args...)>(nullptr))};
+  }
+
+ private:
+  // Needed so a Function<F, M> can be converted to a Function<F, N>.
+  template <typename, std::size_t>
+  friend class Function;
+
+  // The function pointer type of function stored in `function_`. The first argument is always
+  // `&opaque_`.
+  using StoredFunction = Ret(void*, Args...);
+
+  // The type of the opaque storage, used to hold an appropriate function object.
+  // The type stored here is ONLY known to the StoredFunction.
+  // We always use at least one std::intptr_t worth of storage, and always a multiple of that size.
+  using OpaqueStorage = typename OpaqueStorageTraits::type;
+
+  // Internal constructor for creating from a raw opaque blob + function pointer.
+  Function(const OpaqueStorage& opaque, StoredFunction* function)
+      : opaque_(opaque), function_(function) {}
+
+  // Note: `mutable` so that `operator() const` can use it.
+  mutable OpaqueStorage opaque_{};
+  StoredFunction* function_{nullptr};
+};
+
+// Makes a ftl::Function given a function object `F`.
+template <typename F, typename T = details::function_traits<F>>
+Function(const F&) -> Function<typename T::type, T::size>;
+
+template <typename F>
+auto make_function(const F& f) -> decltype(Function{f}) {
+  return Function{f};
+}
+
+// Makes a ftl::Function given a `MemberFunction` and a instance pointer to the associated `Class`.
+template <auto MemberFunction, typename Class>
+auto make_function(Class* instance)
+    -> decltype(Function{details::bind_member_function<MemberFunction>(
+        instance,
+        static_cast<details::remove_member_function_pointer_t<MemberFunction>*>(nullptr))}) {
+  return Function{details::bind_member_function<MemberFunction>(
+      instance, static_cast<details::remove_member_function_pointer_t<MemberFunction>*>(nullptr))};
+}
+
+// Makes a ftl::Function given an ordinary free function.
+template <auto FreeFunction>
+auto make_function() -> decltype(Function{
+    details::bind_free_function<FreeFunction>(static_cast<decltype(FreeFunction)>(nullptr))}) {
+  return Function{
+      details::bind_free_function<FreeFunction>(static_cast<decltype(FreeFunction)>(nullptr))};
+}
+
+}  // namespace android::ftl
diff --git a/libs/ftl/Android.bp b/libs/ftl/Android.bp
index ea1b5e4..918680d 100644
--- a/libs/ftl/Android.bp
+++ b/libs/ftl/Android.bp
@@ -17,6 +17,7 @@
         "enum_test.cpp",
         "fake_guard_test.cpp",
         "flags_test.cpp",
+        "function_test.cpp",
         "future_test.cpp",
         "match_test.cpp",
         "mixins_test.cpp",
diff --git a/libs/ftl/function_test.cpp b/libs/ftl/function_test.cpp
new file mode 100644
index 0000000..91b5e08
--- /dev/null
+++ b/libs/ftl/function_test.cpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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.
+ */
+
+#include <ftl/function.h>
+#include <gtest/gtest.h>
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <string_view>
+#include <type_traits>
+
+namespace android::test {
+namespace {
+
+// Create an alias to composite requirements defined by the trait class `T` for easier testing.
+template <typename T, typename S>
+inline constexpr bool is_opaquely_storable = (T::template require_trivially_copyable<S> &&
+                                              T::template require_trivially_destructible<S> &&
+                                              T::template require_will_fit_in_opaque_storage<S> &&
+                                              T::template require_alignment_compatible<S>);
+
+// `I` gives a count of sizeof(std::intptr_t) bytes , and `J` gives a raw count of bytes
+template <size_t I, size_t J = 0>
+struct KnownSizeFunctionObject {
+  using Data = std::array<std::byte, sizeof(std::intptr_t) * I + J>;
+  void operator()() const {};
+  Data data{};
+};
+
+}  // namespace
+
+// static_assert the expected type traits
+static_assert(std::is_invocable_r_v<void, ftl::Function<void()>>);
+static_assert(std::is_trivially_copyable_v<ftl::Function<void()>>);
+static_assert(std::is_trivially_destructible_v<ftl::Function<void()>>);
+static_assert(std::is_trivially_copy_constructible_v<ftl::Function<void()>>);
+static_assert(std::is_trivially_move_constructible_v<ftl::Function<void()>>);
+static_assert(std::is_trivially_copy_assignable_v<ftl::Function<void()>>);
+static_assert(std::is_trivially_move_assignable_v<ftl::Function<void()>>);
+
+template <typename T>
+using function_traits = ftl::details::function_traits<T>;
+
+// static_assert that the expected value of N is used for known function object sizes.
+static_assert(function_traits<KnownSizeFunctionObject<0, 0>>::size == 0);
+static_assert(function_traits<KnownSizeFunctionObject<0, 1>>::size == 0);
+static_assert(function_traits<KnownSizeFunctionObject<1, 0>>::size == 0);
+static_assert(function_traits<KnownSizeFunctionObject<1, 1>>::size == 1);
+static_assert(function_traits<KnownSizeFunctionObject<2, 0>>::size == 1);
+static_assert(function_traits<KnownSizeFunctionObject<2, 1>>::size == 2);
+
+// Check that is_function_v works
+static_assert(!ftl::is_function_v<KnownSizeFunctionObject<0>>);
+static_assert(!ftl::is_function_v<std::function<void()>>);
+static_assert(ftl::is_function_v<ftl::Function<void()>>);
+
+// static_assert what can and cannot be stored inside the opaque storage
+
+template <size_t N>
+using function_opaque_storage = ftl::details::function_opaque_storage<N>;
+
+// Function objects can be stored if they fit.
+static_assert(is_opaquely_storable<function_opaque_storage<0>, KnownSizeFunctionObject<0>>);
+static_assert(is_opaquely_storable<function_opaque_storage<0>, KnownSizeFunctionObject<1>>);
+static_assert(!is_opaquely_storable<function_opaque_storage<0>, KnownSizeFunctionObject<2>>);
+
+static_assert(is_opaquely_storable<function_opaque_storage<1>, KnownSizeFunctionObject<2>>);
+static_assert(!is_opaquely_storable<function_opaque_storage<1>, KnownSizeFunctionObject<3>>);
+
+static_assert(is_opaquely_storable<function_opaque_storage<2>, KnownSizeFunctionObject<3>>);
+static_assert(!is_opaquely_storable<function_opaque_storage<2>, KnownSizeFunctionObject<4>>);
+
+// Another opaque storage can be stored if it fits. This property is used to copy smaller
+// ftl::Functions into larger ones.
+static_assert(is_opaquely_storable<function_opaque_storage<2>, function_opaque_storage<0>::type>);
+static_assert(is_opaquely_storable<function_opaque_storage<2>, function_opaque_storage<1>::type>);
+static_assert(is_opaquely_storable<function_opaque_storage<2>, function_opaque_storage<2>::type>);
+static_assert(!is_opaquely_storable<function_opaque_storage<2>, function_opaque_storage<3>::type>);
+
+// Function objects that aren't trivially copyable or destroyable cannot be stored.
+auto lambda_capturing_unique_ptr = [ptr = std::unique_ptr<void*>()] { static_cast<void>(ptr); };
+static_assert(
+    !is_opaquely_storable<function_opaque_storage<2>, decltype(lambda_capturing_unique_ptr)>);
+
+// Keep in sync with "Example usage" in header file.
+TEST(Function, Example) {
+  using namespace std::string_view_literals;
+
+  class MyClass {
+   public:
+    void on_event() const {}
+    int on_string(int*, std::string_view) { return 1; }
+
+    auto get_function() {
+      return ftl::make_function([this] { on_event(); });
+    }
+  } cls;
+
+  // A function container with no arguments, and returning no value.
+  ftl::Function<void()> f;
+
+  // Construct a ftl::Function containing a small lambda.
+  f = cls.get_function();
+
+  // Construct a ftl::Function that calls `cls.on_event()`.
+  f = ftl::make_function<&MyClass::on_event>(&cls);
+
+  // Create a do-nothing function.
+  f = ftl::no_op;
+
+  // Invoke the contained function.
+  f();
+
+  // Also invokes it.
+  std::invoke(f);
+
+  // Create a typedef to give a more meaningful name and bound the size.
+  using MyFunction = ftl::Function<int(std::string_view), 2>;
+  int* ptr = nullptr;
+  auto f1 =
+      MyFunction::make([cls = &cls, ptr](std::string_view sv) { return cls->on_string(ptr, sv); });
+  int r = f1("abc"sv);
+
+  // Returns a default-constructed int (0).
+  f1 = ftl::no_op;
+  r = f1("abc"sv);
+  EXPECT_EQ(r, 0);
+}
+
+TEST(Function, BasicOperations) {
+  // Default constructible.
+  ftl::Function<int()> f;
+
+  // Compares as empty
+  EXPECT_FALSE(f);
+  EXPECT_TRUE(f == nullptr);
+  EXPECT_FALSE(f != nullptr);
+  EXPECT_TRUE(ftl::Function<int()>() == f);
+  EXPECT_FALSE(ftl::Function<int()>() != f);
+
+  // Assigning no_op sets it to not empty.
+  f = ftl::no_op;
+
+  // Verify it can be called, and that it returns a default constructed value.
+  EXPECT_EQ(f(), 0);
+
+  // Comparable when non-empty.
+  EXPECT_TRUE(f);
+  EXPECT_FALSE(f == nullptr);
+  EXPECT_TRUE(f != nullptr);
+  EXPECT_FALSE(ftl::Function<int()>() == f);
+  EXPECT_TRUE(ftl::Function<int()>() != f);
+
+  // Constructing from nullptr means empty.
+  f = ftl::Function<int()>{nullptr};
+  EXPECT_FALSE(f);
+
+  // Assigning nullptr means it is empty.
+  f = nullptr;
+  EXPECT_FALSE(f);
+
+  // Move construction
+  f = ftl::no_op;
+  ftl::Function<int()> g{std::move(f)};
+  EXPECT_TRUE(g != nullptr);
+
+  // Move assignment
+  f = nullptr;
+  f = std::move(g);
+  EXPECT_TRUE(f != nullptr);
+
+  // Copy construction
+  ftl::Function<int()> h{f};
+  EXPECT_TRUE(h != nullptr);
+
+  // Copy assignment
+  g = h;
+  EXPECT_TRUE(g != nullptr);
+}
+
+TEST(Function, CanMoveConstructFromLambda) {
+  auto lambda = [] {};
+  ftl::Function<void()> f{std::move(lambda)};
+}
+
+TEST(Function, TerseDeducedConstructAndAssignFromLambda) {
+  auto f = ftl::Function([] { return 1; });
+  EXPECT_EQ(f(), 1);
+
+  f = [] { return 2; };
+  EXPECT_EQ(f(), 2);
+}
+
+namespace {
+
+struct ImplicitConversionsHelper {
+  auto exact(int) -> int { return 0; }
+  auto inexact(long) -> short { return 0; }
+  // TODO: Switch to `auto templated(auto x)` with C++20
+  template <typename T>
+  T templated(T x) {
+    return x;
+  }
+
+  static auto static_exact(int) -> int { return 0; }
+  static auto static_inexact(long) -> short { return 0; }
+  // TODO: Switch to `static auto static_templated(auto x)` with C++20
+  template <typename T>
+  static T static_templated(T x) {
+    return x;
+  }
+};
+
+}  // namespace
+
+TEST(Function, ImplicitConversions) {
+  using Function = ftl::Function<int(int)>;
+  auto check = [](Function f) { return f(0); };
+  auto exact = [](int) -> int { return 0; };
+  auto inexact = [](long) -> short { return 0; };
+  auto templated = [](auto x) { return x; };
+
+  ImplicitConversionsHelper helper;
+
+  // Note, `check(nullptr)` would crash, so we can only check if it would be invocable.
+  static_assert(std::is_invocable_v<decltype(check), decltype(nullptr)>);
+
+  // Note: We invoke each of these to fully expand all the templates involved.
+  EXPECT_EQ(check(ftl::no_op), 0);
+
+  EXPECT_EQ(check(exact), 0);
+  EXPECT_EQ(check(inexact), 0);
+  EXPECT_EQ(check(templated), 0);
+
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::exact>(&helper)), 0);
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::inexact>(&helper)), 0);
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::templated<int>>(&helper)), 0);
+
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::static_exact>()), 0);
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::static_inexact>()), 0);
+  EXPECT_EQ(check(Function::make<&ImplicitConversionsHelper::static_templated<int>>()), 0);
+}
+
+TEST(Function, MakeWithNonConstMemberFunction) {
+  struct Observer {
+    bool called = false;
+    void setCalled() { called = true; }
+  } observer;
+
+  auto f = ftl::make_function<&Observer::setCalled>(&observer);
+
+  f();
+
+  EXPECT_TRUE(observer.called);
+
+  EXPECT_TRUE(f == ftl::Function<void()>::make<&Observer::setCalled>(&observer));
+}
+
+TEST(Function, MakeWithConstMemberFunction) {
+  struct Observer {
+    mutable bool called = false;
+    void setCalled() const { called = true; }
+  } observer;
+
+  const auto f = ftl::make_function<&Observer::setCalled>(&observer);
+
+  f();
+
+  EXPECT_TRUE(observer.called);
+
+  EXPECT_TRUE(f == ftl::Function<void()>::make<&Observer::setCalled>(&observer));
+}
+
+TEST(Function, MakeWithConstClassPointer) {
+  const struct Observer {
+    mutable bool called = false;
+    void setCalled() const { called = true; }
+  } observer;
+
+  const auto f = ftl::make_function<&Observer::setCalled>(&observer);
+
+  f();
+
+  EXPECT_TRUE(observer.called);
+
+  EXPECT_TRUE(f == ftl::Function<void()>::make<&Observer::setCalled>(&observer));
+}
+
+TEST(Function, MakeWithNonCapturingLambda) {
+  auto f = ftl::make_function([](int a, int b) { return a + b; });
+  EXPECT_EQ(f(1, 2), 3);
+}
+
+TEST(Function, MakeWithCapturingLambda) {
+  bool called = false;
+  auto f = ftl::make_function([&called](int a, int b) {
+    called = true;
+    return a + b;
+  });
+  EXPECT_EQ(f(1, 2), 3);
+  EXPECT_TRUE(called);
+}
+
+TEST(Function, MakeWithCapturingMutableLambda) {
+  bool called = false;
+  auto f = ftl::make_function([&called](int a, int b) mutable {
+    called = true;
+    return a + b;
+  });
+  EXPECT_EQ(f(1, 2), 3);
+  EXPECT_TRUE(called);
+}
+
+TEST(Function, MakeWithThreePointerCapturingLambda) {
+  bool my_bool = false;
+  int my_int = 0;
+  float my_float = 0.f;
+
+  auto f = ftl::make_function(
+      [ptr_bool = &my_bool, ptr_int = &my_int, ptr_float = &my_float](int a, int b) mutable {
+        *ptr_bool = true;
+        *ptr_int = 1;
+        *ptr_float = 1.f;
+
+        return a + b;
+      });
+
+  EXPECT_EQ(f(1, 2), 3);
+
+  EXPECT_TRUE(my_bool);
+  EXPECT_EQ(my_int, 1);
+  EXPECT_EQ(my_float, 1.f);
+}
+
+TEST(Function, MakeWithFreeFunction) {
+  auto f = ftl::make_function<&std::make_unique<int, int>>();
+  std::unique_ptr<int> unique_int = f(1);
+  ASSERT_TRUE(unique_int);
+  EXPECT_EQ(*unique_int, 1);
+}
+
+TEST(Function, CopyToLarger) {
+  int counter = 0;
+  ftl::Function<void()> a{[ptr_counter = &counter] { (*ptr_counter)++; }};
+  ftl::Function<void(), 1> b = a;
+  ftl::Function<void(), 2> c = a;
+
+  EXPECT_EQ(counter, 0);
+  a();
+  EXPECT_EQ(counter, 1);
+  b();
+  EXPECT_EQ(counter, 2);
+  c();
+  EXPECT_EQ(counter, 3);
+
+  b = [ptr_counter = &counter] { (*ptr_counter) += 2; };
+  c = [ptr_counter = &counter] { (*ptr_counter) += 3; };
+
+  b();
+  EXPECT_EQ(counter, 5);
+  c();
+  EXPECT_EQ(counter, 8);
+}
+
+}  // namespace android::test
