Skip to content

Commit

Permalink
third_party/fuchsia: Copybara import of the fit library
Browse files Browse the repository at this point in the history
  - 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 <[email protected]>
Commit-Queue: Ben Lawson <[email protected]>
  • Loading branch information
Fuchsia Authors authored and CQ Bot Account committed Jan 20, 2023
1 parent b49bee7 commit 643eb5c
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 11 deletions.
1 change: 1 addition & 0 deletions third_party/fuchsia/repo/.clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Standard: Cpp11
SortIncludes: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
BreakStringLiterals: false
DerivePointerAlignment: true
PointerAlignment: Left
ColumnLimit: 100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@ bool operator!=(decltype(nullptr),
// 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.
Expand All @@ -515,7 +516,8 @@ namespace internal {
// 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)...);
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ struct arrow_operator {
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; }
Expand Down
79 changes: 78 additions & 1 deletion third_party/fuchsia/repo/sdk/lib/fit/include/lib/fit/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -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).
//
Expand Down Expand Up @@ -410,6 +411,44 @@ class LIB_FIT_NODISCARD result<E, T> {
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;
Expand Down Expand Up @@ -526,6 +565,44 @@ class LIB_FIT_NODISCARD result<E> {
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;
Expand Down
15 changes: 15 additions & 0 deletions third_party/fuchsia/repo/sdk/lib/fit/test/function_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1075,3 +1075,18 @@ TEST(FunctionTests, closure_fit_inline_function_Closure_HugeCallableSize) {
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_);
}
Original file line number Diff line number Diff line change
@@ -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_
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ static constexpr bool is_reference_wrapper<std::reference_wrapper<T>> = true;

// 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>
Expand All @@ -31,12 +30,11 @@ static constexpr bool invoke_pmf_other =
!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>
Expand Down

0 comments on commit 643eb5c

Please sign in to comment.