diff --git a/src/corelib/kernel/qjniarray.h b/src/corelib/kernel/qjniarray.h index a0bb25cf0f1..a69b4a6dac3 100644 --- a/src/corelib/kernel/qjniarray.h +++ b/src/corelib/kernel/qjniarray.h @@ -573,8 +573,7 @@ protected: std::is_same, std::is_base_of >) { - using ResultType = decltype(std::declval>() - .convertToJni(std::declval())); + using ResultType = decltype(QtJniTypes::Traits::convertToJni(nullptr, {})); const auto className = QtJniTypes::Traits::className(); jclass elementClass = env.findClass(className); if (!elementClass) { @@ -694,9 +693,7 @@ public: auto arrayObject() const { - if constexpr (std::is_convertible_v) - return object(); - else if constexpr (std::is_same_v) + if constexpr (QtJniTypes::isObjectType()) return object(); else if constexpr (QtJniTypes::sameTypeForJni) return object(); @@ -741,26 +738,12 @@ public: const_reference at(size_type i) const { JNIEnv *env = jniEnv(); - if constexpr (std::is_convertible_v) { + if constexpr (QtJniTypes::isObjectType()) { jobject element = env->GetObjectArrayElement(object(), i); - if constexpr (std::is_base_of_v) - return QJniObject::fromLocalRef(element); - else if constexpr (std::is_base_of_v) - return T::fromLocalRef(element); + if constexpr (std::is_base_of_v, std::remove_pointer_t>) + return static_cast(element); else - return T{element}; - } else if constexpr (std::is_same_v) { - jstring string = static_cast(env->GetObjectArrayElement(arrayObject(), i)); - if (string) { - QString res = QtJniTypes::Detail::toQString(string, env); - env->DeleteLocalRef(string); - return res; - } else { - return QString(); - } - } else if constexpr (std::is_base_of_v, std::remove_pointer_t>) { - // jstring, jclass etc - return static_cast(env->GetObjectArrayElement(object(), i)); + return QtJniTypes::Traits::convertFromJni(QJniObject::fromLocalRef(element)); } else { T res = {}; if constexpr (QtJniTypes::sameTypeForJni) @@ -787,15 +770,10 @@ public: { JNIEnv *env = jniEnv(); - if constexpr (std::disjunction_v, - std::is_same>) { - env->SetObjectArrayElement(object(), i, val.object()); - } else if constexpr (std::is_same_v) { - env->SetObjectArrayElement(object(), i, - QJniObject::fromString(val).template object()); - } else if constexpr (std::is_base_of_v, std::remove_pointer_t>) { - // jstring, jclass etc - env->SetObjectArrayElement(object(), i, val); + if constexpr (QtJniTypes::isObjectType()) { + QtJniTypes::Detail::LocalFrame frame(env); + jobject element = frame.template convertToJni(val); + env->SetObjectArrayElement(object(), i, element); } else { // primitive types if constexpr (QtJniTypes::sameTypeForJni) env->SetByteArrayRegion(object(), i, 1, &val); @@ -918,8 +896,8 @@ template auto QJniArrayBase::makeObjectArray(List &&list) { using ElementType = typename q20::remove_cvref_t::value_type; - using ResultType = QJniArray>() - .convertToJni(std::declval()))>; + using ResultType = QJniArray::convertToJni(nullptr, + {}))>; if (std::size(list) == 0) return ResultType(); @@ -945,8 +923,6 @@ auto QJniArrayBase::makeObjectArray(List &&list) } // explicitly manage the frame for local references in chunks of 100 - QtJniTypes::Detail::LocalFrame frame(env); - frame.hasFrame = true; constexpr jint frameCapacity = 100; qsizetype i = 0; for (const auto &element : std::as_const(list)) { @@ -956,13 +932,12 @@ auto QJniArrayBase::makeObjectArray(List &&list) if (env->PushLocalFrame(frameCapacity) != 0) return ResultType{}; } - jobject object = frame.convertToJni(element); + jobject object = QtJniTypes::Traits::convertToJni(env, element); env->SetObjectArrayElement(localArray, i, object); ++i; } if (i) env->PopLocalFrame(nullptr); - frame.hasFrame = false; return ResultType(QJniObject::fromLocalRef(localArray)); } diff --git a/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp index 97510ecfa1f..75c1ae8f977 100644 --- a/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp +++ b/tests/auto/corelib/kernel/qjniarray/tst_qjniarray.cpp @@ -148,6 +148,13 @@ void tst_QJniArray::construct() QCOMPARE(list.at(500), QString::number(500)); QCOMPARE(list.toContainer(), strings); } + { + constexpr qsizetype size = 5; + const QJniArray list(size); + const QStringList strings = list.toContainer(); + QCOMPARE(strings.at(0), QString()); + QCOMPARE(strings.size(), size); + } { QJniArray bytes = QJniArrayBase::fromContainer(QByteArray("abc")); static_assert(std::is_same_v);