Skip to content

Commit

Permalink
Support {static,dynamic}_ref_cast without ::javaobject (#17)
Browse files Browse the repository at this point in the history
Summary:
Treat `static_ref_cast<JFoo>` as equivalent to `static_ref_cast<JniType<JFoo>>`,
which is equivalent to `static_ref_cast<JFoo::javaobject>`.

As a side-effect, this also allows `JMap<JFoo, JFoo>`, since the only
thing blocking that before was a cast.

Pull Request resolved: facebookincubator/fbjni#17

Test Plan: CI

Reviewed By: cjhopman

Differential Revision: D18121225

Pulled By: dreiss

fbshipit-source-id: 81d0d56967dcb8d907d3a3cec4a52e110743853c
  • Loading branch information
dreiss authored and facebook-github-bot committed Oct 28, 2019
1 parent 0486015 commit 3753398
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 19 deletions.
4 changes: 2 additions & 2 deletions first-party/fbjni/cxx/fbjni/JThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ class JThread : public JavaClass<JThread> {

static local_ref<JThread> create(std::function<void()>&& runnable) {
auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
return newInstance(static_ref_cast<JRunnable::javaobject>(jrunnable));
return newInstance(static_ref_cast<JRunnable>(jrunnable));
}

static local_ref<JThread> create(std::function<void()>&& runnable, std::string&& name) {
auto jrunnable = JNativeRunnable::newObjectCxxArgs(std::move(runnable));
return newInstance(static_ref_cast<JRunnable::javaobject>(jrunnable), make_jstring(std::move(name)));
return newInstance(static_ref_cast<JRunnable>(jrunnable), make_jstring(std::move(name)));
}

static local_ref<JThread> getCurrent() {
Expand Down
2 changes: 1 addition & 1 deletion first-party/fbjni/cxx/fbjni/detail/Iterator-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct IteratorHelper : public JavaClass<IteratorHelper<E>> {
value_type next() {
static auto elementField =
JavaBase_::javaClassStatic()->template getField<jobject>("mElement");
return dynamic_ref_cast<JniType<E>>(JavaBase_::getFieldValue(elementField));
return dynamic_ref_cast<E>(JavaBase_::getFieldValue(elementField));
}

static void reset(value_type& v) {
Expand Down
14 changes: 7 additions & 7 deletions first-party/fbjni/cxx/fbjni/detail/References-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,32 +491,32 @@ inline void swap(alias_ref<T>& a, alias_ref<T>& b) noexcept {
// template argument. I'm not sure whether that would make the code
// more maintainable (DRY), or less (too clever/confusing.).
template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), local_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), local_ref<T>>
static_ref_cast(const local_ref<U>& ref) noexcept
{
T p = static_cast<T>(ref.get());
JniType<T> p = static_cast<JniType<T>>(ref.get());
return make_local(p);
}

template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), global_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), global_ref<T>>
static_ref_cast(const global_ref<U>& ref) noexcept
{
T p = static_cast<T>(ref.get());
JniType<T> p = static_cast<JniType<T>>(ref.get());
return make_global(p);
}

template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), alias_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), alias_ref<T>>
static_ref_cast(const alias_ref<U>& ref) noexcept
{
T p = static_cast<T>(ref.get());
JniType<T> p = static_cast<JniType<T>>(ref.get());
return wrap_alias(p);
}

template<typename T, typename RefType>
auto dynamic_ref_cast(const RefType& ref) ->
enable_if_t<IsPlainJniReference<T>(), decltype(static_ref_cast<T>(ref))>
enable_if_t<IsPlainJniReference<JniType<T>>(), decltype(static_ref_cast<T>(ref))>
{
if (!ref) {
return decltype(static_ref_cast<T>(ref))();
Expand Down
8 changes: 4 additions & 4 deletions first-party/fbjni/cxx/fbjni/detail/References.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,20 +598,20 @@ class JniLocalScope {
};

template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), local_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), local_ref<T>>
static_ref_cast(const local_ref<U>& ref) noexcept;

template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), global_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), global_ref<T>>
static_ref_cast(const global_ref<U>& ref) noexcept;

template<typename T, typename U>
enable_if_t<IsPlainJniReference<T>(), alias_ref<T>>
enable_if_t<IsPlainJniReference<JniType<T>>(), alias_ref<T>>
static_ref_cast(const alias_ref<U>& ref) noexcept;

template<typename T, typename RefType>
auto dynamic_ref_cast(const RefType& ref) ->
enable_if_t<IsPlainJniReference<T>(), decltype(static_ref_cast<T>(ref))> ;
enable_if_t<IsPlainJniReference<JniType<T>>(), decltype(static_ref_cast<T>(ref))> ;

}}

Expand Down
6 changes: 3 additions & 3 deletions first-party/fbjni/test/jni/doc_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,11 +260,11 @@ struct DocTests : JavaClass<DocTests> {
// Just like raw pointers, upcasting is implicit.
alias_ref<JObject> obj = base;
// static_ref_cast is like C++ static_cast. No runtime checking is done.
alias_ref<JMyDerivedClass> derived_1 = static_ref_cast<JMyDerivedClass::javaobject>(base);
alias_ref<JMyDerivedClass> derived_1 = static_ref_cast<JMyDerivedClass>(base);
// dynamic_ref_cast is like C++ dynamic_cast.
// It will check that the runtime Java type is actually derived from the target type.
try {
alias_ref<JMyDerivedClass> derived_2 = dynamic_ref_cast<JMyDerivedClass::javaobject>(base);
alias_ref<JMyDerivedClass> derived_2 = dynamic_ref_cast<JMyDerivedClass>(base);
(void)derived_2;
} catch (const JniException& exn) {
// Throws ClassCastException if the cast fails.
Expand Down Expand Up @@ -346,7 +346,7 @@ struct DocTests : JavaClass<DocTests> {
alias_ref<JClass> clazz,
// Note that generic types are *not* checked against Java declarations.
alias_ref<JList<JInteger>> values,
alias_ref<JMap<JString::javaobject, JInteger::javaobject>> names) {
alias_ref<JMap<JString, JInteger>> names) {
int sum = 0;
std::string ret;
// Iterator and Iterable support C++ iteration.
Expand Down
4 changes: 2 additions & 2 deletions first-party/fbjni/test/jni/iterator_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jboolean nativeTestListIterator(

jboolean nativeTestMapIterator(
alias_ref<jclass>,
alias_ref<JMap<jstring, JInteger::javaobject>> jmap) {
alias_ref<JMap<jstring, JInteger>> jmap) {
EXPECT(jmap);

EXPECT(jmap->size() == 3);
Expand Down Expand Up @@ -129,7 +129,7 @@ jboolean nativeTestIterateWrongType(

jboolean nativeTestIterateNullKey(
alias_ref<jclass>,
alias_ref<JMap<jstring, JInteger::javaobject>> jmap) {
alias_ref<JMap<jstring, JInteger>> jmap) {
EXPECT(jmap);

EXPECT(jmap->size() == 3);
Expand Down

0 comments on commit 3753398

Please sign in to comment.