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>
This commit is contained in:
parent
dc126de22e
commit
0022b05a9a
@ -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(...) \
|
||||
|
@ -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>();
|
||||
}
|
||||
|
||||
|
@ -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::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::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").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()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user