7#include <QtCore/qglobal.h>
9#if defined(Q_QDOC) || defined(Q_OS_ANDROID)
19template<
size_t N_WITH_NULL,
typename BaseType =
char>
22 BaseType
m_data[N_WITH_NULL] = {};
24 constexpr String() noexcept {}
26 constexpr explicit String(
const BaseType (&
data)[N_WITH_NULL])
noexcept
28 for (
size_t i = 0;
i < N_WITH_NULL - 1; ++
i)
32 constexpr BaseType
at(
size_t i)
const {
return m_data[
i]; }
33 constexpr BaseType operator[](
size_t i)
const {
return at(
i); }
34 static constexpr size_t size() noexcept {
return N_WITH_NULL; }
35 constexpr operator const BaseType *()
const noexcept {
return m_data; }
36 constexpr const BaseType *
data() const noexcept {
return m_data; }
37 template<
size_t N2_WITH_NULL>
38 constexpr bool startsWith(
const BaseType (&lit)[N2_WITH_NULL])
const noexcept
40 if constexpr (N2_WITH_NULL > N_WITH_NULL) {
43 for (
size_t i = 0;
i < N2_WITH_NULL - 1; ++
i) {
50 constexpr bool startsWith(BaseType
c)
const noexcept
52 return N_WITH_NULL > 1 &&
m_data[0] ==
c;
54 template<
size_t N2_WITH_NULL>
55 constexpr bool endsWith(
const BaseType (&lit)[N2_WITH_NULL])
const noexcept
57 if constexpr (N2_WITH_NULL > N_WITH_NULL) {
60 for (
size_t i = 0;
i < N2_WITH_NULL; ++
i) {
61 if (
m_data[N_WITH_NULL -
i - 1] != lit[N2_WITH_NULL -
i - 1])
67 constexpr bool endsWith(BaseType
c)
const noexcept
69 return N_WITH_NULL > 1 &&
m_data[N_WITH_NULL - 2] ==
c;
72 template<
size_t N2_WITH_NULL>
73 friend inline constexpr bool operator==(
const String<N_WITH_NULL> &lhs,
74 const String<N2_WITH_NULL> &rhs)
noexcept
76 if constexpr (N_WITH_NULL != N2_WITH_NULL) {
79 for (
size_t i = 0;
i < N_WITH_NULL - 1; ++
i) {
80 if (lhs.at(
i) != rhs.at(
i))
87 template<
size_t N2_WITH_NULL>
88 friend inline constexpr bool operator!=(
const String<N_WITH_NULL> &lhs,
89 const String<N2_WITH_NULL> &rhs)
noexcept
94 template<
size_t N2_WITH_NULL>
95 friend inline constexpr bool operator==(
const String<N_WITH_NULL> &lhs,
96 const BaseType (&rhs)[N2_WITH_NULL])
noexcept
98 return operator==(lhs, String<N2_WITH_NULL>(rhs));
100 template<
size_t N2_WITH_NULL>
101 friend inline constexpr bool operator==(
const BaseType (&lhs)[N2_WITH_NULL],
102 const String<N_WITH_NULL> &rhs)
noexcept
104 return operator==(String<N2_WITH_NULL>(lhs), rhs);
107 template<
size_t N2_WITH_NULL>
108 friend inline constexpr bool operator!=(
const String<N_WITH_NULL> &lhs,
109 const BaseType (&rhs)[N2_WITH_NULL])
noexcept
111 return operator!=(lhs, String<N2_WITH_NULL>(rhs));
113 template<
size_t N2_WITH_NULL>
114 friend inline constexpr bool operator!=(
const BaseType (&lhs)[N2_WITH_NULL],
115 const String<N_WITH_NULL> &rhs)
noexcept
117 return operator!=(String<N2_WITH_NULL>(lhs), rhs);
120 template<
size_t N2_WITH_NULL>
121 friend inline constexpr auto operator+(
const String<N_WITH_NULL> &lhs,
122 const String<N2_WITH_NULL> &rhs)
noexcept
124 char data[N_WITH_NULL + N2_WITH_NULL - 1] = {};
125 for (
size_t i = 0;
i < N_WITH_NULL - 1; ++
i)
127 for (
size_t i = 0;
i < N2_WITH_NULL - 1; ++
i)
128 data[N_WITH_NULL - 1 +
i] = rhs[
i];
129 return String<N_WITH_NULL + N2_WITH_NULL - 1>(
data);
136template<
typename T,
size_t N = 0>
struct IsStringType : std::false_type {};
137template<>
struct IsStringType<const char*, 0> : std::true_type {};
138template<
size_t N>
struct IsStringType<
String<
N>> : std::true_type {};
139template<
size_t N>
struct IsStringType<const char[
N]> : std::true_type {};
141template<
bool flag = false>
142static void staticAssertTypeMismatch()
144 static_assert(flag,
"The used type is not supported by this template call. "
145 "Use a JNI based type instead.");
149constexpr auto typeSignature()
151 if constexpr(std::is_array_v<T>) {
152 using UnderlyingType =
typename std::remove_extent<T>::type;
153 static_assert(!std::is_array_v<UnderlyingType>,
154 "typeSignature() does not handle multi-dimensional arrays");
155 return String(
"[") + typeSignature<UnderlyingType>();
156 }
else if constexpr(std::is_same_v<T, jobject>) {
157 return String(
"Ljava/lang/Object;");
158 }
else if constexpr(std::is_same_v<T, jclass>) {
159 return String(
"Ljava/lang/Class;");
160 }
else if constexpr(std::is_same_v<T, jstring>) {
161 return String(
"Ljava/lang/String;");
162 }
else if constexpr(std::is_same_v<T, jobjectArray>) {
163 return String(
"[Ljava/lang/Object;");
164 }
else if constexpr(std::is_same_v<T, jthrowable>) {
165 return String(
"Ljava/lang/Throwable;");
166 }
else if constexpr(std::is_same_v<T, jbooleanArray>) {
168 }
else if constexpr(std::is_same_v<T, jbyteArray>) {
170 }
else if constexpr(std::is_same_v<T, jshortArray>) {
172 }
else if constexpr(std::is_same_v<T, jintArray>) {
174 }
else if constexpr(std::is_same_v<T, jlongArray>) {
176 }
else if constexpr(std::is_same_v<T, jfloatArray>) {
178 }
else if constexpr(std::is_same_v<T, jdoubleArray>) {
180 }
else if constexpr(std::is_same_v<T, jcharArray>) {
182 }
else if constexpr(std::is_same_v<T, jboolean>) {
184 }
else if constexpr(std::is_same_v<T, bool>) {
186 }
else if constexpr(std::is_same_v<T, jbyte>) {
188 }
else if constexpr(std::is_same_v<T, jchar>) {
190 }
else if constexpr(std::is_same_v<T, char>) {
192 }
else if constexpr(std::is_same_v<T, jshort>) {
194 }
else if constexpr(std::is_same_v<T, short>) {
196 }
else if constexpr(std::is_same_v<T, jint>) {
198 }
else if constexpr(std::is_same_v<T, int>) {
200 }
else if constexpr(std::is_same_v<T, uint>) {
202 }
else if constexpr(std::is_same_v<T, jlong>) {
204 }
else if constexpr(std::is_same_v<T, long>) {
206 }
else if constexpr(std::is_same_v<T, jfloat>) {
208 }
else if constexpr(std::is_same_v<T, float>) {
210 }
else if constexpr(std::is_same_v<T, jdouble>) {
212 }
else if constexpr(std::is_same_v<T, double>) {
214 }
else if constexpr(std::is_same_v<T, void>) {
216 }
else if constexpr(IsStringType<T>::value) {
217 static_assert(!IsStringType<T>::value,
"Don't use a literal type, call data!");
219 staticAssertTypeMismatch();
223template<
bool flag = false>
224static void staticAssertClassNotRegistered()
226 static_assert(flag,
"Class not registered, use Q_DECLARE_JNI_CLASS");
232 if constexpr(std::is_same<T, jstring>::value)
233 return String(
"java/lang/String");
235 staticAssertClassNotRegistered();
241 return typeSignature<T>().size() == 2;
245static constexpr bool isObjectType()
247 if constexpr(std::is_convertible<T, jobject>::value) {
250 constexpr auto signature = typeSignature<T>();
257static constexpr bool isArrayType()
259 constexpr auto signature = typeSignature<T>();
264static constexpr void assertPrimitiveType()
266 static_assert(isPrimitiveType<T>(),
"Type needs to be a primitive JNI type!");
272 static_assert(isObjectType<T>(),
273 "Type needs to be a JNI object type (convertible to jobject, or with "
274 "an object type signature registered)!");
278static constexpr void assertType()
280 static_assert(isPrimitiveType<T>() || isObjectType<T>(),
281 "Type needs to be a JNI type!");
284template<
typename R,
typename ...Args>
285static constexpr auto methodSignature()
288 ... + typeSignature<std::decay_t<Args>>())
290 + typeSignature<R>();
294static constexpr auto fieldSignature()
296 return QtJniTypes::typeSignature<T>();
299template<
typename ...Args>
300static constexpr auto constructorSignature()
302 return methodSignature<
void, Args...>();
305template<
typename Ret,
typename ...Args>
306static constexpr auto nativeMethodSignature(Ret (*)(JNIEnv *, jobject, Args...))
308 return methodSignature<Ret, Args...>();
311template<
typename Ret,
typename ...Args>
312static constexpr auto nativeMethodSignature(Ret (*)(JNIEnv *, jclass, Args...))
314 return methodSignature<Ret, Args...>();
324 constexpr operator jobject()
const {
return _object; }
329#define Q_DECLARE_JNI_TYPE_HELPER(Type) \
330namespace QtJniTypes { \
331struct Type : Object \
333 constexpr Type(jobject o) noexcept : Object{o} {} \
338#define Q_DECLARE_JNI_TYPE(Type, Signature) \
339Q_DECLARE_JNI_TYPE_HELPER(Type) \
341constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
343 static_assert((Signature[0] == 'L' || Signature[0] == '[') \
344 && Signature[sizeof(Signature) - 2] == ';', \
345 "Type signature needs to start with 'L' or '['" \
346 " and end with ';'"); \
347 return QtJniTypes::String(Signature); \
350#define Q_DECLARE_JNI_CLASS(Type, Signature) \
351Q_DECLARE_JNI_TYPE_HELPER(Type) \
353constexpr auto QtJniTypes::className<QtJniTypes::Type>() \
355 return QtJniTypes::String(Signature); \
358constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
360 return QtJniTypes::String("L") \
361 + QtJniTypes::String(Signature) \
362 + QtJniTypes::String(";"); \
365#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
366 QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD, __VA_ARGS__) \
368#define QT_DECLARE_JNI_NATIVE_METHOD_2(Method, Name) \
369namespace QtJniMethods { \
370static constexpr auto Method##_signature = \
371 QtJniTypes::nativeMethodSignature(Method); \
372static const JNINativeMethod Method##_method = { \
373 #Name, Method##_signature.data(), \
374 reinterpret_cast<void *>(Method) \
378#define QT_DECLARE_JNI_NATIVE_METHOD_1(Method) \
379 QT_DECLARE_JNI_NATIVE_METHOD_2(Method, Method) \
381#define Q_JNI_NATIVE_METHOD(Method) QtJniMethods::Method##_method
383#define Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(...) \
384 QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE, __VA_ARGS__) \
386#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Name) \
387 static inline constexpr auto Method##_signature = QtJniTypes::nativeMethodSignature(Method); \
388 static inline const JNINativeMethod Method##_method = { \
389 #Name, Method##_signature.data(), reinterpret_cast<void *>(Method) \
392#define QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_1(Method) \
393 QT_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE_2(Method, Method) \
395#define Q_JNI_NATIVE_SCOPED_METHOD(Method, Scope) Scope::Method##_method
Combined button and popup list for selecting options.
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
void assertObjectType(QObjectPrivate *d)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
constexpr bool operator!=(const timespec &t1, const timespec &t2)
constexpr timespec operator+(const timespec &t1, const timespec &t2)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
static QT_BEGIN_NAMESPACE bool isPrimitiveType(QMetaType metaType)
bool operator==(const QRandomGenerator &rng1, const QRandomGenerator &rng2)
const char className[16]
[1]