summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-09-16 11:28:49 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-09-22 07:18:10 +0200
commit0022b05a9a222912ed91f658c058dff6955d2de4 (patch)
tree756117c07c0cec93fba0ef6e09a981ca61d78a4a
parentdc126de22ea4d38736ae57c08c0b271f3c53fad9 (diff)
JNI: rename our compile-time String type to CTString
The type lives in the QtJniTypes namespace, which is where types end up that are declared through the Q_DECLARE_JNI_CLASS/TYPE macros. Having a String type in that namespace prevents us from declaring the Java String class as a QtJniTypes type, which is silly. Perhaps this type becomes obsolete at some point with std::string being a constexpr type in C++23, but until then we need it. It has no ABI, so renaming it us safe. Until submodules are ported, leave a compatibility alias String type, which also prevents us from declaring a String JNI class in tests until the alias is removed in a later commit. Change-Id: I489a40a9b9e94e6495cf54548238438e9220d5c1 Reviewed-by: Zoltan Gera <zoltan.gera@qt.io> Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io> Reviewed-by: Petri Virkkunen <petri.virkkunen@qt.io>
-rw-r--r--src/corelib/kernel/qjnitypes.h10
-rw-r--r--src/corelib/kernel/qjnitypes_impl.h109
-rw-r--r--tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp38
3 files changed, 79 insertions, 78 deletions
diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h
index 72d6f2783c..d3634d6bc5 100644
--- a/src/corelib/kernel/qjnitypes.h
+++ b/src/corelib/kernel/qjnitypes.h
@@ -45,7 +45,7 @@ constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
&& Signature[sizeof(Signature) - 2] == ';', \
"Type signature needs to start with 'L' or '['" \
" and end with ';'"); \
- return QtJniTypes::String(Signature); \
+ return QtJniTypes::CTString(Signature); \
} \
#define Q_DECLARE_JNI_CLASS(Type, Signature) \
@@ -53,14 +53,14 @@ Q_DECLARE_JNI_TYPE_HELPER(Type) \
template<> \
constexpr auto QtJniTypes::className<QtJniTypes::Type>() \
{ \
- return QtJniTypes::String(Signature); \
+ return QtJniTypes::CTString(Signature); \
} \
template<> \
constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
{ \
- return QtJniTypes::String("L") \
- + QtJniTypes::String(Signature) \
- + QtJniTypes::String(";"); \
+ return QtJniTypes::CTString("L") \
+ + QtJniTypes::CTString(Signature) \
+ + QtJniTypes::CTString(";"); \
} \
#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
diff --git a/src/corelib/kernel/qjnitypes_impl.h b/src/corelib/kernel/qjnitypes_impl.h
index 97be4f4394..a671eeae35 100644
--- a/src/corelib/kernel/qjnitypes_impl.h
+++ b/src/corelib/kernel/qjnitypes_impl.h
@@ -18,13 +18,13 @@ namespace QtJniTypes
// a constexpr type for string literals of any character width, aware of the length
// of the string.
template<size_t N_WITH_NULL, typename BaseType = char>
-struct String
+struct CTString
{
BaseType m_data[N_WITH_NULL] = {};
- constexpr String() noexcept {}
+ constexpr CTString() noexcept {}
// Can be instantiated (only) with a string literal
- constexpr explicit String(const BaseType (&data)[N_WITH_NULL]) noexcept
+ constexpr explicit CTString(const BaseType (&data)[N_WITH_NULL]) noexcept
{
for (size_t i = 0; i < N_WITH_NULL - 1; ++i)
m_data[i] = data[i];
@@ -71,8 +71,8 @@ struct String
}
template<size_t N2_WITH_NULL>
- friend inline constexpr bool operator==(const String<N_WITH_NULL> &lhs,
- const String<N2_WITH_NULL> &rhs) noexcept
+ friend inline constexpr bool operator==(const CTString<N_WITH_NULL> &lhs,
+ const CTString<N2_WITH_NULL> &rhs) noexcept
{
if constexpr (N_WITH_NULL != N2_WITH_NULL) {
return false;
@@ -86,57 +86,60 @@ struct String
}
template<size_t N2_WITH_NULL>
- friend inline constexpr bool operator!=(const String<N_WITH_NULL> &lhs,
- const String<N2_WITH_NULL> &rhs) noexcept
+ friend inline constexpr bool operator!=(const CTString<N_WITH_NULL> &lhs,
+ const CTString<N2_WITH_NULL> &rhs) noexcept
{
return !operator==(lhs, rhs);
}
template<size_t N2_WITH_NULL>
- friend inline constexpr bool operator==(const String<N_WITH_NULL> &lhs,
+ friend inline constexpr bool operator==(const CTString<N_WITH_NULL> &lhs,
const BaseType (&rhs)[N2_WITH_NULL]) noexcept
{
- return operator==(lhs, String<N2_WITH_NULL>(rhs));
+ return operator==(lhs, CTString<N2_WITH_NULL>(rhs));
}
template<size_t N2_WITH_NULL>
friend inline constexpr bool operator==(const BaseType (&lhs)[N2_WITH_NULL],
- const String<N_WITH_NULL> &rhs) noexcept
+ const CTString<N_WITH_NULL> &rhs) noexcept
{
- return operator==(String<N2_WITH_NULL>(lhs), rhs);
+ return operator==(CTString<N2_WITH_NULL>(lhs), rhs);
}
template<size_t N2_WITH_NULL>
- friend inline constexpr bool operator!=(const String<N_WITH_NULL> &lhs,
+ friend inline constexpr bool operator!=(const CTString<N_WITH_NULL> &lhs,
const BaseType (&rhs)[N2_WITH_NULL]) noexcept
{
- return operator!=(lhs, String<N2_WITH_NULL>(rhs));
+ return operator!=(lhs, CTString<N2_WITH_NULL>(rhs));
}
template<size_t N2_WITH_NULL>
friend inline constexpr bool operator!=(const BaseType (&lhs)[N2_WITH_NULL],
- const String<N_WITH_NULL> &rhs) noexcept
+ const CTString<N_WITH_NULL> &rhs) noexcept
{
- return operator!=(String<N2_WITH_NULL>(lhs), rhs);
+ return operator!=(CTString<N2_WITH_NULL>(lhs), rhs);
}
template<size_t N2_WITH_NULL>
- friend inline constexpr auto operator+(const String<N_WITH_NULL> &lhs,
- const String<N2_WITH_NULL> &rhs) noexcept
+ friend inline constexpr auto operator+(const CTString<N_WITH_NULL> &lhs,
+ const CTString<N2_WITH_NULL> &rhs) noexcept
{
char data[N_WITH_NULL + N2_WITH_NULL - 1] = {};
for (size_t i = 0; i < N_WITH_NULL - 1; ++i)
data[i] = lhs[i];
for (size_t i = 0; i < N2_WITH_NULL - 1; ++i)
data[N_WITH_NULL - 1 + i] = rhs[i];
- return String<N_WITH_NULL + N2_WITH_NULL - 1>(data);
+ return CTString<N_WITH_NULL + N2_WITH_NULL - 1>(data);
}
};
+// compatibility alias until submodules are ported
+template<size_t N_WITH_NULL, typename BaseType = char>
+using String = CTString<N_WITH_NULL, BaseType>;
// Helper types that allow us to disable variadic overloads that would conflict
// with overloads that take a const char*.
template<typename T, size_t N = 0> struct IsStringType : std::false_type {};
template<> struct IsStringType<const char*, 0> : std::true_type {};
-template<size_t N> struct IsStringType<String<N>> : std::true_type {};
+template<size_t N> struct IsStringType<CTString<N>> : std::true_type {};
template<size_t N> struct IsStringType<const char[N]> : std::true_type {};
template<bool flag = false>
@@ -153,67 +156,67 @@ constexpr auto typeSignature()
using UnderlyingType = typename std::remove_extent_t<T>;
static_assert(!std::is_array_v<UnderlyingType>,
"typeSignature() does not handle multi-dimensional arrays");
- return String("[") + typeSignature<UnderlyingType>();
+ return CTString("[") + typeSignature<UnderlyingType>();
} else if constexpr (std::is_same_v<T, jobject>) {
- return String("Ljava/lang/Object;");
+ return CTString("Ljava/lang/Object;");
} else if constexpr (std::is_same_v<T, jclass>) {
- return String("Ljava/lang/Class;");
+ return CTString("Ljava/lang/Class;");
} else if constexpr (std::is_same_v<T, jstring>) {
- return String("Ljava/lang/String;");
+ return CTString("Ljava/lang/String;");
} else if constexpr (std::is_same_v<T, jobjectArray>) {
- return String("[Ljava/lang/Object;");
+ return CTString("[Ljava/lang/Object;");
} else if constexpr (std::is_same_v<T, jthrowable>) {
- return String("Ljava/lang/Throwable;");
+ return CTString("Ljava/lang/Throwable;");
} else if constexpr (std::is_same_v<T, jbooleanArray>) {
- return String("[Z");
+ return CTString("[Z");
} else if constexpr (std::is_same_v<T, jbyteArray>) {
- return String("[B");
+ return CTString("[B");
} else if constexpr (std::is_same_v<T, jshortArray>) {
- return String("[S");
+ return CTString("[S");
} else if constexpr (std::is_same_v<T, jintArray>) {
- return String("[I");
+ return CTString("[I");
} else if constexpr (std::is_same_v<T, jlongArray>) {
- return String("[J");
+ return CTString("[J");
} else if constexpr (std::is_same_v<T, jfloatArray>) {
- return String("[F");
+ return CTString("[F");
} else if constexpr (std::is_same_v<T, jdoubleArray>) {
- return String("[D");
+ return CTString("[D");
} else if constexpr (std::is_same_v<T, jcharArray>) {
- return String("[C");
+ return CTString("[C");
} else if constexpr (std::is_same_v<T, jboolean>) {
- return String("Z");
+ return CTString("Z");
} else if constexpr (std::is_same_v<T, bool>) {
- return String("Z");
+ return CTString("Z");
} else if constexpr (std::is_same_v<T, jbyte>) {
- return String("B");
+ return CTString("B");
} else if constexpr (std::is_same_v<T, jchar>) {
- return String("C");
+ return CTString("C");
} else if constexpr (std::is_same_v<T, char>) {
- return String("C");
+ return CTString("C");
} else if constexpr (std::is_same_v<T, jshort>) {
- return String("S");
+ return CTString("S");
} else if constexpr (std::is_same_v<T, short>) {
- return String("S");
+ return CTString("S");
} else if constexpr (std::is_same_v<T, jint>) {
- return String("I");
+ return CTString("I");
} else if constexpr (std::is_same_v<T, int>) {
- return String("I");
+ return CTString("I");
} else if constexpr (std::is_same_v<T, uint>) {
- return String("I");
+ return CTString("I");
} else if constexpr (std::is_same_v<T, jlong>) {
- return String("J");
+ return CTString("J");
} else if constexpr (std::is_same_v<T, long>) {
- return String("J");
+ return CTString("J");
} else if constexpr (std::is_same_v<T, jfloat>) {
- return String("F");
+ return CTString("F");
} else if constexpr (std::is_same_v<T, float>) {
- return String("F");
+ return CTString("F");
} else if constexpr (std::is_same_v<T, jdouble>) {
- return String("D");
+ return CTString("D");
} else if constexpr (std::is_same_v<T, double>) {
- return String("D");
+ return CTString("D");
} else if constexpr (std::is_same_v<T, void>) {
- return String("V");
+ return CTString("V");
}
// else: The return type becomes void, indicating that the typeSignature
@@ -232,7 +235,7 @@ template<typename T>
constexpr auto className()
{
if constexpr (std::is_same_v<T, jstring>)
- return String("java/lang/String");
+ return CTString("java/lang/String");
else
staticAssertClassNotRegistered();
}
@@ -289,9 +292,9 @@ using ValidFieldType = std::enable_if_t<
template<typename R, typename ...Args, ValidSignatureTypes<R, Args...> = true>
static constexpr auto methodSignature()
{
- return (String("(") +
+ return (CTString("(") +
... + typeSignature<q20::remove_cvref_t<Args>>())
- + String(")")
+ + CTString(")")
+ typeSignature<R>();
}
diff --git a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp
index 3ad4827f93..d7b7059bd3 100644
--- a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp
+++ b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp
@@ -21,20 +21,20 @@ struct QtJavaWrapper {};
template<>
constexpr auto QtJniTypes::typeSignature<QtJavaWrapper>()
{
- return QtJniTypes::String("Lorg/qtproject/qt/android/QtJavaWrapper;");
+ return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtJavaWrapper;");
}
template<>
constexpr auto QtJniTypes::typeSignature<QJniObject>()
{
- return QtJniTypes::String("Ljava/lang/Object;");
+ return QtJniTypes::CTString("Ljava/lang/Object;");
}
struct QtCustomJniObject : QJniObject {};
template<>
constexpr auto QtJniTypes::typeSignature<QtCustomJniObject>()
{
- return QtJniTypes::String("Lorg/qtproject/qt/android/QtCustomJniObject;");
+ return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtCustomJniObject;");
}
static_assert(QtJniTypes::typeSignature<QtJavaWrapper>() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
@@ -46,8 +46,6 @@ static_assert(QtJniTypes::typeSignature<QtJniTypes::JavaType>() == "Lorg/qtproje
Q_DECLARE_JNI_TYPE(ArrayType, "[Lorg/qtproject/qt/ArrayType;")
static_assert(QtJniTypes::typeSignature<QtJniTypes::ArrayType>() == "[Lorg/qtproject/qt/ArrayType;");
-static_assert(QtJniTypes::className<jstring>() == "java/lang/String");
-
Q_DECLARE_JNI_CLASS(QtTextToSpeech, "org/qtproject/qt/android/speech/QtTextToSpeech")
static_assert(QtJniTypes::className<QtJniTypes::QtTextToSpeech>() == "org/qtproject/qt/android/speech/QtTextToSpeech");
@@ -91,21 +89,21 @@ 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"));
-static_assert(!QtJniTypes::String("ABCDE").startsWith("ABCDEF"));
-static_assert(!QtJniTypes::String("ABCDE").startsWith("9AB"));
-static_assert(QtJniTypes::String("ABCDE").startsWith('A'));
-static_assert(!QtJniTypes::String("ABCDE").startsWith('B'));
-
-static_assert(QtJniTypes::String("ABCDE").endsWith("CDE"));
-static_assert(QtJniTypes::String("ABCDE").endsWith("E"));
-static_assert(QtJniTypes::String("ABCDE").endsWith("ABCDE"));
-static_assert(!QtJniTypes::String("ABCDE").endsWith("DEF"));
-static_assert(!QtJniTypes::String("ABCDE").endsWith("ABCDEF"));
-static_assert(QtJniTypes::String("ABCDE").endsWith('E'));
-static_assert(!QtJniTypes::String("ABCDE").endsWith('F'));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("ABC"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("A"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith("ABCDE"));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith("ABCDEF"));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith("9AB"));
+static_assert(QtJniTypes::CTString("ABCDE").startsWith('A'));
+static_assert(!QtJniTypes::CTString("ABCDE").startsWith('B'));
+
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("CDE"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("E"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith("ABCDE"));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith("DEF"));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith("ABCDEF"));
+static_assert(QtJniTypes::CTString("ABCDE").endsWith('E'));
+static_assert(!QtJniTypes::CTString("ABCDE").endsWith('F'));
void tst_QJniTypes::initTestCase()
{