@@ -11,88 +11,126 @@ namespace jni
11
11
template < class TheTag , class > class Field ;
12
12
template < class TheTag , class > class Method ;
13
13
14
- struct ObjectTag { static constexpr auto Name () { return " java/lang/Object" ; } };
14
+ struct ObjectTag
15
+ {
16
+ static constexpr auto Name () { return " java/lang/Object" ; }
17
+ };
18
+
19
+ struct StringTag
20
+ {
21
+ using SuperTag = ObjectTag;
22
+ static constexpr auto Name () { return " java/lang/String" ; }
23
+ };
24
+
25
+ class ObjectBase
26
+ {
27
+ protected:
28
+ jobject* ptr = nullptr ;
29
+
30
+ explicit ObjectBase (std::nullptr_t = nullptr )
31
+ {}
32
+
33
+ explicit ObjectBase (jobject* p)
34
+ : ptr(p)
35
+ {}
36
+
37
+ ~ObjectBase () = default ;
38
+
39
+ void reset (jobject* p) { ptr = p; }
40
+
41
+ public:
42
+ explicit operator bool () const { return ptr; }
43
+
44
+ friend bool operator ==(const ObjectBase& a, const ObjectBase& b) { return a.ptr == b.ptr ; }
45
+ friend bool operator !=(const ObjectBase& a, const ObjectBase& b) { return !( a == b ); }
46
+
47
+ template < class OtherTag >
48
+ bool IsInstanceOf (JNIEnv& env, const Class<OtherTag>& clazz) const
49
+ {
50
+ return jni::IsInstanceOf (env, ptr, clazz);
51
+ }
52
+ };
53
+
54
+ template < class Tag , class Enable = void >
55
+ struct SuperObject ;
15
56
16
- template < class TagType >
17
- struct UntaggedObjectType { using Type = jobject; };
57
+ template < class Tag >
58
+ struct SuperObject <Tag, typename Tag::SuperTag>
59
+ {
60
+ using Type = Object<typename Tag::SuperTag>;
61
+ };
62
+
63
+ template < class Tag >
64
+ struct SuperObject <Tag>
65
+ {
66
+ using Type = Object<ObjectTag>;
67
+ };
68
+
69
+ template <>
70
+ struct SuperObject <ObjectTag>
71
+ {
72
+ using Type = ObjectBase;
73
+ };
18
74
19
75
template < class TheTag = ObjectTag >
20
- class Object
76
+ class Object : public SuperObject <TheTag>::Type
21
77
{
22
78
public:
23
79
using TagType = TheTag;
24
- using UntaggedObjectType = typename UntaggedObjectType<TagType>::Type;
25
-
26
- private:
27
- UntaggedObjectType* obj = nullptr ;
80
+ using UntaggedType = std::conditional_t < std::is_same< TheTag, StringTag >::value, jstring, jobject >;
28
81
29
82
protected:
30
83
explicit Object (std::nullptr_t = nullptr )
31
84
{}
32
85
33
- explicit Object (UntaggedObjectType* o )
34
- : obj(o )
86
+ explicit Object (UntaggedType* p )
87
+ : SuperObject<TagType>::Type(p )
35
88
{}
36
89
37
- Object (const Object& o)
38
- : obj(o.obj)
39
- {}
40
-
41
- template < class Tag >
42
- Object (const Object<Tag>& o, std::enable_if_t < std::is_convertible<Tag, TagType>::value >* = nullptr )
43
- : obj(o.Get())
44
- {}
45
-
46
- ~Object () = default ;
47
-
90
+ Object (const Object&) = delete ;
48
91
Object& operator =(const Object&) = delete ;
49
- void reset (UntaggedObjectType* o) { obj = o; }
50
92
51
93
public:
52
- explicit operator bool () const { return obj; }
53
-
54
- operator UntaggedObjectType*() const { return obj; }
55
- UntaggedObjectType& operator *() const { return *obj; }
56
- UntaggedObjectType* Get () const { return obj; }
94
+ UntaggedType* Get () const { return reinterpret_cast <UntaggedType*>(this ->ptr ); }
57
95
58
- friend bool operator ==( const Object& a, const Object& b ) { return a. Get () == b. Get (); }
59
- friend bool operator !=( const Object& a, const Object& b ) { return !( a == b ); }
96
+ operator UntaggedType*() const { return Get (); }
97
+ UntaggedType& operator *() const { return * Get ( ); }
60
98
61
99
template < class T >
62
100
auto Get (JNIEnv& env, const Field<TagType, T>& field) const
63
101
-> std::enable_if_t< IsPrimitive<T>::value, T >
64
102
{
65
- return GetField<T>(env, obj , field);
103
+ return GetField<T>(env, this -> ptr , field);
66
104
}
67
105
68
106
template < class T >
69
107
auto Get (JNIEnv& env, const Field<TagType, T>& field) const
70
108
-> std::enable_if_t< !IsPrimitive<T>::value, Local<T> >
71
109
{
72
- return Local<T>(env, reinterpret_cast <UntaggedType<T>> (GetField<jobject*>(env, obj , field)));
110
+ return Local<T>(env, reinterpret_cast <typename T::UntaggedType*> (GetField<jobject*>(env, this -> ptr , field)));
73
111
}
74
112
75
113
template < class T >
76
114
auto Set (JNIEnv& env, const Field<TagType, T>& field, T value) const
77
115
-> std::enable_if_t< IsPrimitive<T>::value >
78
116
{
79
- SetField<T>(env, obj , field, value);
117
+ SetField<T>(env, this -> ptr , field, value);
80
118
}
81
119
82
120
template < class Expected , class Actual >
83
121
auto Set (JNIEnv& env, const Field<TagType, Expected>& field, const Actual& value) const
84
122
-> std::enable_if_t< !IsPrimitive<Expected>::value
85
123
&& std::is_convertible<const Actual&, const Expected&>::value >
86
124
{
87
- SetField<jobject*>(env, obj , field, value.Get ());
125
+ SetField<jobject*>(env, this -> ptr , field, value.Get ());
88
126
}
89
127
90
128
template < class R , class ... ExpectedArgs, class ... ActualArgs >
91
129
auto Call (JNIEnv& env, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
92
130
-> std::enable_if_t< IsPrimitive<R>::value
93
131
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, R >
94
132
{
95
- return CallMethod<R>(env, obj , method, Untag (args)...);
133
+ return CallMethod<R>(env, this -> ptr , method, Untag (args)...);
96
134
}
97
135
98
136
template < class R , class ... ExpectedArgs, class ... ActualArgs >
@@ -101,22 +139,22 @@ namespace jni
101
139
&& !std::is_void<R>::value
102
140
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, Local<R> >
103
141
{
104
- return Local<R>(env, reinterpret_cast <UntaggedType<R>> (CallMethod<jobject*>(env, obj , method, Untag (args)...)));
142
+ return Local<R>(env, reinterpret_cast <typename R::UntaggedType*> (CallMethod<jobject*>(env, this -> ptr , method, Untag (args)...)));
105
143
}
106
144
107
145
template < class ... ExpectedArgs, class ... ActualArgs >
108
146
auto Call (JNIEnv& env, const Method<TagType, void (ExpectedArgs...)>& method, const ActualArgs&... args) const
109
147
-> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value >
110
148
{
111
- CallMethod<void >(env, obj , method, Untag (args)...);
149
+ CallMethod<void >(env, this -> ptr , method, Untag (args)...);
112
150
}
113
151
114
152
template < class R , class ... ExpectedArgs, class ... ActualArgs >
115
153
auto CallNonvirtual (JNIEnv& env, const Class<TagType>& clazz, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
116
154
-> std::enable_if_t< IsPrimitive<R>::value
117
155
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, R >
118
156
{
119
- return CallNonvirtualMethod<R>(env, obj , clazz, method, Untag (args)...);
157
+ return CallNonvirtualMethod<R>(env, this -> ptr , clazz, method, Untag (args)...);
120
158
}
121
159
122
160
template < class R , class ... ExpectedArgs, class ... ActualArgs >
@@ -125,37 +163,31 @@ namespace jni
125
163
&& !std::is_void<R>::value
126
164
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, Local<R> >
127
165
{
128
- return Local<R>(env, reinterpret_cast <UntaggedType<R>> (CallNonvirtualMethod<jobject*>(env, obj , clazz, method, Untag (args)...)));
166
+ return Local<R>(env, reinterpret_cast <typename R::UntaggedType*> (CallNonvirtualMethod<jobject*>(env, this -> ptr , clazz, method, Untag (args)...)));
129
167
}
130
168
131
169
template < class ... ExpectedArgs, class ... ActualArgs >
132
170
auto CallNonvirtual (JNIEnv& env, const Class<TagType>& clazz, const Method<TagType, void (ExpectedArgs...)>& method, const ActualArgs&... args) const
133
171
-> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value >
134
172
{
135
- CallNonvirtualMethod<void >(env, obj , clazz, method, Untag (args)...);
173
+ CallNonvirtualMethod<void >(env, this -> ptr , clazz, method, Untag (args)...);
136
174
}
137
175
138
176
template < template < RefDeletionMethod > class Deleter = DefaultRefDeleter >
139
177
Global<Object<TagType>, Deleter> NewGlobalRef (JNIEnv& env) const
140
178
{
141
- return Global<Object<TagType>, Deleter>(env, jni::NewGlobalRef (env, obj ).release ());
179
+ return Global<Object<TagType>, Deleter>(env, reinterpret_cast < typename Object<TagType>::UntaggedType*>( jni::NewGlobalRef (env, this -> ptr ).release () ));
142
180
}
143
181
144
182
template < template < RefDeletionMethod > class Deleter = DefaultRefDeleter >
145
183
Weak<Object<TagType>, Deleter> NewWeakGlobalRef (JNIEnv& env) const
146
184
{
147
- return Weak<Object<TagType>, Deleter>(env, jni::NewWeakGlobalRef (env, obj ).release ());
185
+ return Weak<Object<TagType>, Deleter>(env, reinterpret_cast < typename Object<TagType>::UntaggedType*>( jni::NewWeakGlobalRef (env, this -> ptr ).release () ));
148
186
}
149
187
150
188
Local<Object<TagType>> NewLocalRef (JNIEnv& env) const
151
189
{
152
- return Local<Object<TagType>>(env, jni::NewLocalRef (env, obj).release ());
153
- }
154
-
155
- template < class OtherTag >
156
- bool IsInstanceOf (JNIEnv& env, const Class<OtherTag>& clazz) const
157
- {
158
- return jni::IsInstanceOf (env, obj, clazz);
190
+ return Local<Object<TagType>>(env, reinterpret_cast <typename Object<TagType>::UntaggedType*>(jni::NewLocalRef (env, this ->ptr ).release ()));
159
191
}
160
192
};
161
193
@@ -166,6 +198,6 @@ namespace jni
166
198
{
167
199
ThrowNew (env, FindClass (env, " java/lang/ClassCastException" ));
168
200
}
169
- return Local<Object<OutTagType>>(env, reinterpret_cast <UntaggedType< Object<OutTagType>>> (object.NewLocalRef ().release ()));
201
+ return Local<Object<OutTagType>>(env, reinterpret_cast <typename Object<OutTagType>::UntaggedType*> (object.NewLocalRef (env ).release ()));
170
202
}
171
203
}
0 commit comments