diff options
| -rw-r--r-- | src/corelib/kernel/qjniobject.h | 135 | ||||
| -rw-r--r-- | src/corelib/kernel/qjnitypes_impl.h | 2 | ||||
| -rw-r--r-- | tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp | 47 | ||||
| -rw-r--r-- | tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp | 17 |
4 files changed, 137 insertions, 64 deletions
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h index e5212d36ff8..d469c339216 100644 --- a/src/corelib/kernel/qjniobject.h +++ b/src/corelib/kernel/qjniobject.h @@ -531,6 +531,21 @@ private: friend bool operator==(const QJniObject &, const QJniObject &); friend bool operator!=(const QJniObject&, const QJniObject&); + template<typename T, typename = void> + struct IntegerTypeDetail + { + using type = T; + }; + template<typename T> + struct IntegerTypeDetail<T, typename std::enable_if_t<std::is_enum_v<T>>> + { + using type = std::underlying_type_t<T>; + }; + + template<typename Have, typename Want> + static constexpr bool likeIntegerType = std::is_same_v<Have, Want> + || std::is_same_v<typename IntegerTypeDetail<Have>::type, Want>; + template<typename T> static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, jmethodID id, ...) @@ -540,16 +555,16 @@ private: if constexpr (std::is_same_v<T, jboolean>) res = env->CallBooleanMethodV(obj, id, args); - else if constexpr (std::is_same_v<T, jbyte>) - res = env->CallByteMethodV(obj, id, args); - else if constexpr (std::is_same_v<T, jchar>) - res = env->CallCharMethodV(obj, id, args); - else if constexpr (std::is_same_v<T, jshort>) - res = env->CallShortMethodV(obj, id, args); - else if constexpr (std::is_same_v<T, jint>) - res = env->CallIntMethodV(obj, id, args); - else if constexpr (std::is_same_v<T, jlong>) - res = env->CallLongMethodV(obj, id, args); + else if constexpr (likeIntegerType<T, jbyte>) + res = T{env->CallByteMethodV(obj, id, args)}; + else if constexpr (likeIntegerType<T, jchar>) + res = T{env->CallCharMethodV(obj, id, args)}; + else if constexpr (likeIntegerType<T, jshort>) + res = T{env->CallShortMethodV(obj, id, args)}; + else if constexpr (likeIntegerType<T, jint>) + res = T{env->CallIntMethodV(obj, id, args)}; + else if constexpr (likeIntegerType<T, jlong>) + res = T{env->CallLongMethodV(obj, id, args)}; else if constexpr (std::is_same_v<T, jfloat>) res = env->CallFloatMethodV(obj, id, args); else if constexpr (std::is_same_v<T, jdouble>) @@ -569,16 +584,16 @@ private: va_start(args, id); if constexpr (std::is_same_v<T, jboolean>) res = env->CallStaticBooleanMethodV(clazz, id, args); - else if constexpr (std::is_same_v<T, jbyte>) - res = env->CallStaticByteMethodV(clazz, id, args); - else if constexpr (std::is_same_v<T, jchar>) - res = env->CallStaticCharMethodV(clazz, id, args); - else if constexpr (std::is_same_v<T, jshort>) - res = env->CallStaticShortMethodV(clazz, id, args); - else if constexpr (std::is_same_v<T, jint>) - res = env->CallStaticIntMethodV(clazz, id, args); - else if constexpr (std::is_same_v<T, jlong>) - res = env->CallStaticLongMethodV(clazz, id, args); + else if constexpr (likeIntegerType<T, jbyte>) + res = T{env->CallStaticByteMethodV(clazz, id, args)}; + else if constexpr (likeIntegerType<T, jchar>) + res = T{env->CallStaticCharMethodV(clazz, id, args)}; + else if constexpr (likeIntegerType<T, jshort>) + res = T{env->CallStaticShortMethodV(clazz, id, args)}; + else if constexpr (likeIntegerType<T, jint>) + res = T{env->CallStaticIntMethodV(clazz, id, args)}; + else if constexpr (likeIntegerType<T, jlong>) + res = T{env->CallStaticLongMethodV(clazz, id, args)}; else if constexpr (std::is_same_v<T, jfloat>) res = env->CallStaticFloatMethodV(clazz, id, args); else if constexpr (std::is_same_v<T, jdouble>) @@ -605,16 +620,16 @@ private: { if constexpr (std::is_same_v<T, jboolean>) res = env->GetBooleanField(obj, id); - else if constexpr (std::is_same_v<T, jbyte>) - res = env->GetByteField(obj, id); - else if constexpr (std::is_same_v<T, jchar>) - res = env->GetCharField(obj, id); - else if constexpr (std::is_same_v<T, jshort>) - res = env->GetShortField(obj, id); - else if constexpr (std::is_same_v<T, jint>) - res = env->GetIntField(obj, id); - else if constexpr (std::is_same_v<T, jlong>) - res = env->GetLongField(obj, id); + else if constexpr (likeIntegerType<T, jbyte>) + res = T{env->GetByteField(obj, id)}; + else if constexpr (likeIntegerType<T, jchar>) + res = T{env->GetCharField(obj, id)}; + else if constexpr (likeIntegerType<T, jshort>) + res = T{env->GetShortField(obj, id)}; + else if constexpr (likeIntegerType<T, jint>) + res = T{env->GetIntField(obj, id)}; + else if constexpr (likeIntegerType<T, jlong>) + res = T{env->GetLongField(obj, id)}; else if constexpr (std::is_same_v<T, jfloat>) res = env->GetFloatField(obj, id); else if constexpr (std::is_same_v<T, jdouble>) @@ -629,16 +644,16 @@ private: { if constexpr (std::is_same_v<T, jboolean>) res = env->GetStaticBooleanField(clazz, id); - else if constexpr (std::is_same_v<T, jbyte>) - res = env->GetStaticByteField(clazz, id); - else if constexpr (std::is_same_v<T, jchar>) - res = env->GetStaticCharField(clazz, id); - else if constexpr (std::is_same_v<T, jshort>) - res = env->GetStaticShortField(clazz, id); - else if constexpr (std::is_same_v<T, jint>) - res = env->GetStaticIntField(clazz, id); - else if constexpr (std::is_same_v<T, jlong>) - res = env->GetStaticLongField(clazz, id); + else if constexpr (likeIntegerType<T, jbyte>) + res = T{env->GetStaticByteField(clazz, id)}; + else if constexpr (likeIntegerType<T, jchar>) + res = T{env->GetStaticCharField(clazz, id)}; + else if constexpr (likeIntegerType<T, jshort>) + res = T{env->GetStaticShortField(clazz, id)}; + else if constexpr (likeIntegerType<T, jint>) + res = T{env->GetStaticIntField(clazz, id)}; + else if constexpr (likeIntegerType<T, jlong>) + res = T{env->GetStaticLongField(clazz, id)}; else if constexpr (std::is_same_v<T, jfloat>) res = env->GetStaticFloatField(clazz, id); else if constexpr (std::is_same_v<T, jdouble>) @@ -653,16 +668,16 @@ private: { if constexpr (std::is_same_v<T, jboolean>) env->SetBooleanField(obj, id, value); - else if constexpr (std::is_same_v<T, jbyte>) - env->SetByteField(obj, id, value); - else if constexpr (std::is_same_v<T, jchar>) - env->SetCharField(obj, id, value); - else if constexpr (std::is_same_v<T, jshort>) - env->SetShortField(obj, id, value); - else if constexpr (std::is_same_v<T, jint>) - env->SetIntField(obj, id, value); - else if constexpr (std::is_same_v<T, jlong>) - env->SetLongField(obj, id, value); + else if constexpr (likeIntegerType<T, jbyte>) + env->SetByteField(obj, id, static_cast<jbyte>(value)); + else if constexpr (likeIntegerType<T, jchar>) + env->SetCharField(obj, id, static_cast<jchar>(value)); + else if constexpr (likeIntegerType<T, jshort>) + env->SetShortField(obj, id, static_cast<jshort>(value)); + else if constexpr (likeIntegerType<T, jint>) + env->SetIntField(obj, id, static_cast<jint>(value)); + else if constexpr (likeIntegerType<T, jlong>) + env->SetLongField(obj, id, static_cast<jlong>(value)); else if constexpr (std::is_same_v<T, jfloat>) env->SetFloatField(obj, id, value); else if constexpr (std::is_same_v<T, jdouble>) @@ -679,16 +694,16 @@ private: { if constexpr (std::is_same_v<T, jboolean>) env->SetStaticBooleanField(clazz, id, value); - else if constexpr (std::is_same_v<T, jbyte>) - env->SetStaticByteField(clazz, id, value); - else if constexpr (std::is_same_v<T, jchar>) - env->SetStaticCharField(clazz, id, value); - else if constexpr (std::is_same_v<T, jshort>) - env->SetStaticShortField(clazz, id, value); - else if constexpr (std::is_same_v<T, jint>) - env->SetStaticIntField(clazz, id, value); - else if constexpr (std::is_same_v<T, jlong>) - env->SetStaticLongField(clazz, id, value); + else if constexpr (likeIntegerType<T, jbyte>) + env->SetStaticByteField(clazz, id, static_cast<jbyte>(value)); + else if constexpr (likeIntegerType<T, jchar>) + env->SetStaticCharField(clazz, id, static_cast<jchar>(value)); + else if constexpr (likeIntegerType<T, jshort>) + env->SetStaticShortField(clazz, id, static_cast<jshort>(value)); + else if constexpr (likeIntegerType<T, jint>) + env->SetStaticIntField(clazz, id, static_cast<jint>(value)); + else if constexpr (likeIntegerType<T, jlong>) + env->SetStaticLongField(clazz, id, static_cast<jlong>(value)); else if constexpr (std::is_same_v<T, jfloat>) env->SetStaticFloatField(clazz, id, value); else if constexpr (std::is_same_v<T, jdouble>) diff --git a/src/corelib/kernel/qjnitypes_impl.h b/src/corelib/kernel/qjnitypes_impl.h index 7b8bd1819af..5f87c97e5b6 100644 --- a/src/corelib/kernel/qjnitypes_impl.h +++ b/src/corelib/kernel/qjnitypes_impl.h @@ -237,6 +237,8 @@ struct Traits { return CTString("D"); } else if constexpr (std::is_same_v<T, void>) { return CTString("V"); + } else if constexpr (std::is_enum_v<T>) { + return Traits<std::underlying_type_t<T>>::signature(); } // else: return void -> not implemented } diff --git a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp index b524997961f..cc3ebc658eb 100644 --- a/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp +++ b/tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp @@ -847,6 +847,10 @@ void tst_QJniObject::getStaticIntField() jint i = QJniObject::getStaticField<jint>(cls, "SIZE"); QCOMPARE(i, 64); + + enum class Enum { SIZE = 64 }; + Enum e = QJniObject::getStaticField<Enum>(cls, "SIZE"); + QCOMPARE(e, Enum::SIZE); } void tst_QJniObject::getStaticByteFieldClassName() @@ -863,6 +867,10 @@ void tst_QJniObject::getStaticByteField() jbyte i = QJniObject::getStaticField<jbyte>(cls, "MAX_VALUE"); QCOMPARE(i, jbyte(127)); + + enum class Enum : jbyte { MAX_VALUE = 127 }; + Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE"); + QCOMPARE(e, Enum::MAX_VALUE); } void tst_QJniObject::getStaticLongFieldClassName() @@ -879,6 +887,10 @@ void tst_QJniObject::getStaticLongField() jlong i = QJniObject::getStaticField<jlong>(cls, "MAX_VALUE"); QCOMPARE(i, jlong(9223372036854775807L)); + + enum class Enum : jlong { MAX_VALUE = 9223372036854775807L }; + Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE"); + QCOMPARE(e, Enum::MAX_VALUE); } void tst_QJniObject::getStaticDoubleFieldClassName() @@ -931,6 +943,9 @@ void tst_QJniObject::getStaticShortField() jshort i = QJniObject::getStaticField<jshort>(cls, "MAX_VALUE"); QCOMPARE(i, jshort(32767)); + enum class Enum : jshort { MAX_VALUE = 32767 }; + Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE"); + QCOMPARE(e, Enum::MAX_VALUE); } void tst_QJniObject::getStaticCharFieldClassName() @@ -947,6 +962,10 @@ void tst_QJniObject::getStaticCharField() jchar i = QJniObject::getStaticField<jchar>(cls, "MAX_VALUE"); QCOMPARE(i, jchar(0xffff)); + + enum class Enum : jchar { MAX_VALUE = 0xffff }; + Enum e = QJniObject::getStaticField<Enum>(cls, "MAX_VALUE"); + QCOMPARE(e, Enum::MAX_VALUE); } @@ -982,16 +1001,22 @@ void setField(const char *fieldName, T testValue) void tst_QJniObject::setIntField() { setField("INT_VAR", 555); + enum class Enum : jint { VALUE = 555 }; + setField("INT_VAR", Enum::VALUE); } void tst_QJniObject::setByteField() { - setField("BYTE_VAR", jbyte(555)); + setField("BYTE_VAR", jbyte(123)); + enum class Enum : jbyte { VALUE = 123 }; + setField("BYTE_VAR", Enum::VALUE); } void tst_QJniObject::setLongField() { setField("LONG_VAR", jlong(9223372036847758232L)); + enum class Enum : jlong { VALUE = 9223372036847758232L }; + setField("LONG_VAR", Enum::VALUE); } void tst_QJniObject::setDoubleField() @@ -1006,12 +1031,16 @@ void tst_QJniObject::setFloatField() void tst_QJniObject::setShortField() { - setField("SHORT_VAR", jshort(123)); + setField("SHORT_VAR", jshort(555)); + enum class Enum : jshort { VALUE = 555 }; + setField("SHORT_VAR", Enum::VALUE); } void tst_QJniObject::setCharField() { setField("CHAR_VAR", jchar('A')); + enum class Enum : jchar { VALUE = 'A' }; + setField("CHAR_VAR", Enum::VALUE); } void tst_QJniObject::setBooleanField() @@ -1049,16 +1078,22 @@ void setStaticField(const char *fieldName, T testValue) void tst_QJniObject::setStaticIntField() { setStaticField("S_INT_VAR", 555); + enum class Enum : jint { VALUE = 555 }; + setStaticField("S_INT_VAR", Enum::VALUE); } void tst_QJniObject::setStaticByteField() { - setStaticField("S_BYTE_VAR", jbyte(555)); + setStaticField("S_BYTE_VAR", jbyte(123)); + enum class Enum : jbyte { VALUE = 123 }; + setStaticField("S_BYTE_VAR", Enum::VALUE); } void tst_QJniObject::setStaticLongField() { setStaticField("S_LONG_VAR", jlong(9223372036847758232L)); + enum class Enum : jlong { VALUE = 9223372036847758232L }; + setStaticField("S_LONG_VAR", Enum::VALUE); } void tst_QJniObject::setStaticDoubleField() @@ -1073,12 +1108,16 @@ void tst_QJniObject::setStaticFloatField() void tst_QJniObject::setStaticShortField() { - setStaticField("S_SHORT_VAR", jshort(123)); + setStaticField("S_SHORT_VAR", jshort(555)); + enum class Enum : jshort { VALUE = 555 }; + setStaticField("S_SHORT_VAR", Enum::VALUE); } void tst_QJniObject::setStaticCharField() { setStaticField("S_CHAR_VAR", jchar('A')); + enum class Enum : jchar { VALUE = 'A' }; + setStaticField("S_CHAR_VAR", Enum::VALUE); } void tst_QJniObject::setStaticBooleanField() diff --git a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp index b7685538f19..cbffb24ff88 100644 --- a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp +++ b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp @@ -115,6 +115,23 @@ static_assert(!QtJniTypes::CTString("ABCDE").endsWith("ABCDEF")); static_assert(QtJniTypes::CTString("ABCDE").endsWith('E')); static_assert(!QtJniTypes::CTString("ABCDE").endsWith('F')); +enum UnscopedEnum {}; +enum class ScopedEnum {}; +enum class IntEnum : int {}; +enum class UnsignedEnum : unsigned {}; +enum class Int8Enum : int8_t {}; +enum class ShortEnum : short {}; +enum class LongEnum : long {}; +enum class JIntEnum : jint {}; + +static_assert(QtJniTypes::Traits<UnscopedEnum>::signature() == "I"); +static_assert(QtJniTypes::Traits<ScopedEnum>::signature() == "I"); +static_assert(QtJniTypes::Traits<IntEnum>::signature() == "I"); +static_assert(QtJniTypes::Traits<UnsignedEnum>::signature() == "I"); +static_assert(QtJniTypes::Traits<Int8Enum>::signature() == "B"); +static_assert(QtJniTypes::Traits<LongEnum>::signature() == "J"); +static_assert(QtJniTypes::Traits<JIntEnum>::signature() == "I"); + void tst_QJniTypes::initTestCase() { |
