Skip to content

Improve naming of template args in bridging #51418

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 35 additions & 24 deletions packages/react-native/ReactCommon/react/bridging/Base.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ namespace detail {
template <typename F>
struct function_wrapper;

template <typename C, typename R, typename... Args>
struct function_wrapper<R (C::*)(Args...)> {
using type = std::function<R(Args...)>;
template <typename ClassT, typename ReturnT, typename... ArgsT>
struct function_wrapper<ReturnT (ClassT::*)(ArgsT...)> {
using type = std::function<ReturnT(ArgsT...)>;
};

template <typename C, typename R, typename... Args>
struct function_wrapper<R (C::*)(Args...) const> {
using type = std::function<R(Args...)>;
template <typename ClassT, typename ReturnT, typename... ArgsT>
struct function_wrapper<ReturnT (ClassT::*)(ArgsT...) const> {
using type = std::function<ReturnT(ArgsT...)>;
};

template <typename T, typename = void>
Expand All @@ -61,36 +61,47 @@ struct bridging_wrapper<
template <typename T>
using bridging_t = typename detail::bridging_wrapper<T>::type;

template <typename R, typename T, std::enable_if_t<is_jsi_v<T>, int> = 0>
auto fromJs(jsi::Runtime& rt, T&& value, const std::shared_ptr<CallInvoker>&)
-> decltype(static_cast<R>(
std::move(convert(rt, std::forward<T>(value))))) {
return static_cast<R>(std::move(convert(rt, std::forward<T>(value))));
template <typename ReturnT, typename JSArgT>
requires is_jsi_v<JSArgT>
auto fromJs(
jsi::Runtime& rt,
JSArgT&& value,
const std::shared_ptr<CallInvoker>& /*unused*/)
-> decltype(static_cast<ReturnT>(
std::move(convert(rt, std::forward<JSArgT>(value)))))

{
return static_cast<ReturnT>(
std::move(convert(rt, std::forward<JSArgT>(value))));
}

template <typename R, typename T>
auto fromJs(jsi::Runtime& rt, T&& value, const std::shared_ptr<CallInvoker>&)
-> decltype(Bridging<remove_cvref_t<R>>::fromJs(
template <typename ReturnT, typename JSArgT>
auto fromJs(
jsi::Runtime& rt,
JSArgT&& value,
const std::shared_ptr<CallInvoker>& /*unused*/)
-> decltype(Bridging<remove_cvref_t<ReturnT>>::fromJs(
rt,
convert(rt, std::forward<T>(value)))) {
return Bridging<remove_cvref_t<R>>::fromJs(
rt, convert(rt, std::forward<T>(value)));
convert(rt, std::forward<JSArgT>(value)))) {
return Bridging<remove_cvref_t<ReturnT>>::fromJs(
rt, convert(rt, std::forward<JSArgT>(value)));
}

template <typename R, typename T>
template <typename ReturnT, typename JSArgT>
auto fromJs(
jsi::Runtime& rt,
T&& value,
JSArgT&& value,
const std::shared_ptr<CallInvoker>& jsInvoker)
-> decltype(Bridging<remove_cvref_t<R>>::fromJs(
-> decltype(Bridging<remove_cvref_t<ReturnT>>::fromJs(
rt,
convert(rt, std::forward<T>(value)),
convert(rt, std::forward<JSArgT>(value)),
jsInvoker)) {
return Bridging<remove_cvref_t<R>>::fromJs(
rt, convert(rt, std::forward<T>(value)), jsInvoker);
return Bridging<remove_cvref_t<ReturnT>>::fromJs(
rt, convert(rt, std::forward<JSArgT>(value)), jsInvoker);
}

template <typename T, std::enable_if_t<is_jsi_v<T>, int> = 0>
template <typename T>
requires is_jsi_v<T>
auto toJs(
jsi::Runtime& rt,
T&& value,
Expand Down
70 changes: 36 additions & 34 deletions packages/react-native/ReactCommon/react/bridging/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,55 @@
namespace facebook::react::bridging {

template <
typename T,
typename C,
typename R,
typename... Args,
typename... JSArgs>
T callFromJs(
typename JSReturnT,
typename ClassT,
typename ReturnT,
typename... ArgsT,
typename... JSArgsT>
JSReturnT callFromJs(
jsi::Runtime& rt,
R (C::*method)(jsi::Runtime&, Args...),
ReturnT (ClassT::*method)(jsi::Runtime&, ArgsT...),
const std::shared_ptr<CallInvoker>& jsInvoker,
C* instance,
JSArgs&&... args) {
ClassT* instance,
JSArgsT&&... args) {
static_assert(
sizeof...(Args) == sizeof...(JSArgs), "Incorrect arguments length");
sizeof...(ArgsT) == sizeof...(JSArgsT), "Incorrect arguments length");
static_assert(
(supportsFromJs<Args, JSArgs> && ...), "Incompatible arguments");
(supportsFromJs<ArgsT, JSArgsT> && ...), "Incompatible arguments");

if constexpr (std::is_void_v<T>) {
if constexpr (std::is_void_v<JSReturnT>) {
(instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...);
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);

} else if constexpr (std::is_void_v<R>) {
} else if constexpr (std::is_void_v<ReturnT>) {
static_assert(
std::is_same_v<T, jsi::Value>,
std::is_same_v<JSReturnT, jsi::Value>,
"Void functions may only return undefined");

(instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...);
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);
return jsi::Value();

} else if constexpr (is_jsi_v<T> || supportsToJs<R, T>) {
static_assert(supportsToJs<R, T>, "Incompatible return type");

} else if constexpr (
is_jsi_v<JSReturnT> || supportsToJs<ReturnT, JSReturnT>) {
static_assert(supportsToJs<ReturnT, JSReturnT>, "Incompatible return type");
return toJs(
rt,
(instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...),
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...),
jsInvoker);
} else if constexpr (is_optional_jsi_v<T>) {
} else if constexpr (is_optional_jsi_v<JSReturnT>) {
static_assert(
is_optional_v<R>
? supportsToJs<typename R::value_type, typename T::value_type>
: supportsToJs<R, typename T::value_type>,
is_optional_v<ReturnT>
? supportsToJs<
typename ReturnT::value_type,
typename JSReturnT::value_type>
: supportsToJs<ReturnT, typename JSReturnT::value_type>,
"Incompatible return type");

auto result = toJs(
rt,
(instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...),
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...),
jsInvoker);

if constexpr (std::is_same_v<decltype(result), jsi::Value>) {
Expand All @@ -70,20 +71,21 @@ T callFromJs(

return convert(rt, std::move(result));
} else {
static_assert(std::is_convertible_v<R, T>, "Incompatible return type");
static_assert(
std::is_convertible_v<ReturnT, JSReturnT>, "Incompatible return type");
return (instance->*method)(
rt, fromJs<Args>(rt, std::forward<JSArgs>(args), jsInvoker)...);
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);
}
}

template <typename R, typename... Args>
constexpr size_t getParameterCount(R (*)(Args...)) {
return sizeof...(Args);
template <typename ReturnT, typename... ArgsT>
constexpr size_t getParameterCount(ReturnT (*)(ArgsT...)) {
return sizeof...(ArgsT);
}

template <typename C, typename R, typename... Args>
constexpr size_t getParameterCount(R (C::*)(Args...)) {
return sizeof...(Args);
template <typename Class, typename ReturnT, typename... ArgsT>
constexpr size_t getParameterCount(ReturnT (Class::*)(ArgsT...)) {
return sizeof...(ArgsT);
}

} // namespace facebook::react::bridging
Loading