|
1 | 1 | #pragma once
|
2 | 2 |
|
3 | 3 | #include <jni/traits.hpp>
|
| 4 | +#include <jni/unique.hpp> |
4 | 5 |
|
5 | 6 | #include <type_traits>
|
6 | 7 |
|
@@ -89,164 +90,6 @@ namespace jni
|
89 | 90 | };
|
90 | 91 |
|
91 | 92 |
|
92 |
| - /* |
93 |
| - The interface for high-level references. Client code using the high-level API |
94 |
| - will most often work with values of this class template, using the following aliases: |
95 |
| -
|
96 |
| - * Global<P>, a.k.a. Tagged<T, DefaultRefDeleter<&JNIEnv::DeleteGlobalRef>>, |
97 |
| - * Weak<P>, a.k.a. Tagged<T, DefaultRefDeleter<&JNIEnv::DeleteWeakGlobalRef>>, |
98 |
| - * Local<P>, a.k.a. Tagged<T, LocalRefDeleter>, |
99 |
| -
|
100 |
| - where P is Object<>, Class<>, or Array<>. |
101 |
| -
|
102 |
| - `Tagged` is an ownership class with a deletion policy that's parameterized both |
103 |
| - by the appropriate method to delete the reference (global, weak, or local) and |
104 |
| - (for global and weak references), a choice about how to obtain the JNIEnv that's |
105 |
| - necessary to call the deletion method. The default policy is to delete the reference |
106 |
| - using the same JNIEnv as was passed to the constructor, but in cases where the |
107 |
| - object may be deleted on a different thread (commonly, the Java finalizer thread), |
108 |
| - EnvGettingDeleter or EnvAttachingDeleter may be needed. |
109 |
| -
|
110 |
| - Object<>, Class<>, or Array<> -- the underlying and inherited types used for |
111 |
| - the template parameter T -- are not publicly constructible or destructible. This |
112 |
| - is to ensure that code works only with ownership types which release the reference |
113 |
| - at an appropriate time. Our experience has shown that this is important even for |
114 |
| - local references; the default JVM cleanup behaviors for local references are not |
115 |
| - enough to ensure that the local reference table never overflows. |
116 |
| -
|
117 |
| - In some cases C++ references -- Object<>&, const Class<>&, or Array<>& -- are used. |
118 |
| - For example, this is the case for receiving parameters passed to a native method |
119 |
| - implementation, reflecting the fact that JVM implementations prohibit explicitly |
120 |
| - releasing this form of local reference. You may also pass C++ references to code |
121 |
| - that does not need to take ownership. However, if you need to store or copy the |
122 |
| - reference, you will need to use a method such as `NewGlobalRef` that copies at the |
123 |
| - reference level -- `Tagged`, `Object<>`, etc., are not themselves copyable. |
124 |
| - */ |
125 |
| - template < class T, class D > |
126 |
| - class Tagged : public T |
127 |
| - { |
128 |
| - private: |
129 |
| - D deleter; |
130 |
| - |
131 |
| - Tagged(const Tagged&) = delete; |
132 |
| - Tagged& operator=(const Tagged&) = delete; |
133 |
| - |
134 |
| - public: |
135 |
| - using Base = T; |
136 |
| - using UntaggedType = typename T::UntaggedType; |
137 |
| - |
138 |
| - explicit Tagged(std::nullptr_t ptr = nullptr) |
139 |
| - : T(ptr), |
140 |
| - deleter() {} |
141 |
| - |
142 |
| - explicit Tagged(JNIEnv& env, UntaggedType* ptr) |
143 |
| - : T(ptr), |
144 |
| - deleter(env) {} |
145 |
| - |
146 |
| - Tagged(Tagged&& other) |
147 |
| - : T(other.release()), |
148 |
| - deleter(std::move(other.get_deleter())) {} |
149 |
| - |
150 |
| - template < class U > |
151 |
| - Tagged(Tagged<U, D>&& other, std::enable_if_t<std::is_convertible<const U&, const T&>::value>* = nullptr) |
152 |
| - : T(other.release()), |
153 |
| - deleter(std::move(other.get_deleter())) {} |
154 |
| - |
155 |
| - ~Tagged() |
156 |
| - { |
157 |
| - reset(); |
158 |
| - } |
159 |
| - |
160 |
| - Tagged& operator=(Tagged&& other) |
161 |
| - { |
162 |
| - reset(other.release()); |
163 |
| - deleter = std::move(other.deleter); |
164 |
| - return *this; |
165 |
| - } |
166 |
| - |
167 |
| - void reset(UntaggedType* ptr = nullptr) |
168 |
| - { |
169 |
| - UntaggedType* current = this->get(); |
170 |
| - T::reset(ptr); |
171 |
| - if (current) |
172 |
| - { |
173 |
| - get_deleter()(current); |
174 |
| - } |
175 |
| - } |
176 |
| - |
177 |
| - UntaggedType* release() |
178 |
| - { |
179 |
| - UntaggedType* current = this->get(); |
180 |
| - T::reset(nullptr); |
181 |
| - return current; |
182 |
| - } |
183 |
| - |
184 |
| - D& get_deleter() { return deleter; } |
185 |
| - const D& get_deleter() const { return deleter; } |
186 |
| - }; |
187 |
| - |
188 |
| - |
189 |
| - template < class T, template < RefDeletionMethod > class Deleter = DefaultRefDeleter > |
190 |
| - using Global = Tagged< T, Deleter<&JNIEnv::DeleteGlobalRef> >; |
191 |
| - |
192 |
| - template < class T, template < RefDeletionMethod > class Deleter = DefaultRefDeleter > |
193 |
| - using Weak = Tagged< T, Deleter<&JNIEnv::DeleteWeakGlobalRef> >; |
194 |
| - |
195 |
| - // Not parameterized by Deleter because local references should be short-lived enough |
196 |
| - // that DefaultRefDeleter suffices in all cases. |
197 |
| - template < class T > |
198 |
| - using Local = Tagged< T, DefaultRefDeleter<&JNIEnv::DeleteLocalRef> >; |
199 |
| - |
200 |
| - |
201 |
| - // Special case for JNI-provided input parameters to native methods, which apparently |
202 |
| - // should not be explicitly deleted (https://bugs.chromium.org/p/chromium/issues/detail?id=506850). |
203 |
| - struct NullDeleter |
204 |
| - { |
205 |
| - NullDeleter() = default; |
206 |
| - NullDeleter(JNIEnv&) {} |
207 |
| - void operator()(jobject*) const {} |
208 |
| - }; |
209 |
| - |
210 |
| - template < class T > |
211 |
| - using Input = Tagged< T, NullDeleter >; |
212 |
| - |
213 |
| - |
214 |
| - // Attempt to promote a weak reference to a strong one. Returns an empty result |
215 |
| - // if the weak reference has expired. |
216 |
| - // |
217 |
| - // Beware that the semantics of JNI weak references are weaker than is typically |
218 |
| - // desired: a JNI weak reference may still be promoted to a non-null strong reference |
219 |
| - // even during finalization. Consider using jni::WeakReference<T> instead. |
220 |
| - template < template < RefDeletionMethod > class Deleter, class T, template < RefDeletionMethod > class WeakDeleter > |
221 |
| - Global<T, Deleter> NewGlobal(JNIEnv& env, const Weak<T, WeakDeleter>& t) |
222 |
| - { |
223 |
| - jobject* obj = Wrap<jobject*>(env.NewGlobalRef(Unwrap(t->get()))); |
224 |
| - CheckJavaException(env); |
225 |
| - return Global<T, Deleter>(env, obj); |
226 |
| - } |
227 |
| - |
228 |
| - template < class T > |
229 |
| - Global<T> NewGlobal(JNIEnv& env, const Weak<T>& t) |
230 |
| - { |
231 |
| - return NewGlobal<DefaultRefDeleter>(env, t); |
232 |
| - } |
233 |
| - |
234 |
| - |
235 |
| - // Attempt to promote a weak reference to a strong one. Returns an empty result |
236 |
| - // if the weak reference has expired. |
237 |
| - // |
238 |
| - // Beware that the semantics of JNI weak references are weaker than is typically |
239 |
| - // desired: a JNI weak reference may still be promoted to a non-null strong reference |
240 |
| - // even during finalization. Consider using jni::WeakReference<T> instead. |
241 |
| - template < class T, template < RefDeletionMethod > class WeakDeleter > |
242 |
| - Local<T> NewLocal(JNIEnv& env, const Weak<T, WeakDeleter>& t) |
243 |
| - { |
244 |
| - jobject* obj = Wrap<jobject*>(env.NewLocalRef(Unwrap(t->get()))); |
245 |
| - CheckJavaException(env); |
246 |
| - return Local<T>(env, obj); |
247 |
| - } |
248 |
| - |
249 |
| - |
250 | 93 | template < class T >
|
251 | 94 | auto Tag(JNIEnv&, T primitive)
|
252 | 95 | -> std::enable_if_t< IsPrimitive<T>::value, T >
|
|
0 commit comments