JNI: add generic support for array-types
The typeSignature for a type T[] is always "[" + typeSignature<t>, so we can just implicitly support arrays of any known type. To prevent support for multi-dimensional arrays, make sure that the underlying type is not also an array. By adding a QJniTypes::isArrayType in addition (that is true for any type with a signature starting with '['), methods like QJniObject::callMethod could then return a special QJniArray type that provides array-specific functionality. As a drive-by, and since all lines need to be touched to add braces, replace std::is_same<>::value with std::is_same_v. Change-Id: Iccadf03cfceb8544381a8f635bb54baeddf46c99 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>bb10
parent
ad736e9150
commit
2ef130a41d
|
|
@ -148,70 +148,76 @@ static void staticAssertTypeMismatch()
|
|||
template<typename T>
|
||||
constexpr auto typeSignature()
|
||||
{
|
||||
if constexpr(std::is_same<T, jobject>::value)
|
||||
if constexpr(std::is_array_v<T>) {
|
||||
using UnderlyingType = typename std::remove_extent<T>::type;
|
||||
static_assert(!std::is_array_v<UnderlyingType>,
|
||||
"typeSignature() does not handle multi-dimensional arrays");
|
||||
return String("[") + typeSignature<UnderlyingType>();
|
||||
} else if constexpr(std::is_same_v<T, jobject>) {
|
||||
return String("Ljava/lang/Object;");
|
||||
else if constexpr(std::is_same<T, jclass>::value)
|
||||
} else if constexpr(std::is_same_v<T, jclass>) {
|
||||
return String("Ljava/lang/Class;");
|
||||
else if constexpr(std::is_same<T, jstring>::value)
|
||||
} else if constexpr(std::is_same_v<T, jstring>) {
|
||||
return String("Ljava/lang/String;");
|
||||
else if constexpr(std::is_same<T, jobjectArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jobjectArray>) {
|
||||
return String("[Ljava/lang/Object;");
|
||||
else if constexpr(std::is_same<T, jthrowable>::value)
|
||||
} else if constexpr(std::is_same_v<T, jthrowable>) {
|
||||
return String("Ljava/lang/Throwable;");
|
||||
else if constexpr(std::is_same<T, jbooleanArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jbooleanArray>) {
|
||||
return String("[Z");
|
||||
else if constexpr(std::is_same<T, jbyteArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jbyteArray>) {
|
||||
return String("[B");
|
||||
else if constexpr(std::is_same<T, jshortArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jshortArray>) {
|
||||
return String("[S");
|
||||
else if constexpr(std::is_same<T, jintArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jintArray>) {
|
||||
return String("[I");
|
||||
else if constexpr(std::is_same<T, jlongArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jlongArray>) {
|
||||
return String("[J");
|
||||
else if constexpr(std::is_same<T, jfloatArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jfloatArray>) {
|
||||
return String("[F");
|
||||
else if constexpr(std::is_same<T, jdoubleArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jdoubleArray>) {
|
||||
return String("[D");
|
||||
else if constexpr(std::is_same<T, jcharArray>::value)
|
||||
} else if constexpr(std::is_same_v<T, jcharArray>) {
|
||||
return String("[C");
|
||||
else if constexpr(std::is_same<T, jboolean>::value)
|
||||
} else if constexpr(std::is_same_v<T, jboolean>) {
|
||||
return String("Z");
|
||||
else if constexpr(std::is_same<T, bool>::value)
|
||||
} else if constexpr(std::is_same_v<T, bool>) {
|
||||
return String("Z");
|
||||
else if constexpr(std::is_same<T, jbyte>::value)
|
||||
} else if constexpr(std::is_same_v<T, jbyte>) {
|
||||
return String("B");
|
||||
else if constexpr(std::is_same<T, jchar>::value)
|
||||
} else if constexpr(std::is_same_v<T, jchar>) {
|
||||
return String("C");
|
||||
else if constexpr(std::is_same<T, char>::value)
|
||||
} else if constexpr(std::is_same_v<T, char>) {
|
||||
return String("C");
|
||||
else if constexpr(std::is_same<T, jshort>::value)
|
||||
} else if constexpr(std::is_same_v<T, jshort>) {
|
||||
return String("S");
|
||||
else if constexpr(std::is_same<T, short>::value)
|
||||
} else if constexpr(std::is_same_v<T, short>) {
|
||||
return String("S");
|
||||
else if constexpr(std::is_same<T, jint>::value)
|
||||
} else if constexpr(std::is_same_v<T, jint>) {
|
||||
return String("I");
|
||||
else if constexpr(std::is_same<T, int>::value)
|
||||
} else if constexpr(std::is_same_v<T, int>) {
|
||||
return String("I");
|
||||
else if constexpr(std::is_same<T, uint>::value)
|
||||
} else if constexpr(std::is_same_v<T, uint>) {
|
||||
return String("I");
|
||||
else if constexpr(std::is_same<T, jlong>::value)
|
||||
} else if constexpr(std::is_same_v<T, jlong>) {
|
||||
return String("J");
|
||||
else if constexpr(std::is_same<T, long>::value)
|
||||
} else if constexpr(std::is_same_v<T, long>) {
|
||||
return String("J");
|
||||
else if constexpr(std::is_same<T, jfloat>::value)
|
||||
} else if constexpr(std::is_same_v<T, jfloat>) {
|
||||
return String("F");
|
||||
else if constexpr(std::is_same<T, float>::value)
|
||||
} else if constexpr(std::is_same_v<T, float>) {
|
||||
return String("F");
|
||||
else if constexpr(std::is_same<T, jdouble>::value)
|
||||
} else if constexpr(std::is_same_v<T, jdouble>) {
|
||||
return String("D");
|
||||
else if constexpr(std::is_same<T, double>::value)
|
||||
} else if constexpr(std::is_same_v<T, double>) {
|
||||
return String("D");
|
||||
else if constexpr(std::is_same<T, void>::value)
|
||||
} else if constexpr(std::is_same_v<T, void>) {
|
||||
return String("V");
|
||||
else if constexpr(IsStringType<T>::value)
|
||||
} else if constexpr(IsStringType<T>::value) {
|
||||
static_assert(!IsStringType<T>::value, "Don't use a literal type, call data!");
|
||||
else
|
||||
} else {
|
||||
staticAssertTypeMismatch();
|
||||
}
|
||||
}
|
||||
|
||||
template<bool flag = false>
|
||||
|
|
@ -247,6 +253,13 @@ static constexpr bool isObjectType()
|
|||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool isArrayType()
|
||||
{
|
||||
constexpr auto signature = typeSignature<T>();
|
||||
return signature.startsWith('[');
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static constexpr void assertPrimitiveType()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,14 +52,17 @@ Q_DECLARE_JNI_CLASS(QtTextToSpeech, "org/qtproject/qt/android/speech/QtTextToSpe
|
|||
static_assert(QtJniTypes::className<QtJniTypes::QtTextToSpeech>() == "org/qtproject/qt/android/speech/QtTextToSpeech");
|
||||
|
||||
static_assert(QtJniTypes::fieldSignature<jint>() == "I");
|
||||
static_assert(QtJniTypes::fieldSignature<jint[]>() == "[I");
|
||||
static_assert(QtJniTypes::fieldSignature<jint>() != "X");
|
||||
static_assert(QtJniTypes::fieldSignature<jint>() != "Ljava/lang/Object;");
|
||||
static_assert(QtJniTypes::fieldSignature<jlong>() == "J");
|
||||
static_assert(QtJniTypes::fieldSignature<jstring>() == "Ljava/lang/String;");
|
||||
static_assert(QtJniTypes::fieldSignature<jobject>() == "Ljava/lang/Object;");
|
||||
static_assert(QtJniTypes::fieldSignature<jobject[]>() == "[Ljava/lang/Object;");
|
||||
static_assert(QtJniTypes::fieldSignature<jobjectArray>() == "[Ljava/lang/Object;");
|
||||
static_assert(QtJniTypes::fieldSignature<QJniObject>() == "Ljava/lang/Object;");
|
||||
static_assert(QtJniTypes::fieldSignature<QtJavaWrapper>() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
static_assert(QtJniTypes::fieldSignature<QtJavaWrapper[]>() == "[Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
static_assert(QtJniTypes::fieldSignature<QtCustomJniObject>() == "Lorg/qtproject/qt/android/QtCustomJniObject;");
|
||||
|
||||
static_assert(QtJniTypes::methodSignature<void>() == "()V");
|
||||
|
|
@ -82,6 +85,12 @@ static_assert(QtJniTypes::isObjectType<jobject>());
|
|||
static_assert(QtJniTypes::isObjectType<jobjectArray>());
|
||||
static_assert(QtJniTypes::isObjectType<QtCustomJniObject>());
|
||||
|
||||
static_assert(!QtJniTypes::isArrayType<jint>());
|
||||
static_assert(QtJniTypes::isArrayType<jint[]>());
|
||||
static_assert(QtJniTypes::isArrayType<jobject[]>());
|
||||
static_assert(QtJniTypes::isArrayType<jobjectArray>());
|
||||
static_assert(QtJniTypes::isArrayType<QtJavaWrapper[]>());
|
||||
|
||||
static_assert(QtJniTypes::String("ABCDE").startsWith("ABC"));
|
||||
static_assert(QtJniTypes::String("ABCDE").startsWith("A"));
|
||||
static_assert(QtJniTypes::String("ABCDE").startsWith("ABCDE"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue