third_party/fuchsia: Copybara import of the fit library

  - 1a2796efccc86f400d6fc3044b1c614b4747bdeb [fit] Ergonomic conversion from fit::result<E, T> to zx::...
  - a01ba65d3b1ea856f8c952fc2fb4aa74a7d22137 [fit] Use decltype(auto) in make_the_call
  - 1db06d2d682ae5d584a3eaad369116a145966573 [sdk][fit] Support operator-> forwarding for pointer resu...
  - bd75a17d8f441417a026430545a9deaa14eb3a86 Reland "Reland "[driver_manager] Hang composite devices o...
  - fcbd029622473b6f9882cd78903d50c651709349 Revert "Reland "[driver_manager] Hang composite devices o...
  - 71eb8951dccb88bf8e9588273961ed12f4f24aa7 Reland "[driver_manager] Hang composite devices off parent"
  - 241bd1d5d6648ac39574614c475227201ea89eca Revert "[driver_manager] Hang composite devices off parent"
  - 7f184779e7866768ca1d1017e25a9d1b29975e9e [driver_manager] Hang composite devices off parent

GitOrigin-RevId: 1a2796efccc86f400d6fc3044b1c614b4747bdeb
Change-Id: Ic7930b1123aecb3971887ac8e4ce32cb532814bb
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/126693
Reviewed-by: Wyatt Hepler <hepler@google.com>
Commit-Queue: Ben Lawson <benlawson@google.com>
diff --git a/third_party/fuchsia/repo/.clang-format b/third_party/fuchsia/repo/.clang-format
index 99ee79a..58381b3 100644
--- a/third_party/fuchsia/repo/.clang-format
+++ b/third_party/fuchsia/repo/.clang-format
@@ -8,6 +8,7 @@
 SortIncludes: true
 AllowShortIfStatementsOnASingleLine: false
 AllowShortLoopsOnASingleLine: false
+BreakStringLiterals: false
 DerivePointerAlignment: true
 PointerAlignment: Left
 ColumnLimit: 100
diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h
index d6ce612..fba3e95 100644
--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h
+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/function.h
@@ -505,7 +505,8 @@
 // supported on C++17 and up. On C++14, a plain lambda should be used instead.
 template <typename R, typename T, typename... Args>
 auto bind_member(T* instance, R (T::*fn)(Args...)) {
-  return [instance, fn](Args... args) { return (instance->*fn)(std::forward<Args>(args)...); };
+  // Use explicit type on the return to ensure perfect forwarding of references.
+  return [instance, fn](Args... args) -> R { return (instance->*fn)(std::forward<Args>(args)...); };
 }
 
 // C++17 due to use of 'auto' template parameters and lambda parameters.
@@ -515,7 +516,8 @@
 // This ensure that the correct overload of |method| is called.
 template <auto method, typename T, typename... Args>
 auto make_the_call(T* instance, parameter_pack<Args...>) {
-  return [instance](Args... args) {
+  // Use decltype(auto) on the return to ensure perfect forwarding of references.
+  return [instance](Args... args) -> decltype(auto) {
     return (instance->*method)(std::forward<decltype(args)>(args)...);
   };
 }
diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h
index 4d97d48..18a0c87 100644
--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h
+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/internal/result.h
@@ -37,6 +37,11 @@
   static constexpr const T* forward(const T& value) { return &value; }
 };
 template <typename T>
+struct arrow_operator<T, std::enable_if_t<cpp17::is_pointer_v<T>>> {
+  static constexpr T& forward(T& value) { return value; }
+  static constexpr const T& forward(const T& value) { return value; }
+};
+template <typename T>
 struct arrow_operator<T, cpp17::void_t<decltype(std::declval<T>().operator->())>> {
   static constexpr T& forward(T& value) { return value; }
   static constexpr const T& forward(const T& value) { return value; }
diff --git a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h
index 253848a..a7f77ca 100644
--- a/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h
+++ b/third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h
@@ -34,7 +34,8 @@
 //
 //   bool is_ok()
 //   bool is_error()
-//   T value_or(default_value)   // Returns value on success, or default on failure.
+//   T value_or(default_value)    // Returns value on success, or default on failure.
+//   result<E[, V]> map_error(fn) // Transforms the error value of the result using fn.
 //
 // Available only when is_ok() (will assert otherwise).
 //
@@ -410,6 +411,44 @@
     PW_ASSERT(false);
   }
 
+  // Maps a result<E, T> to a result<E2, T> by transforming the error through
+  // fn, where E2 is the result of invoking fn on E. Success values will be
+  // passed through untouched.
+  //
+  // Note that map_error is not necessary if E2 is constructible from E.
+  // In that case, result<E2, T> will be constructible from result<E, T>.
+  //
+  // If the current object is an r-value, errors and successes in the current
+  // result object will be moved.
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>, T> map_error(Fn&& fn) & {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(error_value()));
+    }
+    return success<T>(value());
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>, T> map_error(Fn&& fn) const& {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(error_value()));
+    }
+    return success<T>(value());
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>, T> map_error(Fn&& fn) && {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(std::move(error_value())));
+    }
+    return take_value();
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>, T> map_error(Fn&& fn) const&& {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(std::move(error_value())));
+    }
+    return success<T>(value());
+  }
+
   constexpr void swap(result& other) {
     if (&other != this) {
       using std::swap;
@@ -526,6 +565,44 @@
     PW_ASSERT(false);
   }
 
+  // Maps a result<E, T> to a result<E2, T> by transforming the error through
+  // fn, where E2 is the result of invoking fn on E. Success values will be
+  // passed through untouched.
+  //
+  // Note that map_error is not necessary if E2 is constructible from E.
+  // In that case, result<E2, T> will be constructible from result<E, T>.
+  //
+  // If the current object is an r-value, errors in the current result object
+  // will be moved.
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>> map_error(Fn&& fn) & {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(error_value()));
+    }
+    return success<>();
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>> map_error(Fn&& fn) const& {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(error_value()));
+    }
+    return success<>();
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>> map_error(Fn&& fn) && {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(std::move(error_value())));
+    }
+    return success<>();
+  }
+  template <typename Fn>
+  constexpr result<std::invoke_result_t<Fn, E>> map_error(Fn&& fn) const&& {
+    if (is_error()) {
+      return error<std::invoke_result_t<Fn, E>>(std::forward<Fn>(fn)(std::move(error_value())));
+    }
+    return success<>();
+  }
+
   constexpr void swap(result& other) {
     if (&other != this) {
       using std::swap;
diff --git a/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc b/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc
index ba7eb5f..c2a2200 100644
--- a/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc
+++ b/third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc
@@ -1075,3 +1075,18 @@
 TEST(FunctionTests, binary_op_fit_inline_function_BinaryOp_HugeCallableSize) {
   binary_op<fit::inline_function<BinaryOp, HugeCallableSize>>();
 }
+
+TEST(FunctionTests, bind_return_reference) {
+  struct TestClass {
+    int& member() { return member_; }
+    int member_ = 0;
+  };
+
+  TestClass instance;
+  // Ensure that references to the original values are returned, not copies.
+  fit::function<int&()> func = fit::bind_member<&TestClass::member>(&instance);
+  EXPECT_EQ(&func(), &instance.member_);
+
+  fit::function<int&()> func_deprecated = fit::bind_member(&instance, &TestClass::member);
+  EXPECT_EQ(&func_deprecated(), &instance.member_);
+}
diff --git a/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/functional.h b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/functional.h
new file mode 100644
index 0000000..34d44e0
--- /dev/null
+++ b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/functional.h
@@ -0,0 +1,50 @@
+// Copyright 2021 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_FUNCTIONAL_H_
+#define LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_FUNCTIONAL_H_
+
+#include "internal/functional.h"
+
+namespace cpp20 {
+
+// This version is always constexpr-qualified, with no other changes from C++17.
+
+#if defined(__cpp_lib_invoke) && defined(__cpp_lib_constexpr_functional) &&     \
+    __cpp_lib_invoke >= 201411L && __cpp_lib_constexpr_functional >= 201907L && \
+    !defined(LIB_STDCOMPAT_USE_POLYFILLS)
+
+using std::invoke;
+
+#else  // Provide invoke() polyfill
+
+template <typename F, typename... Args>
+constexpr cpp17::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args) noexcept(
+    cpp17::is_nothrow_invocable_v<F, Args...>) {
+  return ::cpp17::internal::invoke(std::forward<F>(f), std::forward<Args>(args)...);
+}
+
+#endif  // __cpp_lib_invoke >= 201411L && __cpp_lib_constexpr_functional >= 201907L &&
+        // !defined(LIB_STDCOMPAT_USE_POLYFILLS)
+
+#if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L && \
+    !defined(LIB_STDCOMPAT_USE_POLYFILLS)
+
+using std::bind_front;
+
+#else  // Provide bind_front() polyfill
+
+template <typename F, typename... Args>
+constexpr ::cpp20::internal::front_binder_t<F, Args...> bind_front(F&& f, Args&&... args) noexcept(
+    cpp17::is_nothrow_constructible_v<::cpp20::internal::front_binder_t<F, Args...>,
+                                      cpp17::in_place_t, F, Args...>) {
+  return ::cpp20::internal::front_binder_t<F, Args...>(cpp17::in_place, std::forward<F>(f),
+                                                       std::forward<Args>(args)...);
+}
+
+#endif  // __cpp_lib_bind_front >= 201907L && !defined(LIB_STDCOMPAT_USE_POLYFILLS)
+
+}  // namespace cpp20
+
+#endif  // LIB_STDCOMPAT_INCLUDE_LIB_STDCOMPAT_FUNCTIONAL_H_
diff --git a/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/type_traits.h b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/type_traits.h
index f2620c1..dced28d 100644
--- a/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/type_traits.h
+++ b/third_party/fuchsia/repo/sdk/lib/stdcompat/include/lib/stdcompat/internal/type_traits.h
@@ -17,12 +17,11 @@
 
 // These are from [func.require] ¶ 1.1-7
 template <typename MemFn, typename Class, typename T>
-static constexpr bool invoke_pmf_base = std::is_member_function_pointer<MemFn Class::*>::value &&
-                                        std::is_base_of<Class, std::remove_reference_t<T>>::value;
+static constexpr bool invoke_pmf_base = std::is_member_function_pointer<MemFn Class::*>::value&&
+    std::is_base_of<Class, std::remove_reference_t<T>>::value;
 
 template <typename MemFn, typename Class, typename T>
-static constexpr bool invoke_pmf_refwrap =
-    std::is_member_function_pointer<MemFn Class::*>::value &&
+static constexpr bool invoke_pmf_refwrap = std::is_member_function_pointer<MemFn Class::*>::value&&
     is_reference_wrapper<std::remove_cv_t<std::remove_reference_t<T>>>;
 
 template <typename MemFn, typename Class, typename T>
@@ -31,12 +30,11 @@
     !invoke_pmf_refwrap<MemFn, Class, T>;
 
 template <typename MemObj, typename Class, typename T>
-static constexpr bool invoke_pmd_base = std::is_member_object_pointer<MemObj Class::*>::value &&
-                                        std::is_base_of<Class, std::remove_reference_t<T>>::value;
+static constexpr bool invoke_pmd_base = std::is_member_object_pointer<MemObj Class::*>::value&&
+    std::is_base_of<Class, std::remove_reference_t<T>>::value;
 
 template <typename MemObj, typename Class, typename T>
-static constexpr bool invoke_pmd_refwrap =
-    std::is_member_object_pointer<MemObj Class::*>::value &&
+static constexpr bool invoke_pmd_refwrap = std::is_member_object_pointer<MemObj Class::*>::value&&
     is_reference_wrapper<std::remove_cv_t<std::remove_reference_t<T>>>;
 
 template <typename MemObj, typename Class, typename T>