diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h index 3cea9098f87..681d2bcec0f 100644 --- a/src/corelib/kernel/qjniobject.h +++ b/src/corelib/kernel/qjniobject.h @@ -582,36 +582,12 @@ private: friend bool operator==(const QJniObject &, const QJniObject &); friend bool operator!=(const QJniObject&, const QJniObject&); - template - static constexpr bool sameTypeForJni = (QtJniTypes::Traits::signature() - == QtJniTypes::Traits::signature()) - && (sizeof(Have) == sizeof(Want)); - template - static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, - jmethodID id, ...) + static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, jmethodID id, ...) { va_list args = {}; va_start(args, id); - - if constexpr (sameTypeForJni) - res = T(env->CallBooleanMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallByteMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallCharMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallShortMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallIntMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallLongMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallFloatMethodV(obj, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallDoubleMethodV(obj, id, args)); - else - QtJniTypes::staticAssertTypeMismatch(); + QtJniTypes::Caller::callMethodForType(env, res, obj, id, args); va_end(args); } @@ -623,24 +599,7 @@ private: return; va_list args = {}; va_start(args, id); - if constexpr (sameTypeForJni) - res = T(env->CallStaticBooleanMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticByteMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticCharMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticShortMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticIntMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticLongMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticFloatMethodV(clazz, id, args)); - else if constexpr (sameTypeForJni) - res = T(env->CallStaticDoubleMethodV(clazz, id, args)); - else - QtJniTypes::staticAssertTypeMismatch(); + QtJniTypes::Caller::callStaticMethodForType(env, res, clazz, id, args); va_end(args); } @@ -656,105 +615,37 @@ private: template - static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj, - jfieldID id) + static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj, jfieldID id) { - if constexpr (sameTypeForJni) - res = T(env->GetBooleanField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetByteField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetCharField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetShortField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetIntField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetLongField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetFloatField(obj, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetDoubleField(obj, id)); - else - QtJniTypes::staticAssertTypeMismatch(); + QtJniTypes::Caller::getFieldForType(env, res, obj, id); } template - static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz, - jfieldID id) + static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz, jfieldID id) { - if constexpr (sameTypeForJni) - res = T(env->GetStaticBooleanField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticByteField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticCharField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticShortField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticIntField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticLongField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticFloatField(clazz, id)); - else if constexpr (sameTypeForJni) - res = T(env->GetStaticDoubleField(clazz, id)); - else - QtJniTypes::staticAssertTypeMismatch(); + QtJniTypes::Caller::getStaticFieldForType(env, res, clazz, id); } template - static constexpr void setFieldForType(JNIEnv *env, jobject obj, - jfieldID id, T value) + static constexpr void setFieldForType(JNIEnv *env, jobject obj, jfieldID id, T value) { - LocalFrame frame(env); - if constexpr (sameTypeForJni) - env->SetBooleanField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetByteField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetCharField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetShortField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetIntField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetLongField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetFloatField(obj, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetDoubleField(obj, id, static_cast(value)); - else if constexpr (QtJniTypes::isObjectType()) + if constexpr (QtJniTypes::isObjectType()) { + LocalFrame frame(env); env->SetObjectField(obj, id, static_cast(frame.convertToJni(value))); - else - QtJniTypes::staticAssertTypeMismatch(); + } else { + QtJniTypes::Caller::setFieldForType(env, obj, id, value); + } } template - static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz, - jfieldID id, T value) + static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz, jfieldID id, T value) { - LocalFrame frame(env); - if constexpr (sameTypeForJni) - env->SetStaticBooleanField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticByteField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticCharField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticShortField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticIntField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticLongField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticFloatField(clazz, id, static_cast(value)); - else if constexpr (sameTypeForJni) - env->SetStaticDoubleField(clazz, id, static_cast(value)); - else if constexpr (QtJniTypes::isObjectType()) + if constexpr (QtJniTypes::isObjectType()) { + LocalFrame frame(env); env->SetStaticObjectField(clazz, id, static_cast(frame.convertToJni(value))); - else - QtJniTypes::staticAssertTypeMismatch(); + } else { + QtJniTypes::Caller::setStaticFieldForType(env, clazz, id, value); + } } friend QJniObjectPrivate; diff --git a/src/corelib/kernel/qjnitypes_impl.h b/src/corelib/kernel/qjnitypes_impl.h index 3612e506869..16bf308dabb 100644 --- a/src/corelib/kernel/qjnitypes_impl.h +++ b/src/corelib/kernel/qjnitypes_impl.h @@ -138,19 +138,6 @@ template<> struct IsStringType : std::true_type {}; template struct IsStringType> : std::true_type {}; template struct IsStringType : std::true_type {}; -template -static void staticAssertTypeMismatch() -{ - static_assert(flag, "The used type is not supported by this template call. " - "Use a JNI based type instead."); -} - -template -static void staticAssertClassNotRegistered() -{ - static_assert(flag, "Class not registered, use Q_DECLARE_JNI_CLASS"); -} - template struct Traits { // The return type of className/signature becomes void for any type @@ -242,6 +229,56 @@ struct Traits { } }; +template +static constexpr bool sameTypeForJni = (QtJniTypes::Traits::signature() + == QtJniTypes::Traits::signature()) + && (sizeof(Have) == sizeof(Want)); + +template +struct Caller +{}; + +#define MAKE_CALLER(Type, Method) \ +template \ +struct Caller>> \ +{ \ + static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, jmethodID id, va_list args) \ + { \ + res = T(env->Call##Method##MethodV(obj, id, args)); \ + } \ + static constexpr void callStaticMethodForType(JNIEnv *env, T &res, jclass clazz, jmethodID id, va_list args) \ + { \ + res = T(env->CallStatic##Method##MethodV(clazz, id, args)); \ + } \ + static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj, jfieldID id) \ + { \ + res = T(env->Get##Method##Field(obj, id)); \ + } \ + static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz, jfieldID id) \ + { \ + res = T(env->GetStatic##Method##Field(clazz, id)); \ + } \ + static constexpr void setFieldForType(JNIEnv *env, jobject obj, jfieldID id, T value) \ + { \ + env->Set##Method##Field(obj, id, static_cast(value)); \ + } \ + static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz, jfieldID id, T value) \ + { \ + env->SetStatic##Method##Field(clazz, id, static_cast(value)); \ + } \ +} + +MAKE_CALLER(jboolean, Boolean); +MAKE_CALLER(jbyte, Byte); +MAKE_CALLER(jchar, Char); +MAKE_CALLER(jshort, Short); +MAKE_CALLER(jint, Int); +MAKE_CALLER(jlong, Long); +MAKE_CALLER(jfloat, Float); +MAKE_CALLER(jdouble, Double); + +#undef MAKE_CALLER + template static constexpr bool isPrimitiveType() {