|
4 | 4 | #include <jni/object.hpp>
|
5 | 5 | #include <jni/array.hpp>
|
6 | 6 |
|
7 |
| -#include <initializer_list> |
8 |
| -#include <string> |
9 |
| - |
10 | 7 | namespace jni
|
11 | 8 | {
|
| 9 | + template < char... chars > |
| 10 | + struct StringLiteral |
| 11 | + { |
| 12 | + operator const char *() const |
| 13 | + { |
| 14 | + static const char result[] = { chars..., 0 }; |
| 15 | + return result; |
| 16 | + } |
| 17 | + }; |
| 18 | + |
| 19 | + constexpr std::size_t StringLiteralLength(const char * str, std::size_t len = 0) |
| 20 | + { |
| 21 | + return str[0] ? StringLiteralLength(str + 1, len + 1) : len; |
| 22 | + } |
| 23 | + |
| 24 | + template < class, class > |
| 25 | + struct TagLiteralImpl; |
| 26 | + |
| 27 | + template < class Tag, std::size_t... Is > |
| 28 | + struct TagLiteralImpl< Tag, std::index_sequence<Is...> > |
| 29 | + { |
| 30 | + using Value = StringLiteral< Tag::Name()[Is]... >; |
| 31 | + }; |
| 32 | + |
| 33 | + template < class Tag > |
| 34 | + using TagLiteral = typename TagLiteralImpl< Tag, std::make_index_sequence<StringLiteralLength(Tag::Name())> >::Value; |
| 35 | + |
| 36 | + template < char... As, char... Bs > |
| 37 | + constexpr auto Concat(const StringLiteral<As...>&, |
| 38 | + const StringLiteral<Bs...>&) |
| 39 | + { |
| 40 | + return StringLiteral<As..., Bs...>(); |
| 41 | + } |
| 42 | + |
| 43 | + template < class A, class B, class... Rest > |
| 44 | + constexpr auto Concat(const A& a, |
| 45 | + const B& b, |
| 46 | + const Rest&... rest) |
| 47 | + { |
| 48 | + return Concat(Concat(a, b), rest...); |
| 49 | + } |
| 50 | + |
12 | 51 | template < class > struct TypeSignature;
|
13 | 52 |
|
14 |
| - template <> struct TypeSignature< jboolean > { const char * operator()() const { return "Z"; } }; |
15 |
| - template <> struct TypeSignature< jbyte > { const char * operator()() const { return "B"; } }; |
16 |
| - template <> struct TypeSignature< jchar > { const char * operator()() const { return "C"; } }; |
17 |
| - template <> struct TypeSignature< jshort > { const char * operator()() const { return "S"; } }; |
18 |
| - template <> struct TypeSignature< jint > { const char * operator()() const { return "I"; } }; |
19 |
| - template <> struct TypeSignature< jlong > { const char * operator()() const { return "J"; } }; |
20 |
| - template <> struct TypeSignature< jfloat > { const char * operator()() const { return "F"; } }; |
21 |
| - template <> struct TypeSignature< jdouble > { const char * operator()() const { return "D"; } }; |
22 |
| - template <> struct TypeSignature< void > { const char * operator()() const { return "V"; } }; |
| 53 | + template <> struct TypeSignature< jboolean > { constexpr auto operator()() const { return StringLiteral<'Z'>(); } }; |
| 54 | + template <> struct TypeSignature< jbyte > { constexpr auto operator()() const { return StringLiteral<'B'>(); } }; |
| 55 | + template <> struct TypeSignature< jchar > { constexpr auto operator()() const { return StringLiteral<'C'>(); } }; |
| 56 | + template <> struct TypeSignature< jshort > { constexpr auto operator()() const { return StringLiteral<'S'>(); } }; |
| 57 | + template <> struct TypeSignature< jint > { constexpr auto operator()() const { return StringLiteral<'I'>(); } }; |
| 58 | + template <> struct TypeSignature< jlong > { constexpr auto operator()() const { return StringLiteral<'J'>(); } }; |
| 59 | + template <> struct TypeSignature< jfloat > { constexpr auto operator()() const { return StringLiteral<'F'>(); } }; |
| 60 | + template <> struct TypeSignature< jdouble > { constexpr auto operator()() const { return StringLiteral<'D'>(); } }; |
| 61 | + template <> struct TypeSignature< void > { constexpr auto operator()() const { return StringLiteral<'V'>(); } }; |
23 | 62 |
|
24 | 63 | template < class TheTag >
|
25 | 64 | struct TypeSignature< Object<TheTag> >
|
26 | 65 | {
|
27 |
| - const char * operator()() const |
| 66 | + constexpr auto operator()() const |
28 | 67 | {
|
29 |
| - static std::string value { std::string("L") + TheTag::Name() + ";" }; |
30 |
| - return value.c_str(); |
| 68 | + return Concat(StringLiteral<'L'>(), TagLiteral<TheTag>(), StringLiteral<';'>()); |
31 | 69 | }
|
32 | 70 | };
|
33 | 71 |
|
34 | 72 | template < class E >
|
35 | 73 | struct TypeSignature< Array<E> >
|
36 | 74 | {
|
37 |
| - const char * operator()() const |
| 75 | + constexpr auto operator()() const |
38 | 76 | {
|
39 |
| - static std::string value { std::string("[") + TypeSignature<E>()() }; |
40 |
| - return value.c_str(); |
| 77 | + return Concat(StringLiteral<'['>(), TypeSignature<E>()()); |
41 | 78 | }
|
42 | 79 | };
|
43 | 80 |
|
44 | 81 | template < class R, class... Args >
|
45 | 82 | struct TypeSignature< R (Args...) >
|
46 | 83 | {
|
47 |
| - private: |
48 |
| - template < class T > void DoNothingWith(const std::initializer_list<T>&) const {} |
49 |
| - |
50 |
| - std::string Compute() const |
51 |
| - { |
52 |
| - static std::string result("("); |
53 |
| - DoNothingWith<int>( { ( result += TypeSignature<Args>()(), 0 )... } ); |
54 |
| - result += ")"; |
55 |
| - result += TypeSignature<R>()(); |
56 |
| - return result; |
57 |
| - } |
58 |
| - |
59 |
| - public: |
60 |
| - const char * operator()() const |
61 |
| - { |
62 |
| - static std::string result = Compute(); |
63 |
| - return result.c_str(); |
64 |
| - } |
| 84 | + constexpr auto operator()() const |
| 85 | + { |
| 86 | + return Concat(StringLiteral<'('>(), TypeSignature<Args>()()..., StringLiteral<')'>(), TypeSignature<R>()()); |
| 87 | + } |
65 | 88 | };
|
66 | 89 | }
|
0 commit comments