File indexing completed on 2024-06-23 05:08:44
0001 /* 0002 SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KANDROIDEXTRAS_JNISIGNATURE_H 0008 #define KANDROIDEXTRAS_JNISIGNATURE_H 0009 0010 #include "jnitypes.h" 0011 0012 #include "jni.h" 0013 #include <cstdint> 0014 #include <utility> 0015 0016 namespace KAndroidExtras { 0017 0018 namespace Jni { 0019 template <typename T> class Array; 0020 } 0021 0022 /** @cond internal */ 0023 namespace Internal { 0024 0025 /** Compile-time concat-able string. */ 0026 template <char... String> 0027 struct StaticString { 0028 inline operator const char*() const 0029 { 0030 static const char data[] = { String..., 0 }; 0031 return data; 0032 } 0033 }; 0034 0035 /** Compile-time strlen. */ 0036 constexpr inline int static_strlen(const char *str) 0037 { 0038 return str[0] == '\0' ? 0 : static_strlen(str + 1) + 1; 0039 } 0040 0041 /** Compile-time concat for two StaticString. */ 0042 template <char... String1, char... String2> 0043 constexpr inline auto static_concat(const StaticString<String1...>&, const StaticString<String2...>&) 0044 { 0045 return StaticString<String1..., String2...>(); 0046 } 0047 0048 /** Compile-time concept for N StaticString. */ 0049 template <typename String1, typename String2, class... Strings> 0050 constexpr inline auto static_concat(const String1& str1, const String2& str2, const Strings&... strs) 0051 { 0052 return static_concat(static_concat(str1, str2), strs...); 0053 } 0054 0055 /** Conversion from const char* literals to StaticString. */ 0056 template <typename, typename> struct staticStringFromJniType; 0057 template <typename T, std::size_t... Indexes> 0058 struct staticStringFromJniType<T, std::index_sequence<Indexes...>> 0059 { 0060 typedef StaticString<Jni::typeName<T>()[Indexes]...> value; 0061 }; 0062 0063 /** Meta function for assembling JNI signatures. */ 0064 template <typename T> 0065 struct JniSignature 0066 { 0067 constexpr inline auto operator()() const 0068 { 0069 using namespace Internal; 0070 return static_concat(StaticString<'L'>(), typename staticStringFromJniType<T, std::make_index_sequence<static_strlen(Jni::typeName<T>())>>::value(), StaticString<';'>()); 0071 } 0072 }; 0073 0074 template <> struct JniSignature<jboolean> { constexpr inline auto operator()() const { return StaticString<'Z'>(); } }; 0075 template <> struct JniSignature<jbyte> { constexpr inline auto operator()() const { return StaticString<'B'>(); } }; 0076 template <> struct JniSignature<jchar> { constexpr inline auto operator()() const { return StaticString<'C'>(); } }; 0077 template <> struct JniSignature<jshort> { constexpr inline auto operator()() const { return StaticString<'S'>(); } }; 0078 template <> struct JniSignature<jint> { constexpr inline auto operator()() const { return StaticString<'I'>(); } }; 0079 template <> struct JniSignature<jlong> { constexpr inline auto operator()() const { return StaticString<'J'>(); } }; 0080 template <> struct JniSignature<jfloat> { constexpr inline auto operator()() const { return StaticString<'F'>(); } }; 0081 template <> struct JniSignature<jdouble> { constexpr inline auto operator()() const { return StaticString<'D'>(); } }; 0082 template <> struct JniSignature<void> { constexpr inline auto operator()() const { return StaticString<'V'>(); } }; 0083 // special case due to jboolean != bool 0084 template <> struct JniSignature<bool> { constexpr inline auto operator()() const { return StaticString<'Z'>(); } }; 0085 0086 template <typename T> 0087 struct JniSignature<T*> 0088 { 0089 constexpr inline auto operator()() const 0090 { 0091 using namespace Internal; 0092 return static_concat(StaticString<'['>(), JniSignature<T>()()); 0093 } 0094 }; 0095 0096 template <typename T> 0097 struct JniSignature<Jni::Array<T>> 0098 { 0099 constexpr inline auto operator()() const 0100 { 0101 using namespace Internal; 0102 return static_concat(StaticString<'['>(), JniSignature<T>()()); 0103 } 0104 }; 0105 0106 template <typename RetT, typename... Args> 0107 struct JniSignature<RetT(Args...)> 0108 { 0109 constexpr inline auto operator()() const 0110 { 0111 using namespace Internal; 0112 return static_concat(StaticString<'('>(), JniSignature<Args>()()..., StaticString<')'>(), JniSignature<RetT>()()); 0113 } 0114 }; 0115 } 0116 /** @endcond */ 0117 0118 /** Helper methods to deal with JNI. */ 0119 namespace Jni 0120 { 0121 /** Returns the JNI signature string for the template argument types. */ 0122 template <typename... Args> constexpr __attribute__((__unused__)) Internal::JniSignature<Args...> signature = {}; 0123 } 0124 0125 } 0126 0127 #endif // KANDROIDEXTRAS_JNISIGNATURE_H