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>