lime
Lime is a C++ library implementing Open Whisper System Signal protocol
unique.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace jni
4 {
5 /*
6 Ownership type and main interface for high-level references. Client code using the high-level
7 API will most often work with values of this class template, using the following aliases:
8
9 * Global<P>, a.k.a. Unique<T, DefaultRefDeleter<&JNIEnv::DeleteGlobalRef>>,
10 * Weak<P>, a.k.a. Unique<T, DefaultRefDeleter<&JNIEnv::DeleteWeakGlobalRef>>,
11 * Local<P>, a.k.a. Unique<T, LocalRefDeleter>,
12
13 where P is Object<>, Class<>, or Array<>.
14
15 `Unique` is an ownership class with a deletion policy that's parameterized both
16 by the appropriate method to delete the reference (global, weak, or local) and
17 (for global and weak references), a choice about how to obtain the JNIEnv that's
18 necessary to call the deletion method. The default policy is to delete the reference
19 using the same JNIEnv as was passed to the constructor, but in cases where the
20 object may be deleted on a different thread (commonly, the Java finalizer thread),
21 EnvGettingDeleter or EnvAttachingDeleter may be needed.
22
23 Object<>, Class<>, or Array<> -- the underlying and inherited types used for
24 the template parameter T -- are not publicly constructible or destructible. This
25 is to ensure that code works only with ownership types which release the reference
26 at an appropriate time. Our experience has shown that this is important even for
27 local references; the default JVM cleanup behaviors for local references are not
28 enough to ensure that the local reference table never overflows.
29
30 You may also pass or receive C++ references when you wish to borrow rather than take
31 ownership. For example, receiving parameters for a native method implementation should be
32 C++ references, reflecting the fact that JVM implementations prohibit explicitly releasing
33 this form of local reference. However, if you need to store or copy the reference, you
34 will need to use a method such as `NewGlobalRef` that copies at the reference level.
35 `Unique`, `Object<>`, etc., are not themselves copyable.
36 */
37 template < class T, class D >
38 class Unique : public T
39 {
40 private:
41 D deleter;
42
43 Unique(const Unique&) = delete;
44 Unique& operator=(const Unique&) = delete;
45
46 public:
47 using Base = T;
48 using UntaggedType = typename T::UntaggedType;
49
50 explicit Unique(std::nullptr_t ptr = nullptr)
51 : T(ptr),
52 deleter() {}
53
54 explicit Unique(JNIEnv& env, UntaggedType* ptr)
55 : T(ptr),
56 deleter(env) {}
57
58 Unique(Unique&& other)
59 : T(other.release()),
60 deleter(std::move(other.get_deleter())) {}
61
62 template < class U >
63 Unique(Unique<U, D>&& other, std::enable_if_t<std::is_convertible<const U&, const T&>::value>* = nullptr)
64 : T(other.release()),
65 deleter(std::move(other.get_deleter())) {}
66
68 {
69 reset();
70 }
71
73 {
74 reset(other.release());
75 deleter = std::move(other.deleter);
76 return *this;
77 }
78
79 void reset(UntaggedType* ptr = nullptr)
80 {
81 UntaggedType* current = this->get();
82 T::reset(ptr);
83 if (current)
84 {
85 get_deleter()(current);
86 }
87 }
88
90 {
91 UntaggedType* current = this->get();
92 T::reset(nullptr);
93 return current;
94 }
95
96 D& get_deleter() { return deleter; }
97 const D& get_deleter() const { return deleter; }
98 };
99
100
101 template < class T, template < RefDeletionMethod > class Deleter = DefaultRefDeleter >
103
104 template < class T, template < RefDeletionMethod > class Deleter = DefaultRefDeleter >
106
107 // Not parameterized by Deleter because local references should be short-lived enough
108 // that DefaultRefDeleter suffices in all cases.
109 template < class T >
111
112
113 // Special case for JNI-provided input parameters to native methods, which apparently
114 // should not be explicitly deleted (https://bugs.chromium.org/p/chromium/issues/detail?id=506850).
116 {
117 NullDeleter() = default;
118 NullDeleter(JNIEnv&) {}
119 void operator()(jobject*) const {}
120 };
121
122 template < class T >
124
125
126 template < class T >
128 {
129 using Type = T;
130 };
131
132 template < class T, class D >
133 struct RemoveUnique< Unique<T, D> >
134 {
135 using Type = T;
136 };
137
138 template < class T >
140
141
142 template < class T >
143 auto ReleaseUnique(T primitive)
144 {
145 return primitive;
146 }
147
148 template < class T, class D >
150 {
151 return t.release();
152 }
153
154
155 template < template < RefDeletionMethod > class Deleter, class T >
156 auto NewGlobal(JNIEnv& env, const T& t)
157 {
158 return Global<RemoveUniqueType<T>, Deleter>(env, reinterpret_cast<typename T::UntaggedType*>(jni::NewGlobalRef(env, t.get()).release()));
159 }
160
161 template < class T >
162 auto NewGlobal(JNIEnv& env, const T& t)
163 {
164 return NewGlobal<DefaultRefDeleter>(env, t);
165 }
166
167 // Attempt to promote a weak reference to a strong one. Returns an empty result
168 // if the weak reference has expired.
169 //
170 // Beware that the semantics of JNI weak references are weaker than is typically
171 // desired: a JNI weak reference may still be promoted to a non-null strong reference
172 // even during finalization. Consider using jni::WeakReference<T> instead.
173 template < template < RefDeletionMethod > class Deleter, class T, template < RefDeletionMethod > class WeakDeleter >
175 {
176 jobject* obj = Wrap<jobject*>(env.NewGlobalRef(Unwrap(t->get())));
178 return Global<T, Deleter>(env, obj);
179 }
180
181 template < class T >
182 Global<T> NewGlobal(JNIEnv& env, const Weak<T>& t)
183 {
184 return NewGlobal<DefaultRefDeleter>(env, t);
185 }
186
187
188 template < template < RefDeletionMethod > class Deleter, class T >
189 auto NewWeak(JNIEnv& env, const T& t)
190 {
191 return Weak<RemoveUniqueType<T>, Deleter>(env, reinterpret_cast<typename T::UntaggedType*>(jni::NewWeakGlobalRef(env, t.get()).release()));
192 }
193
194 template < class T >
195 auto NewWeak(JNIEnv& env, const T& t)
196 {
197 return NewWeak<DefaultRefDeleter>(env, t);
198 }
199
200
201 template < class T >
202 auto NewLocal(JNIEnv& env, const T& t)
203 {
204 return Local<RemoveUniqueType<T>>(env, reinterpret_cast<typename T::UntaggedType*>(jni::NewLocalRef(env, t.get()).release()));
205 }
206
207 // Attempt to promote a weak reference to a strong one. Returns an empty result
208 // if the weak reference has expired.
209 //
210 // Beware that the semantics of JNI weak references are weaker than is typically
211 // desired: a JNI weak reference may still be promoted to a non-null strong reference
212 // even during finalization. Consider using jni::WeakReference<T> instead.
213 template < class T, template < RefDeletionMethod > class WeakDeleter >
215 {
216 jobject* obj = Wrap<jobject*>(env.NewLocalRef(Unwrap(t->get())));
218 return Local<T>(env, obj);
219 }
220 }
Definition: ownership.hpp:27
Definition: unique.hpp:39
typename T::UntaggedType UntaggedType
Definition: unique.hpp:48
Unique(JNIEnv &env, UntaggedType *ptr)
Definition: unique.hpp:54
Unique(std::nullptr_t ptr=nullptr)
Definition: unique.hpp:50
T Base
Definition: unique.hpp:47
Unique(Unique< U, D > &&other, std::enable_if_t< std::is_convertible< const U &, const T & >::value > *=nullptr)
Definition: unique.hpp:63
Unique(Unique &&other)
Definition: unique.hpp:58
Unique & operator=(Unique &&other)
Definition: unique.hpp:72
const D & get_deleter() const
Definition: unique.hpp:97
UntaggedType * release()
Definition: unique.hpp:89
~Unique()
Definition: unique.hpp:67
D & get_deleter()
Definition: unique.hpp:96
void reset(UntaggedType *ptr=nullptr)
Definition: unique.hpp:79
Definition: advanced_ownership.hpp:6
UniqueGlobalRef< T, Deleter > NewGlobalRef(JNIEnv &env, T *t)
Definition: functions.hpp:132
UniqueWeakGlobalRef< T, Deleter > NewWeakGlobalRef(JNIEnv &env, T *t)
Definition: functions.hpp:205
decltype(Untag(std::declval< T >())) UntaggedType
Definition: tagging.hpp:130
R CheckJavaException(JNIEnv &env, R &&r)
Definition: errors.hpp:61
typename RemoveUnique< T >::Type RemoveUniqueType
Definition: unique.hpp:139
auto NewLocal(JNIEnv &env, const T &t)
Definition: unique.hpp:202
auto ReleaseUnique(T primitive)
Definition: unique.hpp:143
auto NewWeak(JNIEnv &env, const T &t)
Definition: unique.hpp:189
auto Unwrap(W &&w)
Definition: wrapping.hpp:22
UniqueLocalRef< T > NewLocalRef(JNIEnv &env, T *t)
Definition: functions.hpp:172
auto NewGlobal(JNIEnv &env, const T &t)
Definition: unique.hpp:156
Definition: errors.hpp:10
Definition: unique.hpp:116
NullDeleter(JNIEnv &)
Definition: unique.hpp:118
void operator()(jobject *) const
Definition: unique.hpp:119
NullDeleter()=default
T Type
Definition: unique.hpp:135
Definition: unique.hpp:128
T Type
Definition: unique.hpp:129
Definition: types.hpp:31